Try to fix concurrentModificationException

This commit is contained in:
huangyuhui 2017-03-10 19:38:51 +08:00
parent 0f390e63d3
commit fd2a5a07a1
5 changed files with 43 additions and 9 deletions

View File

@ -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(JavaProcessExitedAbnormallyEvent.class).register(event -> {
int exitCode = event.getValue().getExitCode();
event.getValue().waitForCommandLineCompletion();
HMCLog.err("The game exited abnormally, exit code: " + exitCode);
String[] logs = event.getValue().getStdOutLines().toArray(new String[0]);
String errorText = null;

View File

@ -17,7 +17,6 @@
*/
package org.jackhuang.hmcl.api;
import java.util.ArrayList;
import java.util.List;
/**
@ -34,10 +33,12 @@ public interface IProcess {
List<String> getStartupCommands();
ArrayList<String> getStdOutLines();
List<String> getStdOutLines();
boolean isRunning();
void stop();
void waitForCommandLineCompletion();
}

View File

@ -18,9 +18,11 @@
package org.jackhuang.hmcl.util.sys;
import org.jackhuang.hmcl.api.IProcess;
import java.util.ArrayList;
import java.util.Arrays;
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 {
private final CountDownLatch latch = new CountDownLatch(2);
private final List<String> commands;
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) {
this.commands = commands;
@ -57,7 +60,7 @@ public class JavaProcess implements IProcess {
}
@Override
public ArrayList<String> getStdOutLines() {
public List<String> getStdOutLines() {
return this.stdOutLines;
}
@ -72,6 +75,19 @@ public class JavaProcess implements IProcess {
return false;
}
CountDownLatch getLatch() {
return latch;
}
@Override
public void waitForCommandLineCompletion() {
try {
latch.await();
} catch (InterruptedException ignore) {
HMCLog.warn("Thread has been interrupted.", ignore);
}
}
@Override
public int getExitCode() {
try {

View File

@ -77,13 +77,14 @@ public class ProcessMonitor {
errorThread.start();
}
private void threadStopped() {
private void threadStopped(SimpleEvent<IProcess> event) {
ProcessThread t = (ProcessThread) event.getSource();
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"),
x -> Level.guessLevel(x, Level.INFO).lessOrEqual(Level.ERROR)))
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.",
"Error occurred during initialization of VM",
"A fatal exception has occurred. Program will exit.",

View File

@ -21,6 +21,8 @@ import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Vector;
import org.jackhuang.hmcl.api.HMCLog;
import org.jackhuang.hmcl.api.event.EventHandler;
import org.jackhuang.hmcl.api.event.SimpleEvent;
@ -28,11 +30,13 @@ import org.jackhuang.hmcl.util.code.Charsets;
import org.jackhuang.hmcl.api.IProcess;
/**
* Watch the process command line output(stdout or stderr).
*
* @author huangyuhui
*/
public class ProcessThread extends Thread {
Vector<String> lines = new Vector<>();
ProcessMonitor monitor;
boolean readError;
public final EventHandler<SimpleEvent<String>> printlnEvent = new EventHandler<>();
@ -48,6 +52,13 @@ public class ProcessThread extends Thread {
return monitor.getProcess();
}
/**
* Only get stdout or stderr output according to readError().
*/
public List<String> getLines() {
return lines;
}
@Override
public void run() {
setName("ProcessMonitor");
@ -62,18 +73,22 @@ public class ProcessThread extends Thread {
while ((line = br.readLine()) != null) {
printlnEvent.fire(new SimpleEvent<>(monitor, line));
System.out.println("MC: " + line);
lines.add(line);
p.getStdOutLines().add(line);
}
while ((line = br.readLine()) != null) {
printlnEvent.fire(new SimpleEvent<>(monitor, line));
System.out.println("MC: " + line);
lines.add(line);
p.getStdOutLines().add(line);
}
stopEvent.fire(new SimpleEvent<>(this, p));
} catch (IOException e) {
HMCLog.err("An error occured when reading process stdout/stderr.", e);
} finally {
IOUtils.closeQuietly(br);
}
if (p instanceof JavaProcess)
((JavaProcess) p).getLatch().countDown();
stopEvent.fire(new SimpleEvent<>(this, p));
}
}