Remove the superfluous Serializer interface and its implemetation

This commit is contained in:
Peter Palaga
2020-10-24 22:43:28 +02:00
parent ada4b27b7a
commit a71033cc94
7 changed files with 179 additions and 307 deletions

View File

@@ -41,7 +41,7 @@ public class DaemonClientConnection implements Closeable {
private final static Logger LOG = LoggerFactory.getLogger(DaemonClientConnection.class); private final static Logger LOG = LoggerFactory.getLogger(DaemonClientConnection.class);
private final DaemonConnection<Message> connection; private final DaemonConnection connection;
private final DaemonInfo daemon; private final DaemonInfo daemon;
private final StaleAddressDetector staleAddressDetector; private final StaleAddressDetector staleAddressDetector;
private final boolean newDaemon; private final boolean newDaemon;
@@ -53,7 +53,7 @@ public class DaemonClientConnection implements Closeable {
private final AtomicBoolean running = new AtomicBoolean(true); private final AtomicBoolean running = new AtomicBoolean(true);
private final AtomicReference<Exception> exception = new AtomicReference<>(); private final AtomicReference<Exception> exception = new AtomicReference<>();
public DaemonClientConnection(DaemonConnection<Message> connection, DaemonInfo daemon, public DaemonClientConnection(DaemonConnection connection, DaemonInfo daemon,
StaleAddressDetector staleAddressDetector, boolean newDaemon, int maxKeepAliveMs) { StaleAddressDetector staleAddressDetector, boolean newDaemon, int maxKeepAliveMs) {
this.connection = connection; this.connection = connection;
this.daemon = daemon; this.daemon = daemon;

View File

@@ -48,9 +48,7 @@ import org.jboss.fuse.mvnd.common.DaemonState;
import org.jboss.fuse.mvnd.common.DaemonStopEvent; import org.jboss.fuse.mvnd.common.DaemonStopEvent;
import org.jboss.fuse.mvnd.common.Environment; import org.jboss.fuse.mvnd.common.Environment;
import org.jboss.fuse.mvnd.common.MavenDaemon; import org.jboss.fuse.mvnd.common.MavenDaemon;
import org.jboss.fuse.mvnd.common.Message;
import org.jboss.fuse.mvnd.common.Os; import org.jboss.fuse.mvnd.common.Os;
import org.jboss.fuse.mvnd.common.Serializer;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -71,15 +69,12 @@ public class DaemonConnector {
private final DaemonRegistry registry; private final DaemonRegistry registry;
private final ClientLayout layout; private final ClientLayout layout;
private final Serializer<Message> serializer;
private final BuildProperties buildProperties; private final BuildProperties buildProperties;
public DaemonConnector(ClientLayout layout, DaemonRegistry registry, BuildProperties buildProperties, public DaemonConnector(ClientLayout layout, DaemonRegistry registry, BuildProperties buildProperties) {
Serializer<Message> serializer) {
this.layout = layout; this.layout = layout;
this.registry = registry; this.registry = registry;
this.buildProperties = buildProperties; this.buildProperties = buildProperties;
this.serializer = serializer;
} }
public DaemonClientConnection maybeConnect(DaemonCompatibilitySpec constraint) { public DaemonClientConnection maybeConnect(DaemonCompatibilitySpec constraint) {
@@ -331,7 +326,7 @@ public class DaemonConnector {
LOGGER.debug("Connecting to Daemon"); LOGGER.debug("Connecting to Daemon");
try { try {
int maxKeepAliveMs = layout.getKeepAliveMs() * layout.getMaxLostKeepAlive(); int maxKeepAliveMs = layout.getKeepAliveMs() * layout.getMaxLostKeepAlive();
DaemonConnection<Message> connection = connect(daemon.getAddress()); DaemonConnection connection = connect(daemon.getAddress());
return new DaemonClientConnection(connection, daemon, staleAddressDetector, newDaemon, maxKeepAliveMs); return new DaemonClientConnection(connection, daemon, staleAddressDetector, newDaemon, maxKeepAliveMs);
} catch (DaemonException.ConnectException e) { } catch (DaemonException.ConnectException e) {
staleAddressDetector.maybeStaleAddress(e); staleAddressDetector.maybeStaleAddress(e);
@@ -360,7 +355,7 @@ public class DaemonConnector {
} }
} }
public DaemonConnection<Message> connect(int port) throws DaemonException.ConnectException { public DaemonConnection connect(int port) throws DaemonException.ConnectException {
InetSocketAddress address = new InetSocketAddress(InetAddress.getLoopbackAddress(), port); InetSocketAddress address = new InetSocketAddress(InetAddress.getLoopbackAddress(), port);
try { try {
LOGGER.debug("Trying to connect to address {}.", address); LOGGER.debug("Trying to connect to address {}.", address);
@@ -372,7 +367,7 @@ public class DaemonConnector {
throw new DaemonException.ConnectException(String.format("Socket connected to itself on %s.", address)); throw new DaemonException.ConnectException(String.format("Socket connected to itself on %s.", address));
} }
LOGGER.debug("Connected to address {}.", socket.getRemoteSocketAddress()); LOGGER.debug("Connected to address {}.", socket.getRemoteSocketAddress());
return new DaemonConnection<>(socketChannel, serializer); return new DaemonConnection(socketChannel);
} catch (DaemonException.ConnectException e) { } catch (DaemonException.ConnectException e) {
throw e; throw e;
} catch (Exception e) { } catch (Exception e) {

View File

@@ -36,7 +36,6 @@ import org.jboss.fuse.mvnd.common.Message.BuildEvent;
import org.jboss.fuse.mvnd.common.Message.BuildException; import org.jboss.fuse.mvnd.common.Message.BuildException;
import org.jboss.fuse.mvnd.common.Message.BuildMessage; import org.jboss.fuse.mvnd.common.Message.BuildMessage;
import org.jboss.fuse.mvnd.common.Message.KeepAliveMessage; import org.jboss.fuse.mvnd.common.Message.KeepAliveMessage;
import org.jboss.fuse.mvnd.common.Message.MessageSerializer;
import org.jboss.fuse.mvnd.common.OsUtils; import org.jboss.fuse.mvnd.common.OsUtils;
import org.jboss.fuse.mvnd.common.logging.ClientOutput; import org.jboss.fuse.mvnd.common.logging.ClientOutput;
import org.jboss.fuse.mvnd.common.logging.TerminalOutput; import org.jboss.fuse.mvnd.common.logging.TerminalOutput;
@@ -184,7 +183,7 @@ public class DefaultClient implements Client {
args.add("-Dmaven.repo.local=" + localMavenRepository.toString()); args.add("-Dmaven.repo.local=" + localMavenRepository.toString());
} }
final DaemonConnector connector = new DaemonConnector(layout, registry, buildProperties, new MessageSerializer()); final DaemonConnector connector = new DaemonConnector(layout, registry, buildProperties);
List<String> opts = new ArrayList<>(); List<String> opts = new ArrayList<>();
try (DaemonClientConnection daemon = connector.connect(new DaemonCompatibilitySpec(javaHome, opts), try (DaemonClientConnection daemon = connector.connect(new DaemonCompatibilitySpec(javaHome, opts),
s -> output.accept(null, s))) { s -> output.accept(null, s))) {

View File

@@ -40,26 +40,24 @@ import org.slf4j.LoggerFactory;
* https://github.com/gradle/gradle/blob/v5.6.2/subprojects/messaging/src/main/java/org/gradle/internal/remote/internal/inet/SocketConnection.java * https://github.com/gradle/gradle/blob/v5.6.2/subprojects/messaging/src/main/java/org/gradle/internal/remote/internal/inet/SocketConnection.java
* *
*/ */
public class DaemonConnection<T> implements AutoCloseable { public class DaemonConnection implements AutoCloseable {
private static final Logger LOGGER = LoggerFactory.getLogger(DaemonConnection.class); private static final Logger LOGGER = LoggerFactory.getLogger(DaemonConnection.class);
private final SocketChannel socket; private final SocketChannel socket;
private final Serializer<T> serializer; private final DataInputStream input;
private final DataOutputStream output;
private final InetSocketAddress localAddress; private final InetSocketAddress localAddress;
private final InetSocketAddress remoteAddress; private final InetSocketAddress remoteAddress;
private final DataInputStream instr;
private final DataOutputStream outstr;
public DaemonConnection(SocketChannel socket, Serializer<T> serializer) { public DaemonConnection(SocketChannel socket) {
this.socket = socket; this.socket = socket;
this.serializer = serializer;
try { try {
// NOTE: we use non-blocking IO as there is no reliable way when using blocking IO to shutdown reads while // NOTE: we use non-blocking IO as there is no reliable way when using blocking IO to shutdown reads while
// keeping writes active. For example, Socket.shutdownInput() does not work on Windows. // keeping writes active. For example, Socket.shutdownInput() does not work on Windows.
socket.configureBlocking(false); socket.configureBlocking(false);
outstr = new DataOutputStream(new SocketOutputStream(socket)); this.output = new DataOutputStream(new SocketOutputStream(socket));
instr = new DataInputStream(new SocketInputStream(socket)); this.input = new DataInputStream(new SocketInputStream(socket));
} catch (IOException e) { } catch (IOException e) {
throw new DaemonException.InterruptedException(e); throw new DaemonException.InterruptedException(e);
} }
@@ -72,15 +70,15 @@ public class DaemonConnection<T> implements AutoCloseable {
return "socket connection from " + localAddress + " to " + remoteAddress; return "socket connection from " + localAddress + " to " + remoteAddress;
} }
public T receive() throws DaemonException.MessageIOException { public Message receive() throws DaemonException.MessageIOException {
try { try {
return serializer.read(instr); return Message.read(input);
} catch (EOFException e) { } catch (EOFException e) {
if (LOGGER.isDebugEnabled()) { if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Discarding EOFException: {}", e.toString()); LOGGER.debug("Discarding EOFException: {}", e.toString());
} }
return null; return null;
} catch (ClassNotFoundException | IOException e) { } catch (IOException e) {
throw new DaemonException.RecoverableMessageIOException( throw new DaemonException.RecoverableMessageIOException(
String.format("Could not read message from '%s'.", remoteAddress), e); String.format("Could not read message from '%s'.", remoteAddress), e);
} catch (Throwable e) { } catch (Throwable e) {
@@ -109,11 +107,11 @@ public class DaemonConnection<T> implements AutoCloseable {
return false; return false;
} }
public void dispatch(T message) throws DaemonException.MessageIOException { public void dispatch(Message message) throws DaemonException.MessageIOException {
try { try {
serializer.write(outstr, message); message.write(output);
outstr.flush(); output.flush();
} catch (ClassNotFoundException | IOException e) { } catch (IOException e) {
throw new DaemonException.RecoverableMessageIOException( throw new DaemonException.RecoverableMessageIOException(
String.format("Could not write message %s to '%s'.", message, remoteAddress), e); String.format("Could not write message %s to '%s'.", message, remoteAddress), e);
} catch (Throwable e) { } catch (Throwable e) {
@@ -124,7 +122,7 @@ public class DaemonConnection<T> implements AutoCloseable {
public void flush() throws DaemonException.MessageIOException { public void flush() throws DaemonException.MessageIOException {
try { try {
outstr.flush(); output.flush();
} catch (Throwable e) { } catch (Throwable e) {
throw new DaemonException.MessageIOException(String.format("Could not write '%s'.", remoteAddress), e); throw new DaemonException.MessageIOException(String.format("Could not write '%s'.", remoteAddress), e);
} }
@@ -132,7 +130,7 @@ public class DaemonConnection<T> implements AutoCloseable {
public void close() { public void close() {
Throwable failure = null; Throwable failure = null;
List<Closeable> elements = Arrays.asList(this::flush, instr, outstr, socket); List<Closeable> elements = Arrays.asList(this::flush, input, output, socket);
for (Closeable element : elements) { for (Closeable element : elements) {
try { try {
element.close(); element.close();

View File

@@ -17,17 +17,43 @@ package org.jboss.fuse.mvnd.common;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.IOException; import java.io.IOException;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.io.StringWriter; import java.io.StringWriter;
import java.io.UTFDataFormatException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
public abstract class Message { public abstract class Message {
static final int BUILD_REQUEST = 0;
static final int BUILD_EVENT = 1;
static final int BUILD_MESSAGE = 2;
static final int BUILD_EXCEPTION = 3;
static final int KEEP_ALIVE = 4;
static final int STOP = 5;
public static Message read(DataInputStream input) throws IOException {
int type = input.read();
if (type == -1) {
return null;
}
switch (type) {
case BUILD_REQUEST:
return BuildRequest.read(input);
case BUILD_EVENT:
return BuildEvent.read(input);
case BUILD_MESSAGE:
return BuildMessage.read(input);
case BUILD_EXCEPTION:
return BuildException.read(input);
case KEEP_ALIVE:
return KeepAliveMessage.SINGLETON;
case STOP:
return StopMessage.SINGLETON;
}
throw new IllegalStateException("Unexpected message type: " + type);
}
final long timestamp = System.nanoTime(); final long timestamp = System.nanoTime();
@@ -35,12 +61,57 @@ public abstract class Message {
return timestamp; return timestamp;
} }
public abstract void write(DataOutputStream output) throws IOException;
static void writeStringList(DataOutputStream output, List<String> value) throws IOException {
output.writeInt(value.size());
for (String v : value) {
output.writeUTF(v);
}
}
static void writeStringMap(DataOutputStream output, Map<String, String> value) throws IOException {
output.writeInt(value.size());
for (Map.Entry<String, String> e : value.entrySet()) {
output.writeUTF(e.getKey());
output.writeUTF(e.getValue());
}
}
static List<String> readStringList(DataInputStream input) throws IOException {
ArrayList<String> l = new ArrayList<>();
int nb = input.readInt();
for (int i = 0; i < nb; i++) {
l.add(input.readUTF());
}
return l;
}
static Map<String, String> readStringMap(DataInputStream input) throws IOException {
LinkedHashMap<String, String> m = new LinkedHashMap<>();
int nb = input.readInt();
for (int i = 0; i < nb; i++) {
String k = input.readUTF();
String v = input.readUTF();
m.put(k, v);
}
return m;
}
public static class BuildRequest extends Message { public static class BuildRequest extends Message {
final List<String> args; final List<String> args;
final String workingDir; final String workingDir;
final String projectDir; final String projectDir;
final Map<String, String> env; final Map<String, String> env;
public static Message read(DataInputStream input) throws IOException {
List<String> args = readStringList(input);
String workingDir = input.readUTF();
String projectDir = input.readUTF();
Map<String, String> env = readStringMap(input);
return new BuildRequest(args, workingDir, projectDir, env);
}
public BuildRequest(List<String> args, String workingDir, String projectDir, Map<String, String> env) { public BuildRequest(List<String> args, String workingDir, String projectDir, Map<String, String> env) {
this.args = args; this.args = args;
this.workingDir = workingDir; this.workingDir = workingDir;
@@ -72,6 +143,15 @@ public abstract class Message {
", projectDir='" + projectDir + '\'' + ", projectDir='" + projectDir + '\'' +
'}'; '}';
} }
@Override
public void write(DataOutputStream output) throws IOException {
output.write(BUILD_REQUEST);
writeStringList(output, args);
output.writeUTF(workingDir);
output.writeUTF(projectDir);
writeStringMap(output, env);
}
} }
public static class BuildException extends Message { public static class BuildException extends Message {
@@ -79,6 +159,13 @@ public abstract class Message {
final String className; final String className;
final String stackTrace; final String stackTrace;
public static Message read(DataInputStream input) throws IOException {
String message = input.readUTF();
String className = input.readUTF();
String stackTrace = input.readUTF();
return new BuildException(message, className, stackTrace);
}
public BuildException(Throwable t) { public BuildException(Throwable t) {
this(t.getMessage(), t.getClass().getName(), getStackTrace(t)); this(t.getMessage(), t.getClass().getName(), getStackTrace(t));
} }
@@ -115,6 +202,14 @@ public abstract class Message {
", stackTrace='" + stackTrace + '\'' + ", stackTrace='" + stackTrace + '\'' +
'}'; '}';
} }
@Override
public void write(DataOutputStream output) throws IOException {
output.write(BUILD_EXCEPTION);
output.writeUTF(message);
output.writeUTF(className);
output.writeUTF(stackTrace);
}
} }
public static class BuildEvent extends Message { public static class BuildEvent extends Message {
@@ -126,6 +221,13 @@ public abstract class Message {
final String projectId; final String projectId;
final String display; final String display;
public static Message read(DataInputStream input) throws IOException {
BuildEvent.Type type = BuildEvent.Type.values()[input.read()];
String projectId = input.readUTF();
String display = input.readUTF();
return new BuildEvent(type, projectId, display);
}
public BuildEvent(Type type, String projectId, String display) { public BuildEvent(Type type, String projectId, String display) {
this.type = type; this.type = type;
this.projectId = projectId; this.projectId = projectId;
@@ -152,12 +254,26 @@ public abstract class Message {
", display='" + display + '\'' + ", display='" + display + '\'' +
'}'; '}';
} }
@Override
public void write(DataOutputStream output) throws IOException {
output.write(BUILD_EVENT);
output.write(type.ordinal());
output.writeUTF(projectId);
output.writeUTF(display);
}
} }
public static class BuildMessage extends Message { public static class BuildMessage extends Message {
final String projectId; final String projectId;
final String message; final String message;
public static Message read(DataInputStream input) throws IOException {
String projectId = input.readUTF();
String message = input.readUTF();
return new BuildMessage(projectId.isEmpty() ? null : projectId, message);
}
public BuildMessage(String projectId, String message) { public BuildMessage(String projectId, String message) {
this.projectId = projectId; this.projectId = projectId;
this.message = message; this.message = message;
@@ -178,245 +294,52 @@ public abstract class Message {
", message='" + message + '\'' + ", message='" + message + '\'' +
'}'; '}';
} }
@Override
public void write(DataOutputStream output) throws IOException {
output.write(BUILD_MESSAGE);
output.writeUTF(projectId != null ? projectId : "");
output.writeUTF(message);
}
} }
public static class KeepAliveMessage extends Message { public static class KeepAliveMessage extends Message {
public static final KeepAliveMessage SINGLETON = new KeepAliveMessage();
/**
* Use {@link #SINGLETON}
*/
private KeepAliveMessage() {
}
@Override @Override
public String toString() { public String toString() {
return "KeepAliveMessage{}"; return "KeepAliveMessage{}";
} }
@Override
public void write(DataOutputStream output) throws IOException {
output.write(KEEP_ALIVE);
}
} }
public static class MessageSerializer implements Serializer<Message> { public static class StopMessage extends Message {
public static final KeepAliveMessage SINGLETON = new KeepAliveMessage();
final int BUILD_REQUEST = 0; /**
final int BUILD_EVENT = 1; * Use {@link #SINGLETON}
final int BUILD_MESSAGE = 2; */
final int BUILD_EXCEPTION = 3; private StopMessage() {
final int KEEP_ALIVE = 4;
@Override
public Message read(DataInputStream input) throws EOFException, Exception {
int type = input.read();
if (type == -1) {
return null;
}
switch (type) {
case BUILD_REQUEST:
return readBuildRequest(input);
case BUILD_EVENT:
return readBuildEvent(input);
case BUILD_MESSAGE:
return readBuildMessage(input);
case BUILD_EXCEPTION:
return readBuildException(input);
case KEEP_ALIVE:
return new KeepAliveMessage();
}
throw new IllegalStateException("Unexpected message type: " + type);
} }
@Override @Override
public void write(DataOutputStream output, Message value) throws Exception { public String toString() {
if (value instanceof BuildRequest) { return "StopMessage{}";
output.write(BUILD_REQUEST);
writeBuildRequest(output, (BuildRequest) value);
} else if (value instanceof BuildEvent) {
output.write(BUILD_EVENT);
writeBuildEvent(output, (BuildEvent) value);
} else if (value instanceof BuildMessage) {
output.write(BUILD_MESSAGE);
writeBuildMessage(output, (BuildMessage) value);
} else if (value instanceof BuildException) {
output.write(BUILD_EXCEPTION);
writeBuildException(output, (BuildException) value);
} else if (value instanceof KeepAliveMessage) {
output.write(KEEP_ALIVE);
} else {
throw new IllegalStateException();
}
} }
private BuildRequest readBuildRequest(DataInputStream input) throws IOException { @Override
List<String> args = readStringList(input); public void write(DataOutputStream output) throws IOException {
String workingDir = readUTF(input); output.write(STOP);
String projectDir = readUTF(input);
Map<String, String> env = readStringMap(input);
return new BuildRequest(args, workingDir, projectDir, env);
} }
private void writeBuildRequest(DataOutputStream output, BuildRequest value) throws IOException {
writeStringList(output, value.args);
writeUTF(output, value.workingDir);
writeUTF(output, value.projectDir);
writeStringMap(output, value.env);
}
private BuildEvent readBuildEvent(DataInputStream input) throws IOException {
BuildEvent.Type type = BuildEvent.Type.values()[input.read()];
String projectId = readUTF(input);
String display = readUTF(input);
return new BuildEvent(type, projectId, display);
}
private void writeBuildEvent(DataOutputStream output, BuildEvent value) throws IOException {
output.write(value.type.ordinal());
writeUTF(output, value.projectId);
writeUTF(output, value.display);
}
private BuildMessage readBuildMessage(DataInputStream input) throws IOException {
String projectId = readUTF(input);
String message = readUTF(input);
return new BuildMessage(projectId.isEmpty() ? null : projectId, message);
}
private void writeBuildMessage(DataOutputStream output, BuildMessage value) throws IOException {
writeUTF(output, value.projectId != null ? value.projectId : "");
writeUTF(output, value.message);
}
private BuildException readBuildException(DataInputStream input) throws IOException {
String message = readUTF(input);
String className = readUTF(input);
String stackTrace = readUTF(input);
return new BuildException(message, className, stackTrace);
}
private void writeBuildException(DataOutputStream output, BuildException value) throws IOException {
writeUTF(output, value.message);
writeUTF(output, value.className);
writeUTF(output, value.stackTrace);
}
private List<String> readStringList(DataInputStream input) throws IOException {
ArrayList<String> l = new ArrayList<>();
int nb = input.readInt();
for (int i = 0; i < nb; i++) {
l.add(readUTF(input));
}
return l;
}
private void writeStringList(DataOutputStream output, List<String> value) throws IOException {
output.writeInt(value.size());
for (String v : value) {
writeUTF(output, v);
}
}
private Map<String, String> readStringMap(DataInputStream input) throws IOException {
LinkedHashMap<String, String> m = new LinkedHashMap<>();
int nb = input.readInt();
for (int i = 0; i < nb; i++) {
String k = readUTF(input);
String v = readUTF(input);
m.put(k, v);
}
return m;
}
private void writeStringMap(DataOutputStream output, Map<String, String> value) throws IOException {
output.writeInt(value.size());
for (Map.Entry<String, String> e : value.entrySet()) {
writeUTF(output, e.getKey());
writeUTF(output, e.getValue());
}
}
private static final String INVALID_BYTE = "Invalid byte";
private static final int UTF_BUFS_CHAR_CNT = 256;
private static final int UTF_BUFS_BYTE_CNT = UTF_BUFS_CHAR_CNT * 3;
final byte[] byteBuf = new byte[UTF_BUFS_BYTE_CNT];
String readUTF(DataInputStream input) throws IOException {
int len = input.readInt();
final char[] chars = new char[len];
int i = 0, cnt = 0, charIdx = 0;
while (charIdx < len) {
if (i == cnt) {
cnt = input.read(byteBuf, 0, Math.min(UTF_BUFS_BYTE_CNT, len - charIdx));
if (cnt < 0) {
throw new EOFException();
}
i = 0;
}
final int a = byteBuf[i++] & 0xff;
if (a < 0x80) {
// low bit clear
chars[charIdx++] = (char) a;
} else if (a < 0xc0) {
throw new UTFDataFormatException(INVALID_BYTE);
} else if (a < 0xe0) {
if (i == cnt) {
cnt = input.read(byteBuf, 0, Math.min(UTF_BUFS_BYTE_CNT, len - charIdx));
if (cnt < 0) {
throw new EOFException();
}
i = 0;
}
final int b = byteBuf[i++] & 0xff;
if ((b & 0xc0) != 0x80) {
throw new UTFDataFormatException(INVALID_BYTE);
}
chars[charIdx++] = (char) ((a & 0x1f) << 6 | b & 0x3f);
} else if (a < 0xf0) {
if (i == cnt) {
cnt = input.read(byteBuf, 0, Math.min(UTF_BUFS_BYTE_CNT, len - charIdx));
if (cnt < 0) {
throw new EOFException();
}
i = 0;
}
final int b = byteBuf[i++] & 0xff;
if ((b & 0xc0) != 0x80) {
throw new UTFDataFormatException(INVALID_BYTE);
}
if (i == cnt) {
cnt = input.read(byteBuf, 0, Math.min(UTF_BUFS_BYTE_CNT, len - charIdx));
if (cnt < 0) {
throw new EOFException();
}
i = 0;
}
final int c = byteBuf[i++] & 0xff;
if ((c & 0xc0) != 0x80) {
throw new UTFDataFormatException(INVALID_BYTE);
}
chars[charIdx++] = (char) ((a & 0x0f) << 12 | (b & 0x3f) << 6 | c & 0x3f);
} else {
throw new UTFDataFormatException(INVALID_BYTE);
}
}
return String.valueOf(chars);
}
void writeUTF(DataOutputStream output, String s) throws IOException {
final int length = s.length();
output.writeInt(length);
int strIdx = 0;
int byteIdx = 0;
while (strIdx < length) {
final char c = s.charAt(strIdx++);
if (c > 0 && c <= 0x7f) {
byteBuf[byteIdx++] = (byte) c;
} else if (c <= 0x07ff) {
byteBuf[byteIdx++] = (byte) (0xc0 | 0x1f & c >> 6);
byteBuf[byteIdx++] = (byte) (0x80 | 0x3f & c);
} else {
byteBuf[byteIdx++] = (byte) (0xe0 | 0x0f & c >> 12);
byteBuf[byteIdx++] = (byte) (0x80 | 0x3f & c >> 6);
byteBuf[byteIdx++] = (byte) (0x80 | 0x3f & c);
}
if (byteIdx > UTF_BUFS_BYTE_CNT - 4) {
output.write(byteBuf, 0, byteIdx);
byteIdx = 0;
}
}
if (byteIdx > 0) {
output.write(byteBuf, 0, byteIdx);
}
}
} }
} }

View File

@@ -1,40 +0,0 @@
/*
* Copyright 2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.fuse.mvnd.common;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
/**
* File origin:
* https://github.com/gradle/gradle/blob/v5.6.2/subprojects/messaging/src/main/java/org/gradle/internal/serialize/Serializer.java
*/
public interface Serializer<T> {
/**
* Reads the next object from the given stream. The implementation must not perform any buffering, so that it reads only
* those bytes from the input stream that are
* required to deserialize the next object.
*
* @throws EOFException When the next object cannot be fully read due to reaching the end of stream.
*/
T read(DataInputStream input) throws EOFException, Exception;
/**
* Writes the given object to the given stream. The implementation must not perform any buffering.
*/
void write(DataOutputStream output, T value) throws Exception;
}

View File

@@ -58,7 +58,7 @@ import org.jboss.fuse.mvnd.common.Message.BuildException;
import org.jboss.fuse.mvnd.common.Message.BuildMessage; import org.jboss.fuse.mvnd.common.Message.BuildMessage;
import org.jboss.fuse.mvnd.common.Message.BuildRequest; import org.jboss.fuse.mvnd.common.Message.BuildRequest;
import org.jboss.fuse.mvnd.common.Message.KeepAliveMessage; import org.jboss.fuse.mvnd.common.Message.KeepAliveMessage;
import org.jboss.fuse.mvnd.common.Message.MessageSerializer; import org.jboss.fuse.mvnd.common.Message.StopMessage;
import org.jboss.fuse.mvnd.daemon.DaemonExpiration.DaemonExpirationResult; import org.jboss.fuse.mvnd.daemon.DaemonExpiration.DaemonExpirationResult;
import org.jboss.fuse.mvnd.daemon.DaemonExpiration.DaemonExpirationStrategy; import org.jboss.fuse.mvnd.daemon.DaemonExpiration.DaemonExpirationStrategy;
import org.jboss.fuse.mvnd.logging.smart.AbstractLoggingSpy; import org.jboss.fuse.mvnd.logging.smart.AbstractLoggingSpy;
@@ -187,7 +187,7 @@ public class Server implements AutoCloseable, Runnable {
private void client(SocketChannel socket) { private void client(SocketChannel socket) {
LOGGER.info("Client connected"); LOGGER.info("Client connected");
try (DaemonConnection<Message> connection = new DaemonConnection<Message>(socket, new MessageSerializer())) { try (DaemonConnection connection = new DaemonConnection(socket)) {
while (true) { while (true) {
LOGGER.info("Waiting for request"); LOGGER.info("Waiting for request");
Message message = connection.receive(); Message message = connection.receive();
@@ -383,10 +383,7 @@ public class Server implements AutoCloseable, Runnable {
} }
} }
static final Message STOP = new Message() { private void handle(DaemonConnection connection, BuildRequest buildRequest) {
};
private void handle(DaemonConnection<Message> connection, BuildRequest buildRequest) {
updateState(Busy); updateState(Busy);
try { try {
int keepAlive = Environment.DAEMON_KEEP_ALIVE_MS.systemProperty().asInt(); int keepAlive = Environment.DAEMON_KEEP_ALIVE_MS.systemProperty().asInt();
@@ -411,7 +408,7 @@ public class Server implements AutoCloseable, Runnable {
if (flushed) { if (flushed) {
m = queue.poll(keepAlive, TimeUnit.MILLISECONDS); m = queue.poll(keepAlive, TimeUnit.MILLISECONDS);
if (m == null) { if (m == null) {
m = new KeepAliveMessage(); m = KeepAliveMessage.SINGLETON;
} }
flushed = false; flushed = false;
} else { } else {
@@ -422,7 +419,7 @@ public class Server implements AutoCloseable, Runnable {
continue; continue;
} }
} }
if (m == STOP) { if (m == StopMessage.SINGLETON) {
connection.flush(); connection.flush();
LOGGER.info("No more message to dispatch"); LOGGER.info("No more message to dispatch");
return; return;
@@ -473,7 +470,7 @@ public class Server implements AutoCloseable, Runnable {
return 96; return 96;
} else if (m instanceof BuildException) { } else if (m instanceof BuildException) {
return 97; return 97;
} else if (m == STOP) { } else if (m == StopMessage.SINGLETON) {
return 99; return 99;
} else if (m instanceof KeepAliveMessage) { } else if (m instanceof KeepAliveMessage) {
return 100; return 100;
@@ -537,12 +534,12 @@ public class Server implements AutoCloseable, Runnable {
public void finish() throws Exception { public void finish() throws Exception {
queue.add(new BuildEvent(Type.BuildStopped, "", "")); queue.add(new BuildEvent(Type.BuildStopped, "", ""));
queue.add(STOP); queue.add(StopMessage.SINGLETON);
} }
public void fail(Throwable t) throws Exception { public void fail(Throwable t) throws Exception {
queue.add(new BuildException(t)); queue.add(new BuildException(t));
queue.add(STOP); queue.add(StopMessage.SINGLETON);
} }
@Override @Override