mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-09-10 04:16:02 -04:00
Try to fix concurrentModificationException
This commit is contained in:
parent
0f390e63d3
commit
fd2a5a07a1
@ -82,6 +82,7 @@ public class LaunchingUIDaemon {
|
|||||||
HMCLApi.EVENT_BUS.channel(JavaProcessStoppedEvent.class).register(event -> checkExit((LauncherVisibility) ((ProcessMonitor) event.getSource()).getTag()));
|
HMCLApi.EVENT_BUS.channel(JavaProcessStoppedEvent.class).register(event -> checkExit((LauncherVisibility) ((ProcessMonitor) event.getSource()).getTag()));
|
||||||
HMCLApi.EVENT_BUS.channel(JavaProcessExitedAbnormallyEvent.class).register(event -> {
|
HMCLApi.EVENT_BUS.channel(JavaProcessExitedAbnormallyEvent.class).register(event -> {
|
||||||
int exitCode = event.getValue().getExitCode();
|
int exitCode = event.getValue().getExitCode();
|
||||||
|
event.getValue().waitForCommandLineCompletion();
|
||||||
HMCLog.err("The game exited abnormally, exit code: " + exitCode);
|
HMCLog.err("The game exited abnormally, exit code: " + exitCode);
|
||||||
String[] logs = event.getValue().getStdOutLines().toArray(new String[0]);
|
String[] logs = event.getValue().getStdOutLines().toArray(new String[0]);
|
||||||
String errorText = null;
|
String errorText = null;
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.jackhuang.hmcl.api;
|
package org.jackhuang.hmcl.api;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -34,10 +33,12 @@ public interface IProcess {
|
|||||||
|
|
||||||
List<String> getStartupCommands();
|
List<String> getStartupCommands();
|
||||||
|
|
||||||
ArrayList<String> getStdOutLines();
|
List<String> getStdOutLines();
|
||||||
|
|
||||||
boolean isRunning();
|
boolean isRunning();
|
||||||
|
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
|
void waitForCommandLineCompletion();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -18,9 +18,11 @@
|
|||||||
package org.jackhuang.hmcl.util.sys;
|
package org.jackhuang.hmcl.util.sys;
|
||||||
|
|
||||||
import org.jackhuang.hmcl.api.IProcess;
|
import org.jackhuang.hmcl.api.IProcess;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Vector;
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
import org.jackhuang.hmcl.api.HMCLog;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -28,9 +30,10 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public class JavaProcess implements IProcess {
|
public class JavaProcess implements IProcess {
|
||||||
|
|
||||||
|
private final CountDownLatch latch = new CountDownLatch(2);
|
||||||
private final List<String> commands;
|
private final List<String> commands;
|
||||||
private final Process process;
|
private final Process process;
|
||||||
private final ArrayList<String> stdOutLines = new ArrayList<>();
|
private final Vector<String> stdOutLines = new Vector<>();
|
||||||
|
|
||||||
public JavaProcess(List<String> commands, Process process) {
|
public JavaProcess(List<String> commands, Process process) {
|
||||||
this.commands = commands;
|
this.commands = commands;
|
||||||
@ -57,7 +60,7 @@ public class JavaProcess implements IProcess {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayList<String> getStdOutLines() {
|
public List<String> getStdOutLines() {
|
||||||
return this.stdOutLines;
|
return this.stdOutLines;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,6 +75,19 @@ public class JavaProcess implements IProcess {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CountDownLatch getLatch() {
|
||||||
|
return latch;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void waitForCommandLineCompletion() {
|
||||||
|
try {
|
||||||
|
latch.await();
|
||||||
|
} catch (InterruptedException ignore) {
|
||||||
|
HMCLog.warn("Thread has been interrupted.", ignore);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getExitCode() {
|
public int getExitCode() {
|
||||||
try {
|
try {
|
||||||
|
@ -77,13 +77,14 @@ public class ProcessMonitor {
|
|||||||
errorThread.start();
|
errorThread.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void threadStopped() {
|
private void threadStopped(SimpleEvent<IProcess> event) {
|
||||||
|
ProcessThread t = (ProcessThread) event.getSource();
|
||||||
HMCLog.log("Process exit code: " + p.getExitCode());
|
HMCLog.log("Process exit code: " + p.getExitCode());
|
||||||
if (p.getExitCode() != 0 || StrUtils.containsOne(p.getStdOutLines(),
|
if (p.getExitCode() != 0 || StrUtils.containsOne(t.getLines(),
|
||||||
Arrays.asList("Unable to launch"),
|
Arrays.asList("Unable to launch"),
|
||||||
x -> Level.guessLevel(x, Level.INFO).lessOrEqual(Level.ERROR)))
|
x -> Level.guessLevel(x, Level.INFO).lessOrEqual(Level.ERROR)))
|
||||||
HMCLApi.EVENT_BUS.fireChannel(new JavaProcessExitedAbnormallyEvent(ProcessMonitor.this, p));
|
HMCLApi.EVENT_BUS.fireChannel(new JavaProcessExitedAbnormallyEvent(ProcessMonitor.this, p));
|
||||||
if (p.getExitCode() != 0 && StrUtils.containsOne(p.getStdOutLines(),
|
if (p.getExitCode() != 0 && StrUtils.containsOne(t.getLines(),
|
||||||
Arrays.asList("Could not create the Java Virtual Machine.",
|
Arrays.asList("Could not create the Java Virtual Machine.",
|
||||||
"Error occurred during initialization of VM",
|
"Error occurred during initialization of VM",
|
||||||
"A fatal exception has occurred. Program will exit.",
|
"A fatal exception has occurred. Program will exit.",
|
||||||
|
@ -21,6 +21,8 @@ import java.io.BufferedReader;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Vector;
|
||||||
import org.jackhuang.hmcl.api.HMCLog;
|
import org.jackhuang.hmcl.api.HMCLog;
|
||||||
import org.jackhuang.hmcl.api.event.EventHandler;
|
import org.jackhuang.hmcl.api.event.EventHandler;
|
||||||
import org.jackhuang.hmcl.api.event.SimpleEvent;
|
import org.jackhuang.hmcl.api.event.SimpleEvent;
|
||||||
@ -28,11 +30,13 @@ import org.jackhuang.hmcl.util.code.Charsets;
|
|||||||
import org.jackhuang.hmcl.api.IProcess;
|
import org.jackhuang.hmcl.api.IProcess;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Watch the process command line output(stdout or stderr).
|
||||||
*
|
*
|
||||||
* @author huangyuhui
|
* @author huangyuhui
|
||||||
*/
|
*/
|
||||||
public class ProcessThread extends Thread {
|
public class ProcessThread extends Thread {
|
||||||
|
|
||||||
|
Vector<String> lines = new Vector<>();
|
||||||
ProcessMonitor monitor;
|
ProcessMonitor monitor;
|
||||||
boolean readError;
|
boolean readError;
|
||||||
public final EventHandler<SimpleEvent<String>> printlnEvent = new EventHandler<>();
|
public final EventHandler<SimpleEvent<String>> printlnEvent = new EventHandler<>();
|
||||||
@ -48,6 +52,13 @@ public class ProcessThread extends Thread {
|
|||||||
return monitor.getProcess();
|
return monitor.getProcess();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Only get stdout or stderr output according to readError().
|
||||||
|
*/
|
||||||
|
public List<String> getLines() {
|
||||||
|
return lines;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
setName("ProcessMonitor");
|
setName("ProcessMonitor");
|
||||||
@ -62,18 +73,22 @@ public class ProcessThread extends Thread {
|
|||||||
while ((line = br.readLine()) != null) {
|
while ((line = br.readLine()) != null) {
|
||||||
printlnEvent.fire(new SimpleEvent<>(monitor, line));
|
printlnEvent.fire(new SimpleEvent<>(monitor, line));
|
||||||
System.out.println("MC: " + line);
|
System.out.println("MC: " + line);
|
||||||
|
lines.add(line);
|
||||||
p.getStdOutLines().add(line);
|
p.getStdOutLines().add(line);
|
||||||
}
|
}
|
||||||
while ((line = br.readLine()) != null) {
|
while ((line = br.readLine()) != null) {
|
||||||
printlnEvent.fire(new SimpleEvent<>(monitor, line));
|
printlnEvent.fire(new SimpleEvent<>(monitor, line));
|
||||||
System.out.println("MC: " + line);
|
System.out.println("MC: " + line);
|
||||||
|
lines.add(line);
|
||||||
p.getStdOutLines().add(line);
|
p.getStdOutLines().add(line);
|
||||||
}
|
}
|
||||||
stopEvent.fire(new SimpleEvent<>(this, p));
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
HMCLog.err("An error occured when reading process stdout/stderr.", e);
|
HMCLog.err("An error occured when reading process stdout/stderr.", e);
|
||||||
} finally {
|
} finally {
|
||||||
IOUtils.closeQuietly(br);
|
IOUtils.closeQuietly(br);
|
||||||
}
|
}
|
||||||
|
if (p instanceof JavaProcess)
|
||||||
|
((JavaProcess) p).getLatch().countDown();
|
||||||
|
stopEvent.fire(new SimpleEvent<>(this, p));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user