This commit is contained in:
David Dehaven 2017-02-13 11:51:03 -08:00
commit eca7a98977
50 changed files with 581 additions and 371 deletions

View File

@ -26,6 +26,7 @@ package java.lang.invoke;
import sun.invoke.util.Wrapper;
import static java.lang.invoke.MethodHandleInfo.*;
import static sun.invoke.util.Wrapper.forPrimitiveType;
import static sun.invoke.util.Wrapper.forWrapperType;
import static sun.invoke.util.Wrapper.isWrapperType;
@ -56,11 +57,11 @@ import static sun.invoke.util.Wrapper.isWrapperType;
final String samMethodName; // Name of the SAM method "foo"
final MethodType samMethodType; // Type of the SAM method "(Object)Object"
final MethodHandle implMethod; // Raw method handle for the implementation method
final MethodType implMethodType; // Type of the implMethod MethodHandle "(CC,int)String"
final MethodHandleInfo implInfo; // Info about the implementation method handle "MethodHandleInfo[5 CC.impl(int)String]"
final int implKind; // Invocation kind for implementation "5"=invokevirtual
final boolean implIsInstanceMethod; // Is the implementation an instance method "true"
final Class<?> implDefiningClass; // Type defining the implementation "class CC"
final MethodType implMethodType; // Type of the implementation method "(int)String"
final Class<?> implClass; // Class for referencing the implementation method "class CC"
final MethodType instantiatedMethodType; // Instantiated erased functional interface method type "(Integer)Object"
final boolean isSerializable; // Should the returned instance be serializable
final Class<?>[] markerInterfaces; // Additional marker interfaces to be implemented
@ -128,14 +129,34 @@ import static sun.invoke.util.Wrapper.isWrapperType;
this.samMethodType = samMethodType;
this.implMethod = implMethod;
this.implMethodType = implMethod.type();
this.implInfo = caller.revealDirect(implMethod);
this.implKind = implInfo.getReferenceKind();
this.implIsInstanceMethod =
implKind == MethodHandleInfo.REF_invokeVirtual ||
implKind == MethodHandleInfo.REF_invokeSpecial ||
implKind == MethodHandleInfo.REF_invokeInterface;
this.implDefiningClass = implInfo.getDeclaringClass();
this.implMethodType = implInfo.getMethodType();
switch (implInfo.getReferenceKind()) {
case REF_invokeVirtual:
case REF_invokeInterface:
this.implClass = implMethodType.parameterType(0);
// reference kind reported by implInfo may not match implMethodType's first param
// Example: implMethodType is (Cloneable)String, implInfo is for Object.toString
this.implKind = implClass.isInterface() ? REF_invokeInterface : REF_invokeVirtual;
this.implIsInstanceMethod = true;
break;
case REF_invokeSpecial:
// JDK-8172817: should use referenced class here, but we don't know what it was
this.implClass = implInfo.getDeclaringClass();
this.implKind = REF_invokeSpecial;
this.implIsInstanceMethod = true;
break;
case REF_invokeStatic:
case REF_newInvokeSpecial:
// JDK-8172817: should use referenced class here for invokestatic, but we don't know what it was
this.implClass = implInfo.getDeclaringClass();
this.implKind = implInfo.getReferenceKind();
this.implIsInstanceMethod = false;
break;
default:
throw new LambdaConversionException(String.format("Unsupported MethodHandle kind: %s", implInfo));
}
this.instantiatedMethodType = instantiatedMethodType;
this.isSerializable = isSerializable;
this.markerInterfaces = markerInterfaces;
@ -183,24 +204,12 @@ import static sun.invoke.util.Wrapper.isWrapperType;
* @throws LambdaConversionException if there are improper conversions
*/
void validateMetafactoryArgs() throws LambdaConversionException {
switch (implKind) {
case MethodHandleInfo.REF_invokeInterface:
case MethodHandleInfo.REF_invokeVirtual:
case MethodHandleInfo.REF_invokeStatic:
case MethodHandleInfo.REF_newInvokeSpecial:
case MethodHandleInfo.REF_invokeSpecial:
break;
default:
throw new LambdaConversionException(String.format("Unsupported MethodHandle kind: %s", implInfo));
}
// Check arity: optional-receiver + captured + SAM == impl
// Check arity: captured + SAM == impl
final int implArity = implMethodType.parameterCount();
final int receiverArity = implIsInstanceMethod ? 1 : 0;
final int capturedArity = invokedType.parameterCount();
final int samArity = samMethodType.parameterCount();
final int instantiatedArity = instantiatedMethodType.parameterCount();
if (implArity + receiverArity != capturedArity + samArity) {
if (implArity != capturedArity + samArity) {
throw new LambdaConversionException(
String.format("Incorrect number of parameters for %s method %s; %d captured parameters, %d functional interface method parameters, %d implementation parameters",
implIsInstanceMethod ? "instance" : "static", implInfo,
@ -221,8 +230,8 @@ import static sun.invoke.util.Wrapper.isWrapperType;
}
// If instance: first captured arg (receiver) must be subtype of class where impl method is defined
final int capturedStart;
final int samStart;
final int capturedStart; // index of first non-receiver capture parameter in implMethodType
final int samStart; // index of first non-receiver sam parameter in implMethodType
if (implIsInstanceMethod) {
final Class<?> receiverClass;
@ -235,45 +244,36 @@ import static sun.invoke.util.Wrapper.isWrapperType;
} else {
// receiver is a captured variable
capturedStart = 1;
samStart = 0;
samStart = capturedArity;
receiverClass = invokedType.parameterType(0);
}
// check receiver type
if (!implDefiningClass.isAssignableFrom(receiverClass)) {
if (!implClass.isAssignableFrom(receiverClass)) {
throw new LambdaConversionException(
String.format("Invalid receiver type %s; not a subtype of implementation type %s",
receiverClass, implDefiningClass));
}
Class<?> implReceiverClass = implMethod.type().parameterType(0);
if (implReceiverClass != implDefiningClass && !implReceiverClass.isAssignableFrom(receiverClass)) {
throw new LambdaConversionException(
String.format("Invalid receiver type %s; not a subtype of implementation receiver type %s",
receiverClass, implReceiverClass));
receiverClass, implClass));
}
} else {
// no receiver
capturedStart = 0;
samStart = 0;
samStart = capturedArity;
}
// Check for exact match on non-receiver captured arguments
final int implFromCaptured = capturedArity - capturedStart;
for (int i=0; i<implFromCaptured; i++) {
for (int i=capturedStart; i<capturedArity; i++) {
Class<?> implParamType = implMethodType.parameterType(i);
Class<?> capturedParamType = invokedType.parameterType(i + capturedStart);
Class<?> capturedParamType = invokedType.parameterType(i);
if (!capturedParamType.equals(implParamType)) {
throw new LambdaConversionException(
String.format("Type mismatch in captured lambda parameter %d: expecting %s, found %s",
i, capturedParamType, implParamType));
}
}
// Check for adaptation match on SAM arguments
final int samOffset = samStart - implFromCaptured;
for (int i=implFromCaptured; i<implArity; i++) {
// Check for adaptation match on non-receiver SAM arguments
for (int i=samStart; i<implArity; i++) {
Class<?> implParamType = implMethodType.parameterType(i);
Class<?> instantiatedParamType = instantiatedMethodType.parameterType(i + samOffset);
Class<?> instantiatedParamType = instantiatedMethodType.parameterType(i - capturedArity);
if (!isAdaptableTo(instantiatedParamType, implParamType, true)) {
throw new LambdaConversionException(
String.format("Type mismatch for lambda argument %d: %s is not convertible to %s",
@ -283,10 +283,7 @@ import static sun.invoke.util.Wrapper.isWrapperType;
// Adaptation match: return type
Class<?> expectedType = instantiatedMethodType.returnType();
Class<?> actualReturnType =
(implKind == MethodHandleInfo.REF_newInvokeSpecial)
? implDefiningClass
: implMethodType.returnType();
Class<?> actualReturnType = implMethodType.returnType();
if (!isAdaptableToAsReturn(actualReturnType, expectedType)) {
throw new LambdaConversionException(
String.format("Type mismatch for lambda return: %s is not convertible to %s",

View File

@ -96,7 +96,6 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*;
private final String implMethodClassName; // Name of type containing implementation "CC"
private final String implMethodName; // Name of implementation method "impl"
private final String implMethodDesc; // Type descriptor for implementation methods "(I)Ljava/lang/String;"
private final Class<?> implMethodReturnClass; // class for implementation method return type "Ljava/lang/String;"
private final MethodType constructorType; // Generated class constructor type "(CC)void"
private final ClassWriter cw; // ASM class writer
private final String[] argNames; // Generated names for the constructor arguments
@ -153,12 +152,9 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*;
super(caller, invokedType, samMethodName, samMethodType,
implMethod, instantiatedMethodType,
isSerializable, markerInterfaces, additionalBridges);
implMethodClassName = implDefiningClass.getName().replace('.', '/');
implMethodClassName = implClass.getName().replace('.', '/');
implMethodName = implInfo.getName();
implMethodDesc = implMethodType.toMethodDescriptorString();
implMethodReturnClass = (implKind == MethodHandleInfo.REF_newInvokeSpecial)
? implDefiningClass
: implMethodType.returnType();
implMethodDesc = implInfo.getMethodType().toMethodDescriptorString();
constructorType = invokedType.changeReturnType(Void.TYPE);
lambdaClassName = targetClass.getName().replace('.', '/') + "$$Lambda$" + counter.incrementAndGet();
cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
@ -467,13 +463,14 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*;
// Invoke the method we want to forward to
visitMethodInsn(invocationOpcode(), implMethodClassName,
implMethodName, implMethodDesc,
implDefiningClass.isInterface());
implClass.isInterface());
// Convert the return value (if any) and return it
// Note: if adapting from non-void to void, the 'return'
// instruction will pop the unneeded result
Class<?> implReturnClass = implMethodType.returnType();
Class<?> samReturnClass = methodType.returnType();
convertType(implMethodReturnClass, samReturnClass, samReturnClass);
convertType(implReturnClass, samReturnClass, samReturnClass);
visitInsn(getReturnOpcode(samReturnClass));
// Maxs computed by ClassWriter.COMPUTE_MAXS,these arguments ignored
visitMaxs(-1, -1);
@ -482,23 +479,13 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*;
private void convertArgumentTypes(MethodType samType) {
int lvIndex = 0;
boolean samIncludesReceiver = implIsInstanceMethod &&
invokedType.parameterCount() == 0;
int samReceiverLength = samIncludesReceiver ? 1 : 0;
if (samIncludesReceiver) {
// push receiver
Class<?> rcvrType = samType.parameterType(0);
visitVarInsn(getLoadOpcode(rcvrType), lvIndex + 1);
lvIndex += getParameterSize(rcvrType);
convertType(rcvrType, implDefiningClass, instantiatedMethodType.parameterType(0));
}
int samParametersLength = samType.parameterCount();
int argOffset = implMethodType.parameterCount() - samParametersLength;
for (int i = samReceiverLength; i < samParametersLength; i++) {
int captureArity = invokedType.parameterCount();
for (int i = 0; i < samParametersLength; i++) {
Class<?> argType = samType.parameterType(i);
visitVarInsn(getLoadOpcode(argType), lvIndex + 1);
lvIndex += getParameterSize(argType);
convertType(argType, implMethodType.parameterType(argOffset + i), instantiatedMethodType.parameterType(i));
convertType(argType, implMethodType.parameterType(captureArity + i), instantiatedMethodType.parameterType(i));
}
}

View File

@ -78,7 +78,7 @@ public class JmodFile implements AutoCloseable {
HEADER_FILES("include"),
LEGAL_NOTICES("legal"),
MAN_PAGES("man"),
NATIVE_LIBS("native"),
NATIVE_LIBS("lib"),
NATIVE_CMDS("bin");
private final String jmodDir;

View File

@ -609,11 +609,13 @@ class AsyncSSLDelegate implements ExceptionallyCloseable, AsyncConnection {
}
// SSLParameters.getApplicationProtocols() can't return null
// JDK 8 EXCL START
for (String approto : p.getApplicationProtocols()) {
sb.append("\n application protocol: {")
.append(params.size()).append("}");
params.add(approto);
}
// JDK 8 EXCL END
if (p.getProtocols() != null) {
for (String protocol : p.getProtocols()) {

View File

@ -91,11 +91,13 @@ class DefaultPublisher<T> implements Flow.Publisher<T> {
for (long i = 0; i < nbItemsDemanded && !done.get(); i++) {
try {
Optional<T> item = Objects.requireNonNull(supplier.get());
item.ifPresentOrElse(subscriber::onNext, () -> {
if (item.isPresent()) {
subscriber.onNext(item.get());
} else {
if (done.compareAndSet(false, true)) {
subscriber.onComplete();
}
});
}
} catch (RuntimeException e) {
if (done.compareAndSet(false, true)) {
subscriber.onError(e);

View File

@ -30,6 +30,8 @@ import java.io.UncheckedIOException;
import java.net.URI;
import jdk.incubator.http.ResponseProcessors.MultiFile;
import jdk.incubator.http.ResponseProcessors.MultiProcessorImpl;
import static jdk.incubator.http.internal.common.Utils.unchecked;
import static jdk.incubator.http.internal.common.Utils.charsetFrom;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
@ -269,19 +271,6 @@ public abstract class HttpResponse<T> {
};
}
/**
* Get the Charset from the Content-encoding header. Defaults to
* UTF_8
*/
private static Charset charsetFrom(HttpHeaders headers) {
String encoding = headers.firstValue("Content-encoding")
.orElse("UTF_8");
try {
return Charset.forName(encoding);
} catch (IllegalArgumentException e) {
return StandardCharsets.UTF_8;
}
}
/**
* Returns a {@code BodyHandler<Path>} that returns a
@ -342,10 +331,6 @@ public abstract class HttpResponse<T> {
};
}
private static UncheckedIOException unchecked(IOException e) {
return new UncheckedIOException(e);
}
/**
* Returns a {@code BodyHandler<Path>} that returns a
* {@link BodyProcessor BodyProcessor}{@code <Path>} obtained from
@ -743,48 +728,5 @@ public abstract class HttpResponse<T> {
return asMap(pushHandler, true);
}
/**
* Returns a {@code MultiProcessor} which writes the response bodies to
* files under a given root directory and which returns an aggregate
* response map that is a {@code Map<HttpRequest, HttpResponse<Path>>}.
* The keyset of the {@code Map} represents the original request and any
* additional requests generated by the server. The values are the
* responses containing the paths of the destination files. Each file
* uses the URI path of the request relative to the destination parent
* directorycprovided.
*
* <p>
* All incoming additional requests (push promises) are accepted by this
* multi response processor. Errors are effectively ignored and any
* failed responses are simply omitted from the result {@code Map}.
* Other implementations of {@code MultiProcessor} may handle these
* situations.
*
* <p>
* <b>Example usage</b>
* <pre>
* {@code
* HttpClient client = ..
* HttpRequest request = HttpRequest
* .create(new URI("https://www.foo.com/"))
* .version(Version.HTTP2)
* .GET();
*
* Map<HttpRequest, HttpResponse<Path>>> map = client
* .sendAsync(HttpResponse.MultiProcessor.multiFile("/usr/destination"))
* .join();
*
* }
* </pre>
* TEMPORARILY REMOVING THIS FROM API. MIGHT NOT BE NEEDED.
*
* @param destination the destination parent directory of all response
* bodies
* @return a MultiProcessor
*/
private static MultiProcessor<MultiMapResult<Path>,Path> multiFile(Path destination) {
MultiFile mf = new MultiFile(destination);
return new MultiProcessorImpl<Path>(mf::handlePush, true);
}
}
}

View File

@ -252,7 +252,7 @@ class ResponseProcessors {
@Override
public void onError(HttpRequest request, Throwable t) {
results.put(request, CompletableFuture.failedFuture(t));
results.put(request, MinimalFuture.failedFuture(t));
}
@Override

View File

@ -449,9 +449,11 @@ class SSLDelegate {
for (String cipher : p.getCipherSuites()) {
System.out.printf("cipher: %s\n", cipher);
}
// JDK 8 EXCL START
for (String approto : p.getApplicationProtocols()) {
System.out.printf("application protocol: %s\n", approto);
}
// JDK 8 EXCL END
for (String protocol : p.getProtocols()) {
System.out.printf("protocol: %s\n", protocol);
}

View File

@ -110,7 +110,6 @@ public final class MinimalFuture<T> extends CompletableFuture<T> {
}
}
@Override
public <U> MinimalFuture<U> newIncompleteFuture() {
return new MinimalFuture<>();
}

View File

@ -118,11 +118,13 @@ public class Queue<T> implements ExceptionallyCloseable {
public synchronized void closeExceptionally(Throwable t) {
if (exception == null) exception = t;
else if (t != null && t != exception) {
Stream.of(exception.getSuppressed())
if (!Stream.of(exception.getSuppressed())
.filter(x -> x == t)
.findFirst()
.ifPresentOrElse((x) -> {},
() -> exception.addSuppressed(t));
.isPresent())
{
exception.addSuppressed(t);
}
}
close();
}

View File

@ -32,12 +32,14 @@ import javax.net.ssl.SSLParameters;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.net.NetPermission;
import java.net.URI;
import java.net.URLPermission;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.AccessController;
import java.security.PrivilegedAction;
@ -54,6 +56,7 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.function.Predicate;
import jdk.incubator.http.HttpHeaders;
/**
* Miscellaneous utilities
@ -259,9 +262,11 @@ public final class Utils {
SSLParameters p1 = new SSLParameters();
p1.setAlgorithmConstraints(p.getAlgorithmConstraints());
p1.setCipherSuites(p.getCipherSuites());
// JDK 8 EXCL START
p1.setEnableRetransmissions(p.getEnableRetransmissions());
p1.setEndpointIdentificationAlgorithm(p.getEndpointIdentificationAlgorithm());
p1.setMaximumPacketSize(p.getMaximumPacketSize());
// JDK 8 EXCL END
p1.setEndpointIdentificationAlgorithm(p.getEndpointIdentificationAlgorithm());
p1.setNeedClientAuth(p.getNeedClientAuth());
String[] protocols = p.getProtocols();
if (protocols != null) {
@ -475,4 +480,21 @@ public final class Utils {
return newb;
}
/**
* Get the Charset from the Content-encoding header. Defaults to
* UTF_8
*/
public static Charset charsetFrom(HttpHeaders headers) {
String encoding = headers.firstValue("Content-encoding")
.orElse("UTF_8");
try {
return Charset.forName(encoding);
} catch (IllegalArgumentException e) {
return StandardCharsets.UTF_8;
}
}
public static UncheckedIOException unchecked(IOException e) {
return new UncheckedIOException(e);
}
}

View File

@ -26,6 +26,7 @@
package jdk.incubator.http.internal.websocket;
import jdk.incubator.http.WebSocket.MessagePart;
import jdk.incubator.http.internal.common.Log;
import jdk.incubator.http.internal.websocket.Frame.Opcode;
import java.nio.ByteBuffer;
@ -33,13 +34,11 @@ import java.nio.CharBuffer;
import java.nio.charset.CharacterCodingException;
import static java.lang.String.format;
import static java.lang.System.Logger.Level.TRACE;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Objects.requireNonNull;
import static jdk.incubator.http.internal.common.Utils.dump;
import static jdk.incubator.http.internal.websocket.StatusCodes.NO_STATUS_CODE;
import static jdk.incubator.http.internal.websocket.StatusCodes.checkIncomingCode;
import static jdk.incubator.http.internal.websocket.WebSocketImpl.logger;
/*
* Consumes frame parts and notifies a message consumer, when there is
@ -71,17 +70,13 @@ class FrameConsumer implements Frame.Consumer {
@Override
public void fin(boolean value) {
if (logger.isLoggable(TRACE)) {
logger.log(TRACE, "Reading fin: {0}", value);
}
Log.logTrace("Reading fin: {0}", value);
fin = value;
}
@Override
public void rsv1(boolean value) {
if (logger.isLoggable(TRACE)) {
logger.log(TRACE, "Reading rsv1: {0}", value);
}
Log.logTrace("Reading rsv1: {0}", value);
if (value) {
throw new FailWebSocketException("Unexpected rsv1 bit");
}
@ -89,9 +84,7 @@ class FrameConsumer implements Frame.Consumer {
@Override
public void rsv2(boolean value) {
if (logger.isLoggable(TRACE)) {
logger.log(TRACE, "Reading rsv2: {0}", value);
}
Log.logTrace("Reading rsv2: {0}", value);
if (value) {
throw new FailWebSocketException("Unexpected rsv2 bit");
}
@ -99,9 +92,7 @@ class FrameConsumer implements Frame.Consumer {
@Override
public void rsv3(boolean value) {
if (logger.isLoggable(TRACE)) {
logger.log(TRACE, "Reading rsv3: {0}", value);
}
Log.logTrace("Reading rsv3: {0}", value);
if (value) {
throw new FailWebSocketException("Unexpected rsv3 bit");
}
@ -109,7 +100,7 @@ class FrameConsumer implements Frame.Consumer {
@Override
public void opcode(Opcode v) {
logger.log(TRACE, "Reading opcode: {0}", v);
Log.logTrace("Reading opcode: {0}", v);
if (v == Opcode.PING || v == Opcode.PONG || v == Opcode.CLOSE) {
if (!fin) {
throw new FailWebSocketException("Fragmented control frame " + v);
@ -137,9 +128,7 @@ class FrameConsumer implements Frame.Consumer {
@Override
public void mask(boolean value) {
if (logger.isLoggable(TRACE)) {
logger.log(TRACE, "Reading mask: {0}", value);
}
Log.logTrace("Reading mask: {0}", value);
if (value) {
throw new FailWebSocketException("Masked frame received");
}
@ -147,10 +136,7 @@ class FrameConsumer implements Frame.Consumer {
@Override
public void payloadLen(long value) {
if (logger.isLoggable(TRACE)) {
// Checked for being loggable because of autoboxing of 'value'
logger.log(TRACE, "Reading payloadLen: {0}", value);
}
Log.logTrace("Reading payloadLen: {0}", value);
if (opcode.isControl()) {
if (value > 125) {
throw new FailWebSocketException(
@ -178,9 +164,7 @@ class FrameConsumer implements Frame.Consumer {
@Override
public void payloadData(ByteBuffer data) {
if (logger.isLoggable(TRACE)) {
logger.log(TRACE, "Reading payloadData: data={0}", data);
}
Log.logTrace("Reading payloadData: data={0}", data);
unconsumedPayloadLen -= data.remaining();
boolean isLast = unconsumedPayloadLen == 0;
if (opcode.isControl()) {

View File

@ -25,6 +25,8 @@
package jdk.incubator.http.internal.websocket;
import jdk.incubator.http.internal.common.Log;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.CharacterCodingException;
@ -32,10 +34,8 @@ import java.nio.charset.CharsetDecoder;
import java.nio.charset.CoderResult;
import java.nio.charset.CodingErrorAction;
import static java.lang.System.Logger.Level.WARNING;
import static java.nio.charset.StandardCharsets.UTF_8;
import static jdk.incubator.http.internal.common.Utils.EMPTY_BYTEBUFFER;
import static jdk.incubator.http.internal.websocket.WebSocketImpl.logger;
final class UTF8AccumulatingDecoder {
@ -74,9 +74,8 @@ final class UTF8AccumulatingDecoder {
// Since it's UTF-8, the assumption is leftovers.remaining() < 4
// (i.e. small). Otherwise a shared buffer should be used
if (!(leftovers.remaining() < 4)) {
logger.log(WARNING,
"The size of decoding leftovers is greater than expected: {0}",
leftovers.remaining());
Log.logError("The size of decoding leftovers is greater than expected: {0}",
leftovers.remaining());
}
b.position(b.limit()); // As if we always read to the end
// Decoder promises that in the case of endOfInput == true:

View File

@ -26,6 +26,7 @@
package jdk.incubator.http.internal.websocket;
import jdk.incubator.http.WebSocket;
import jdk.incubator.http.internal.common.Log;
import jdk.incubator.http.internal.common.Pair;
import jdk.incubator.http.internal.websocket.OpeningHandshake.Result;
import jdk.incubator.http.internal.websocket.OutgoingMessage.Binary;
@ -47,8 +48,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;
import java.util.function.Function;
import static java.lang.System.Logger.Level.ERROR;
import static java.lang.System.Logger.Level.TRACE;
import static java.util.Objects.requireNonNull;
import static java.util.concurrent.CompletableFuture.failedFuture;
import static jdk.incubator.http.internal.common.Pair.pair;
@ -61,8 +60,6 @@ import static jdk.incubator.http.internal.websocket.StatusCodes.checkOutgoingCod
*/
final class WebSocketImpl implements WebSocket {
static final System.Logger logger = System.getLogger("jdk.httpclient.WebSocket");
private final URI uri;
private final String subprotocol;
private final RawChannel channel;
@ -142,7 +139,7 @@ final class WebSocketImpl implements WebSocket {
try {
channel.close();
} catch (IOException e) {
logger.log(ERROR, e);
Log.logError(e);
} finally {
closed.set(true);
}
@ -168,14 +165,14 @@ final class WebSocketImpl implements WebSocket {
private void signalError(Throwable error) {
synchronized (lock) {
if (lastMethodInvoked) {
logger.log(ERROR, error);
Log.logError(error);
} else {
lastMethodInvoked = true;
receiver.close();
try {
listener.onError(this, error);
} catch (Exception e) {
logger.log(ERROR, e);
Log.logError(e);
}
}
}
@ -190,7 +187,7 @@ final class WebSocketImpl implements WebSocket {
try {
channel.shutdownInput();
} catch (IOException e) {
logger.log(ERROR, e);
Log.logError(e);
}
boolean wasComplete = !closeReceived.complete(null);
if (wasComplete) {
@ -210,7 +207,7 @@ final class WebSocketImpl implements WebSocket {
enqueueClose(new Close(code, ""))
.whenComplete((r1, error1) -> {
if (error1 != null) {
logger.log(ERROR, error1);
Log.logError(error1);
}
});
});
@ -223,14 +220,14 @@ final class WebSocketImpl implements WebSocket {
private CompletionStage<?> signalClose(int statusCode, String reason) {
synchronized (lock) {
if (lastMethodInvoked) {
logger.log(TRACE, "Close: {0}, ''{1}''", statusCode, reason);
Log.logTrace("Close: {0}, ''{1}''", statusCode, reason);
} else {
lastMethodInvoked = true;
receiver.close();
try {
return listener.onClose(this, statusCode, reason);
} catch (Exception e) {
logger.log(ERROR, e);
Log.logError(e);
}
}
}
@ -289,7 +286,7 @@ final class WebSocketImpl implements WebSocket {
try {
channel.shutdownOutput();
} catch (IOException e) {
logger.log(ERROR, e);
Log.logError(e);
}
boolean wasComplete = !closeSent.complete(null);
if (wasComplete) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -38,7 +38,7 @@ import java.security.cert.CertificateException;
* @deprecated This class has been deprecated.
*/
@Deprecated
@Deprecated(since="9")
public abstract class ContentSigner {
/**

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -36,7 +36,7 @@ import java.util.zip.ZipFile;
* @author Vincent Ryan
* @deprecated This class has been deprecated.
*/
@Deprecated
@Deprecated(since="9")
public interface ContentSignerParameters {
/**

View File

@ -158,7 +158,7 @@ public class Main {
static final String MANIFEST_DIR = "META-INF/";
static final String VERSIONS_DIR = MANIFEST_DIR + "versions/";
static final String VERSION = "1.0";
static final int VERSIONS_DIR_LENGTH = VERSIONS_DIR.length();
private static ResourceBundle rsrc;
/**
@ -681,7 +681,7 @@ public class Main {
void addPackageIfNamed(Set<String> packages, String name) {
if (name.startsWith(VERSIONS_DIR)) {
// trim the version dir prefix
int i0 = VERSIONS_DIR.length();
int i0 = VERSIONS_DIR_LENGTH;
int i = name.indexOf('/', i0);
if (i <= 0) {
warn(formatMsg("warn.release.unexpected.versioned.entry", name));
@ -1727,12 +1727,16 @@ public class Main {
private boolean printModuleDescriptor(ZipFile zipFile)
throws IOException
{
ZipEntry entry = zipFile.getEntry(MODULE_INFO);
if (entry == null)
ZipEntry[] zes = zipFile.stream()
.filter(e -> isModuleInfoEntry(e.getName()))
.sorted(Validator.ENTRY_COMPARATOR)
.toArray(ZipEntry[]::new);
if (zes.length == 0)
return false;
try (InputStream is = zipFile.getInputStream(entry)) {
printModuleDescriptor(is);
for (ZipEntry ze : zes) {
try (InputStream is = zipFile.getInputStream(ze)) {
printModuleDescriptor(is, ze.getName());
}
}
return true;
}
@ -1742,16 +1746,23 @@ public class Main {
{
try (BufferedInputStream bis = new BufferedInputStream(fis);
ZipInputStream zis = new ZipInputStream(bis)) {
ZipEntry e;
while ((e = zis.getNextEntry()) != null) {
if (e.getName().equals(MODULE_INFO)) {
printModuleDescriptor(zis);
return true;
String ename = e.getName();
if (isModuleInfoEntry(ename)){
moduleInfos.put(ename, zis.readAllBytes());
}
}
}
return false;
if (moduleInfos.size() == 0)
return false;
String[] names = moduleInfos.keySet().stream()
.sorted(Validator.ENTRYNAME_COMPARATOR)
.toArray(String[]::new);
for (String name : names) {
printModuleDescriptor(new ByteArrayInputStream(moduleInfos.get(name)), name);
}
return true;
}
static <T> String toString(Collection<T> set) {
@ -1760,7 +1771,7 @@ public class Main {
.collect(joining(" "));
}
private void printModuleDescriptor(InputStream entryInputStream)
private void printModuleDescriptor(InputStream entryInputStream, String ename)
throws IOException
{
ModuleInfo.Attributes attrs = ModuleInfo.read(entryInputStream, null);
@ -1768,10 +1779,12 @@ public class Main {
ModuleHashes hashes = attrs.recordedHashes();
StringBuilder sb = new StringBuilder();
sb.append("\n");
sb.append("\nmodule ")
.append(md.toNameAndVersion())
.append(" (").append(ename).append(")");
if (md.isOpen())
sb.append("open ");
sb.append(md.toNameAndVersion());
sb.append("\n open ");
md.requires().stream()
.sorted(Comparator.comparing(Requires::name))
@ -1879,7 +1892,7 @@ public class Main {
if (end == 0)
return true;
if (name.startsWith(VERSIONS_DIR)) {
int off = VERSIONS_DIR.length();
int off = VERSIONS_DIR_LENGTH;
if (off == end) // meta-inf/versions/module-info.class
return false;
while (off < end - 1) {

View File

@ -49,6 +49,7 @@ import java.util.zip.ZipEntry;
import static java.util.jar.JarFile.MANIFEST_NAME;
import static sun.tools.jar.Main.VERSIONS_DIR;
import static sun.tools.jar.Main.VERSIONS_DIR_LENGTH;
import static sun.tools.jar.Main.MODULE_INFO;
import static sun.tools.jar.Main.getMsg;
import static sun.tools.jar.Main.formatMsg;
@ -59,19 +60,19 @@ import static sun.tools.jar.Main.isModuleInfoEntry;
final class Validator {
private final static boolean DEBUG = Boolean.getBoolean("jar.debug");
private final Map<String,FingerPrint> fps = new HashMap<>();
private static final int vdlen = VERSIONS_DIR.length();
private final Main main;
private final JarFile jf;
private int oldVersion = -1;
private String currentTopLevelName;
private boolean isValid = true;
private Set<String> concealedPkgs;
private Set<String> concealedPkgs = Collections.emptySet();
private ModuleDescriptor md;
private String mdName;
private Validator(Main main, JarFile jf) {
this.main = main;
this.jf = jf;
loadModuleDescriptor();
checkModuleDescriptor(MODULE_INFO);
}
static boolean validate(Main main, JarFile jf) throws IOException {
@ -83,7 +84,7 @@ final class Validator {
jf.stream()
.filter(e -> !e.isDirectory() &&
!e.getName().equals(MANIFEST_NAME))
.sorted(entryComparator)
.sorted(ENTRY_COMPARATOR)
.forEachOrdered(e -> validate(e));
return isValid;
} catch (InvalidJarException e) {
@ -102,9 +103,8 @@ final class Validator {
// sort base entries before versioned entries, and sort entry classes with
// nested classes so that the top level class appears before the associated
// nested class
private static Comparator<JarEntry> entryComparator = (je1, je2) -> {
String s1 = je1.getName();
String s2 = je2.getName();
static Comparator<String> ENTRYNAME_COMPARATOR = (s1, s2) -> {
if (s1.equals(s2)) return 0;
boolean b1 = s1.startsWith(VERSIONS_DIR);
boolean b2 = s2.startsWith(VERSIONS_DIR);
@ -140,6 +140,9 @@ final class Validator {
return l1 - l2;
};
static Comparator<ZipEntry> ENTRY_COMPARATOR =
Comparator.comparing(ZipEntry::getName, ENTRYNAME_COMPARATOR);
/*
* Validator has state and assumes entries provided to accept are ordered
* from base entries first and then through the versioned entries in
@ -158,24 +161,25 @@ final class Validator {
// validate the versioned module-info
if (isModuleInfoEntry(entryName)) {
if (entryName.length() != MODULE_INFO.length())
checkModuleDescriptor(je);
if (!entryName.equals(mdName))
checkModuleDescriptor(entryName);
return;
}
// figure out the version and basename from the JarEntry
int version;
String basename;
String versionStr = null;;
if (entryName.startsWith(VERSIONS_DIR)) {
int n = entryName.indexOf("/", vdlen);
int n = entryName.indexOf("/", VERSIONS_DIR_LENGTH);
if (n == -1) {
error(formatMsg("error.validator.version.notnumber", entryName));
isValid = false;
return;
}
String v = entryName.substring(vdlen, n);
versionStr = entryName.substring(VERSIONS_DIR_LENGTH, n);
try {
version = Integer.parseInt(v);
version = Integer.parseInt(versionStr);
} catch (NumberFormatException x) {
error(formatMsg("error.validator.version.notnumber", entryName));
isValid = false;
@ -196,6 +200,11 @@ final class Validator {
if (oldVersion != version) {
oldVersion = version;
currentTopLevelName = null;
if (md == null && versionStr != null) {
// don't have a base module-info.class yet, try to see if
// a versioned one exists
checkModuleDescriptor(VERSIONS_DIR + versionStr + "/" + MODULE_INFO);
}
}
// analyze the entry, keeping key attributes
@ -308,61 +317,52 @@ final class Validator {
return;
}
private void loadModuleDescriptor() {
ZipEntry je = jf.getEntry(MODULE_INFO);
if (je != null) {
try (InputStream jis = jf.getInputStream(je)) {
md = ModuleDescriptor.read(jis);
concealedPkgs = new HashSet<>(md.packages());
md.exports().stream().map(Exports::source).forEach(concealedPkgs::remove);
md.opens().stream().map(Opens::source).forEach(concealedPkgs::remove);
return;
} catch (Exception x) {
error(x.getMessage() + " : " + je.getName());
this.isValid = false;
}
}
md = null;
concealedPkgs = Collections.emptySet();
}
private static boolean isPlatformModule(String name) {
return name.startsWith("java.") || name.startsWith("jdk.");
}
/**
* Checks whether or not the given versioned module descriptor's attributes
* are valid when compared against the root module descriptor.
* are valid when compared against the root/base module descriptor.
*
* A versioned module descriptor must be identical to the root module
* A versioned module descriptor must be identical to the root/base module
* descriptor, with two exceptions:
* - A versioned descriptor can have different non-public `requires`
* clauses of platform ( `java.*` and `jdk.*` ) modules, and
* - A versioned descriptor can have different `uses` clauses, even of
* service types defined outside of the platform modules.
*/
private void checkModuleDescriptor(JarEntry je) {
try (InputStream is = jf.getInputStream(je)) {
ModuleDescriptor root = this.md;
ModuleDescriptor md = null;
try {
md = ModuleDescriptor.read(is);
} catch (InvalidModuleDescriptorException x) {
error(x.getMessage());
isValid = false;
return;
}
if (root == null) {
this.md = md;
} else {
if (!root.name().equals(md.name())) {
private void checkModuleDescriptor(String miName) {
ZipEntry je = jf.getEntry(miName);
if (je != null) {
try (InputStream jis = jf.getInputStream(je)) {
ModuleDescriptor md = ModuleDescriptor.read(jis);
// Initialize the base md if it's not yet. A "base" md can be either the
// root module-info.class or the first versioned module-info.class
ModuleDescriptor base = this.md;
if (base == null) {
concealedPkgs = new HashSet<>(md.packages());
md.exports().stream().map(Exports::source).forEach(concealedPkgs::remove);
md.opens().stream().map(Opens::source).forEach(concealedPkgs::remove);
// must have the implementation class of the services it 'provides'.
if (md.provides().stream().map(Provides::providers)
.flatMap(List::stream)
.filter(p -> jf.getEntry(toBinaryName(p)) == null)
.peek(p -> error(formatMsg("error.missing.provider", p)))
.count() != 0) {
isValid = false;
return;
}
this.md = md;
this.mdName = miName;
return;
}
if (!base.name().equals(md.name())) {
error(getMsg("error.validator.info.name.notequal"));
isValid = false;
}
if (!root.requires().equals(md.requires())) {
Set<Requires> rootRequires = root.requires();
if (!base.requires().equals(md.requires())) {
Set<Requires> baseRequires = base.requires();
for (Requires r : md.requires()) {
if (rootRequires.contains(r))
if (baseRequires.contains(r))
continue;
if (r.modifiers().contains(Requires.Modifier.TRANSITIVE)) {
error(getMsg("error.validator.info.requires.transitive"));
@ -372,7 +372,7 @@ final class Validator {
isValid = false;
}
}
for (Requires r : rootRequires) {
for (Requires r : baseRequires) {
Set<Requires> mdRequires = md.requires();
if (mdRequires.contains(r))
continue;
@ -382,33 +382,37 @@ final class Validator {
}
}
}
if (!root.exports().equals(md.exports())) {
if (!base.exports().equals(md.exports())) {
error(getMsg("error.validator.info.exports.notequal"));
isValid = false;
}
if (!root.opens().equals(md.opens())) {
if (!base.opens().equals(md.opens())) {
error(getMsg("error.validator.info.opens.notequal"));
isValid = false;
}
if (!root.provides().equals(md.provides())) {
if (!base.provides().equals(md.provides())) {
error(getMsg("error.validator.info.provides.notequal"));
isValid = false;
}
if (!root.mainClass().equals(md.mainClass())) {
if (!base.mainClass().equals(md.mainClass())) {
error(formatMsg("error.validator.info.manclass.notequal", je.getName()));
isValid = false;
}
if (!root.version().equals(md.version())) {
if (!base.version().equals(md.version())) {
error(formatMsg("error.validator.info.version.notequal", je.getName()));
isValid = false;
}
} catch (Exception x) {
error(x.getMessage() + " : " + miName);
this.isValid = false;
}
} catch (IOException x) {
error(x.getMessage());
isValid = false;
}
}
private static boolean isPlatformModule(String name) {
return name.startsWith("java.") || name.startsWith("jdk.");
}
private boolean checkInternalName(String entryName, String basename, String internalName) {
String className = className(basename);
if (internalName.equals(className)) {

View File

@ -362,7 +362,7 @@ public final class DefaultImageBuilder implements ImageBuilder {
String module = "/" + entry.moduleName() + "/";
String filename = entry.path().substring(module.length());
// Remove radical native|config|...
// Remove radical lib|config|...
return filename.substring(filename.indexOf('/') + 1);
}

View File

@ -38,7 +38,7 @@ import jdk.tools.jlink.plugin.ResourcePoolEntry;
* <li>For jimage content: /{module name}/{package1}/.../{packageN}/{file
* name}</li>
* <li>For other files (shared lib, launchers, config, ...):/{module name}/
* {@literal bin|conf|native}/{dir1}>/.../{dirN}/{file name}</li>
* {@literal bin|conf|lib}/{dir1}>/.../{dirN}/{file name}</li>
* </ul>
*/
abstract class AbstractResourcePoolEntry implements ResourcePoolEntry {

View File

@ -95,9 +95,9 @@ public final class ExcludeVMPlugin implements Plugin {
/**
* VM paths:
* /java.base/native/{architecture}/{server|client|minimal}/{shared lib}
* e.g.: /java.base/native/amd64/server/libjvm.so
* /java.base/native/server/libjvm.dylib
* /java.base/lib/{architecture}/{server|client|minimal}/{shared lib}
* e.g.: /java.base/lib/server/libjvm.so
* /java.base/lib/server/libjvm.dylib
*/
private List<ResourcePoolEntry> getVMs(ResourcePoolModule javaBase, String[] jvmlibs) {
List<ResourcePoolEntry> ret = javaBase.entries().filter((t) -> {
@ -198,17 +198,17 @@ public final class ExcludeVMPlugin implements Plugin {
}
case CLIENT: {
target = Jvm.CLIENT;
exclude = "/java.base/native**server/**,/java.base/native**minimal/**";
exclude = "/java.base/lib**server/**,/java.base/lib**minimal/**";
break;
}
case SERVER: {
target = Jvm.SERVER;
exclude = "/java.base/native**client/**,/java.base/native**minimal/**";
exclude = "/java.base/lib**client/**,/java.base/lib**minimal/**";
break;
}
case MINIMAL: {
target = Jvm.MINIMAL;
exclude = "/java.base/native**server/**,/java.base/native**client/**";
exclude = "/java.base/lib**server/**,/java.base/lib**client/**";
break;
}
default: {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -46,11 +46,16 @@ import java.util.TreeSet;
import java.util.function.IntSupplier;
import jdk.internal.module.Checks;
import jdk.internal.module.ClassFileAttributes;
import jdk.internal.module.ClassFileConstants;
import jdk.internal.module.ModuleHashes;
import jdk.internal.module.ModuleInfo.Attributes;
import jdk.internal.module.ModuleInfoExtender;
import jdk.internal.module.ModuleResolution;
import jdk.internal.module.SystemModules;
import jdk.internal.org.objectweb.asm.Attribute;
import jdk.internal.org.objectweb.asm.ClassReader;
import jdk.internal.org.objectweb.asm.ClassVisitor;
import jdk.internal.org.objectweb.asm.ClassWriter;
import jdk.internal.org.objectweb.asm.MethodVisitor;
import jdk.internal.org.objectweb.asm.Opcodes;
@ -108,6 +113,11 @@ public final class SystemModulesPlugin implements Plugin {
return true;
}
@Override
public String getArgumentsDescription() {
return PluginsResourceBundle.getArgument(NAME);
}
@Override
public void configure(Map<String, String> config) {
String arg = config.get(NAME);
@ -171,10 +181,11 @@ public final class SystemModulesPlugin implements Plugin {
}
static class ModuleInfo {
private final ByteArrayInputStream bain;
private final Attributes attrs;
private final Set<String> packages;
private final ByteArrayInputStream bain;
private final boolean dropModuleTarget;
private final boolean addModulePackages;
private ModuleDescriptor descriptor; // may be different that the original one
ModuleInfo(byte[] bytes, Set<String> packages, boolean dropModuleTarget)
@ -182,15 +193,21 @@ public final class SystemModulesPlugin implements Plugin {
{
this.bain = new ByteArrayInputStream(bytes);
this.packages = packages;
this.attrs = jdk.internal.module.ModuleInfo.read(bain, null);
// If ModulePackages attribute is present, the packages from this
// module descriptor returns the packages in that attribute.
// If it's not present, ModuleDescriptor::packages only contains
// the exported and open packages from module-info.class
this.descriptor = attrs.descriptor();
if (descriptor.isAutomatic()) {
throw new InternalError("linking automatic module is not supported");
}
// add ModulePackages attribute if this module contains some packages
// and ModulePackages is not present
this.addModulePackages = packages.size() > 0 && !hasModulePackages();
// drop target attribute only if any OS property is present
if (dropModuleTarget) {
// drop target attribute only if any OS property is present
this.dropModuleTarget =
descriptor.osName().isPresent() ||
descriptor.osArch().isPresent() ||
@ -276,53 +293,71 @@ public final class SystemModulesPlugin implements Plugin {
}
}
boolean hasModulePackages() throws IOException {
Set<String> attrTypes = new HashSet<>();
ClassVisitor cv = new ClassVisitor(Opcodes.ASM5) {
@Override
public void visitAttribute(Attribute attr) {
attrTypes.add(attr.type);
}
};
// prototype of attributes that should be parsed
Attribute[] attrs = new Attribute[] {
new ClassFileAttributes.ModulePackagesAttribute()
};
try (InputStream in = getInputStream()) {
// parse module-info.class
ClassReader cr = new ClassReader(in);
cr.accept(cv, attrs, 0);
return attrTypes.contains(ClassFileConstants.MODULE_PACKAGES);
}
}
/**
* Returns true if module-info.class should be written
* 1. add ModulePackages attribute if not present; or
* 2. drop ModuleTarget attribute except java.base
*/
boolean shouldRewrite() {
return shouldAddModulePackages() || shouldDropModuleTarget();
}
boolean shouldAddModulePackages() {
return (descriptor.packages().isEmpty() && packages.size() > 0);
}
boolean shouldDropModuleTarget() {
return dropModuleTarget &&
(descriptor.osName().isPresent() ||
descriptor.osArch().isPresent() ||
descriptor.osVersion().isPresent());
return addModulePackages || dropModuleTarget;
}
/**
* Returns the bytes for the module-info.class with ModulePackages
* if it contains at least one package
* attribute added and/or with ModuleTarget attribute dropped.
*/
byte[] getBytes() throws IOException {
bain.reset();
// add ModulePackages attribute if not exist
if (shouldRewrite()) {
ModuleInfoRewriter rewriter = new ModuleInfoRewriter(bain);
if (shouldAddModulePackages()) {
rewriter.addModulePackages(packages);
try (InputStream in = getInputStream()) {
if (shouldRewrite()) {
ModuleInfoRewriter rewriter = new ModuleInfoRewriter(in);
if (addModulePackages) {
rewriter.addModulePackages(packages);
}
if (dropModuleTarget) {
rewriter.dropModuleTarget();
}
// rewritten module descriptor
byte[] bytes = rewriter.getBytes();
try (ByteArrayInputStream bain = new ByteArrayInputStream(bytes)) {
this.descriptor = ModuleDescriptor.read(bain);
}
return bytes;
} else {
return in.readAllBytes();
}
if (shouldDropModuleTarget()) {
rewriter.dropModuleTarget();
}
// rewritten module descriptor
byte[] bytes = rewriter.getBytes();
try (ByteArrayInputStream bain = new ByteArrayInputStream(bytes)) {
this.descriptor = ModuleDescriptor.read(bain);
}
return bytes;
} else {
return bain.readAllBytes();
}
}
/*
* Returns the input stream of the module-info.class
*/
InputStream getInputStream() {
bain.reset();
return bain;
}
class ModuleInfoRewriter extends ByteArrayOutputStream {
final ModuleInfoExtender extender;
ModuleInfoRewriter(InputStream in) {

View File

@ -62,7 +62,7 @@ are different.
exclude-files.argument=<pattern-list> of files to exclude
exclude-files.description=\
Specify files to exclude. e.g.: **.java,glob:/java.base/native/client/**
Specify files to exclude. e.g.: **.java,glob:/java.base/lib/client/**
exclude-resources.argument=<pattern-list> resources to exclude

View File

@ -33,6 +33,7 @@
import java.lang.module.ModuleFinder;
import java.lang.module.ModuleReference;
import java.lang.reflect.Layer;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
@ -80,25 +81,33 @@ public class CheckPackageAccess {
}
void test() {
System.out.println("Testing module " + moduleName);
final boolean isModulePresent =
Layer.boot().findModule(moduleName).isPresent();
System.out.format("Testing module: %1$s. Module is%2$s present.\n",
moduleName, isModulePresent ? "" : " NOT");
// access to exported pkg should pass
testNonRestricted(exports);
if (isModulePresent) {
// access to opened pkg should pass
opens.ifPresent(Test::testNonRestricted);
// access to exported pkg should pass
testNonRestricted(exports);
// access to concealed pkg should fail
testRestricted(conceals);
// access to opened pkg should pass
opens.ifPresent(Test::testNonRestricted);
// access to qualified export pkg should fail
qualExports.ifPresent(Test::testRestricted);
// access to concealed pkg should fail
testRestricted(conceals);
// access to qualified open pkg should fail
qualOpens.ifPresent(Test::testRestricted);
// access to qualified export pkg should fail
qualExports.ifPresent(Test::testRestricted);
// access to qualified opened pkg that is also exported should pass
qualOpensAndExports.ifPresent(Test::testNonRestricted);
// access to qualified open pkg should fail
qualOpens.ifPresent(Test::testRestricted);
// access to qualified opened pkg that is also exported should pass
qualOpensAndExports.ifPresent(Test::testNonRestricted);
} else {
System.out.println("Skipping tests for module.");
}
}
private static void testRestricted(String pkg) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -26,6 +26,7 @@
* @bug 6479237
* @summary Basic test StackTraceElement with class loader names
* @library lib /lib/testlibrary
* @modules jdk.compiler
* @build m1/* WithClassLoaderName
* @run main/othervm m1/com.app.Main
* @run main/othervm WithClassLoaderName

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -30,7 +30,7 @@
* @library /lib/testlibrary/jsr292 /lib/testlibrary
* @modules java.base/java.lang.invoke:open
* java.base/java.lang.ref:open
* jdk.management
* java.management
* @build TestMethods
* @build LambdaFormTestCase
* @build LFCachingTestCase

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -30,6 +30,7 @@
* @library /lib/testlibrary/jsr292 /lib/testlibrary
* @modules java.base/java.lang.ref:open
* java.base/java.lang.invoke:open
* java.management
* @build TestMethods
* @build LambdaFormTestCase
* @build LFCachingTestCase

View File

@ -0,0 +1,85 @@
/*
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8174399
* @summary LambdaMetafactory should be able to handle inherited methods as 'implMethod'
*/
import java.lang.ReflectiveOperationException;
import java.lang.invoke.*;
public class InheritedMethodTest {
public static MethodType mt(Class<?> ret, Class<?>... params) { return MethodType.methodType(ret, params); }
public interface StringFactory {
String get();
}
public interface I {
String iString();
}
public interface J extends I {}
public static abstract class C implements I {}
public static class D extends C implements J {
public String toString() { return "a"; }
public String iString() { return "b"; }
}
private static final MethodHandles.Lookup lookup = MethodHandles.lookup();
public static void main(String... args) throws Throwable {
test(lookup.findVirtual(C.class, "toString", mt(String.class)), "a");
test(lookup.findVirtual(C.class, "iString", mt(String.class)), "b");
test(lookup.findVirtual(J.class, "toString", mt(String.class)), "a");
test(lookup.findVirtual(J.class, "iString", mt(String.class)), "b");
test(lookup.findVirtual(I.class, "toString", mt(String.class)), "a");
test(lookup.findVirtual(I.class, "iString", mt(String.class)), "b");
}
static void test(MethodHandle implMethod, String expected) throws Throwable {
testMetafactory(implMethod, expected);
testAltMetafactory(implMethod, expected);
}
static void testMetafactory(MethodHandle implMethod, String expected) throws Throwable {
CallSite cs = LambdaMetafactory.metafactory(lookup, "get", mt(StringFactory.class, D.class), mt(String.class),
implMethod, mt(String.class));
StringFactory factory = (StringFactory) cs.dynamicInvoker().invokeExact(new D());
String actual = factory.get();
if (!expected.equals(actual)) throw new AssertionError("Unexpected result: " + actual);
}
static void testAltMetafactory(MethodHandle implMethod, String expected) throws Throwable {
CallSite cs = LambdaMetafactory.altMetafactory(lookup, "get", mt(StringFactory.class, D.class), mt(String.class),
implMethod, mt(String.class), LambdaMetafactory.FLAG_SERIALIZABLE);
StringFactory factory = (StringFactory) cs.dynamicInvoker().invokeExact(new D());
String actual = factory.get();
if (!expected.equals(actual)) throw new AssertionError("Unexpected result: " + actual);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -26,6 +26,7 @@
* @bug 8151099
* @summary Verify platform MXBeans initialized properly with java.management
* module only. No other management provider
* @modules java.management
* @run main/othervm --limit-modules=java.management DefaultManagementProviderTest
*/
import java.lang.management.ManagementFactory;

View File

@ -57,6 +57,9 @@ import static java.util.stream.Collectors.toMap;
/*
* @test
* @bug 8062389
* @modules java.compiler
* jdk.compiler
* jdk.zipfs
* @summary Nearly exhaustive test of Class.getMethod() and Class.getMethods()
* @run main PublicMethodsTest
*/

View File

@ -94,6 +94,7 @@ public class BasicTest {
} catch (Throwable tt) {
System.err.println("tt caught");
tt.printStackTrace();
throw tt;
} finally {
httpServer.stop();
httpsServer.stop();
@ -223,7 +224,7 @@ public class BasicTest {
CompletableFuture[] responses = new CompletableFuture[LOOPS];
final Path source = TestUtil.getAFile(FILESIZE);
HttpRequest request = HttpRequest.newBuilder(uri)
.POST(fromFile(tempFile()))
.POST(fromFile(source))
.build();
for (int i = 0; i < LOOPS; i++) {
responses[i] = client.sendAsync(request, asFile(tempFile()))

View File

@ -392,9 +392,11 @@ public class Http2TestServerConnection {
//System.err.println ("Stream window size = " + winsize);
final InputStream bis;
if (endStreamReceived) {
if (endStreamReceived && queue.size() == 0) {
System.err.println("Server: got END_STREAM for stream " + streamid);
bis = NullInputStream.INSTANCE;
} else {
System.err.println("Server: creating input stream for stream " + streamid);
bis = new BodyInputStream(queue, streamid, this);
}
try (bis;

View File

@ -28,13 +28,43 @@
# @summary Tests that java.lang.AbstractMethodError is not thrown when
# serializing improper version of DocumentImpl class.
OS=`uname -s`
case "$OS" in
SunOS )
PS=":"
;;
Linux )
PS=":"
;;
Darwin )
PS=":"
;;
AIX )
PS=":"
;;
Windows*)
PS=";"
;;
CYGWIN*)
PS=";"
;;
* )
echo "Unrecognized system!"
exit 1;
;;
esac
mkdir -p exec/java.xml compile/java.xml
$COMPILEJAVA/bin/javac ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} \
-d compile/java.xml -Xmodule:java.xml $TESTSRC/Document.java $TESTSRC/Node.java || exit 1
-d compile/java.xml --patch-module java.xml=$TESTSRC/patch-src1 \
$TESTSRC/patch-src1/org/w3c/dom/Document.java \
$TESTSRC/patch-src1/org/w3c/dom/Node.java || exit 1
$COMPILEJAVA/bin/javac ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} \
-d exec/java.xml --patch-module java.xml=compile/java.xml -Xmodule:java.xml $TESTSRC/DocumentImpl.java || exit 2
-d exec/java.xml --patch-module java.xml=compile/java.xml${PS}$TESTSRC/patch-src2 \
$TESTSRC/patch-src2/com/sun/org/apache/xerces/internal/dom/DocumentImpl.java \
|| exit 2
$COMPILEJAVA/bin/javac ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} \
$TESTSRC/AbstractMethodErrorTest.java -d exec || exit 3

View File

@ -60,8 +60,8 @@ cd ${TESTSRC}
TEST_JAVABASE=${TESTCLASSES}/java.base
mkdir -p ${TEST_JAVABASE}
${COMPILEJAVA}/bin/javac ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} \
-Xmodule:java.base \
-d ${TEST_JAVABASE} Bug4170614Test.java
--patch-module java.base=patch-src \
-d ${TEST_JAVABASE} patch-src/java/text/Bug4170614Test.java
${TESTJAVA}/bin/java ${TESTVMOPTS} --patch-module java.base=${TEST_JAVABASE} java.text.Bug4170614Test

View File

@ -268,7 +268,7 @@ public class Basic {
actual = lines(outbytes);
expected = Set.of(
"hi",
"module hi (module-info.class)",
"requires mandated java.base",
"contains p",
"contains p.internal"
@ -304,7 +304,7 @@ public class Basic {
actual = lines(outbytes);
expected = Set.of(
"hi",
"module hi (module-info.class)",
"requires mandated java.base",
"contains p",
"contains p.internal",
@ -396,18 +396,18 @@ public class Basic {
Paths.get("test7-v10", "module-info.class"));
int rc = jar("--create --file mmr.jar --main-class=p.Main -C test7 . --release 9 -C test7-v9 . --release 10 -C test7-v10 .");
System.out.println("-----------------------");
System.out.println( new String(errbytes.toByteArray()));
Assert.assertEquals(rc, 0);
jar("-tf mmr.jar");
System.out.println("-----------------------");
System.out.println( new String(outbytes.toByteArray()));
jar("-d --file=mmr.jar");
System.out.println("-----------------------");
System.out.println( new String(outbytes.toByteArray()));
Assert.assertEquals(lines(outbytes),
Set.of(
"module m1 (META-INF/versions/9/module-info.class)",
"module m1 (META-INF/versions/10/module-info.class)",
"requires mandated java.base",
"exports p",
"main-class p.Main"));
Optional<String> exp = Optional.of("p.Main");
try (ZipFile zf = new ZipFile("mmr.jar")) {

View File

@ -46,7 +46,7 @@ import static java.lang.System.out;
/*
* @test
* @bug 8167328 8171830
* @bug 8167328 8171830 8165640
* @library /lib/testlibrary
* @modules jdk.compiler
* jdk.jartool
@ -241,11 +241,6 @@ public class Basic {
java(mp, FOO.moduleName + "/" + FOO.mainClass)
.assertSuccess()
.resultChecker(r -> {
System.out.println("===================================");
System.out.println(r.output);
System.out.println("===================================");
})
.resultChecker(r -> assertModuleData(r, FOO));
try (InputStream fis = Files.newInputStream(modularJar);
JarInputStream jis = new JarInputStream(fis)) {
@ -484,7 +479,7 @@ public class Basic {
.resultChecker(r -> {
// Expect similar output: "bar, requires mandated foo, ...
// conceals jdk.test.foo, conceals jdk.test.foo.internal"
Pattern p = Pattern.compile("\\s+bar\\s+requires\\s++foo");
Pattern p = Pattern.compile("module bar \\(module-info.class\\)\\s+requires\\s++foo");
assertTrue(p.matcher(r.output).find(),
"Expecting to find \"bar, requires foo,...\"",
"in output, but did not: [" + r.output + "]");
@ -739,6 +734,53 @@ public class Basic {
.assertSuccess();
}
@Test
public void servicesCreateWithoutFailureNonRootMRMJAR() throws IOException {
// without a root module-info.class
Path mp = Paths.get("servicesCreateWithoutFailureNonRootMRMJAR");
createTestDir(mp);
Path modClasses = MODULE_CLASSES.resolve("baz");
Path mrjarDir = MRJAR_DIR.resolve("baz");
Path modularJar = mp.resolve("baz.jar");
jar("--create",
"--file=" + modularJar.toString(),
"--main-class=" + "jdk.test.baz.Baz",
"-m", mrjarDir.resolve("META-INF/MANIFEST.MF").toRealPath().toString(),
"-C", mrjarDir.toString(), "META-INF/versions/9/module-info.class",
"-C", modClasses.toString(), "jdk/test/baz/BazService.class",
"-C", modClasses.toString(), "jdk/test/baz/Baz.class",
"-C", modClasses.toString(), "jdk/test/baz/internal/BazServiceImpl.class")
.assertSuccess();
for (String option : new String[] {"--print-module-descriptor", "-d" }) {
jar(option,
"--file=" + modularJar.toString())
.assertSuccess()
.resultChecker(r ->
assertTrue(r.output.contains("main-class jdk.test.baz.Baz"),
"Expected to find ", "main-class jdk.test.baz.Baz",
" in [", r.output, "]"));
jarWithStdin(modularJar.toFile(), option)
.assertSuccess()
.resultChecker(r ->
assertTrue(r.output.contains("main-class jdk.test.baz.Baz"),
"Expected to find ", "main-class jdk.test.baz.Baz",
" in [", r.output, "]"));
}
// run module maain class
java(mp, "baz/jdk.test.baz.Baz")
.assertSuccess()
.resultChecker(r ->
assertTrue(r.output.contains("mainClass:jdk.test.baz.Baz"),
"Expected to find ", "mainClass:jdk.test.baz.Baz",
" in [", r.output, "]"));
}
@Test
public void exportCreateWithMissingPkg() throws IOException {

View File

@ -0,0 +1,34 @@
/*
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.test.baz;
import java.lang.module.ModuleDescriptor;
public class Baz {
public static void main(String[] args) {
ModuleDescriptor md = Baz.class.getModule().getDescriptor();
System.out.println("nameAndVersion:" + md.toNameAndVersion());
md.mainClass().ifPresent(mc -> System.out.println("mainClass:" + mc));
}
}

View File

@ -250,7 +250,7 @@ public class JLinkNegativeTest {
String moduleName = "hacked4";
Path jmod = helper.generateDefaultJModule(moduleName).assertSuccess();
JImageGenerator.addFiles(jmod,
new InMemoryFile("/native", new byte[0]),
new InMemoryFile("/lib", new byte[0]),
new InMemoryFile("/conf", new byte[0]),
new InMemoryFile("/bin", new byte[0]));
try {

View File

@ -155,10 +155,10 @@ public class ExcludeVMPluginTest {
String[] winput = new String[input.length];
String[] woutput = new String[expectedOutput.length];
for (int i = 0; i < input.length; i++) {
winput[i] = "/java.base/native" + arch + input[i];
winput[i] = "/java.base/lib" + arch + input[i];
}
for (int i = 0; i < expectedOutput.length; i++) {
woutput[i] = "/java.base/native" + arch + expectedOutput[i];
woutput[i] = "/java.base/lib" + arch + expectedOutput[i];
}
doCheckVM(vm, winput, jvmcfg, woutput, expectdJvmCfg);
}
@ -169,7 +169,7 @@ public class ExcludeVMPluginTest {
byte[] jvmcfgContent = jvmcfg.getBytes();
ResourcePoolManager poolMgr = new ResourcePoolManager();
poolMgr.add(
ResourcePoolEntry.create("/java.base/native/jvm.cfg",
ResourcePoolEntry.create("/java.base/lib/jvm.cfg",
ResourcePoolEntry.Type.NATIVE_LIB, jvmcfgContent));
// java.base/module-info.class is used by exclude vm plugin
@ -192,7 +192,7 @@ public class ExcludeVMPluginTest {
p.configure(config);
ResourcePool out = p.transform(poolMgr.resourcePool(), outMgr.resourcePoolBuilder());
String newContent = new String(out.findEntry("/java.base/native/jvm.cfg").get().contentBytes());
String newContent = new String(out.findEntry("/java.base/lib/jvm.cfg").get().contentBytes());
if (!expectdJvmCfg.equals(newContent)) {
throw new Exception("Got content " + newContent + " expected " + expectdJvmCfg);
@ -209,7 +209,7 @@ public class ExcludeVMPluginTest {
}
out.entries().forEach(md -> {
if (md.path().equals("/java.base/native/jvm.cfg") ||
if (md.path().equals("/java.base/lib/jvm.cfg") ||
md.path().equals("/java.base/module-info.class")) {
return;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -45,7 +45,7 @@ import static org.testng.Assert.*;
/**
* @test
* @bug 8142968 8173381
* @bug 8142968 8173381 8174740
* @library /lib/testlibrary
* @modules jdk.compiler jdk.jlink
* @build UserModuleTest CompilerUtils jdk.testlibrary.FileUtils jdk.testlibrary.ProcessTools

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -21,5 +21,9 @@
* questions.
*/
/*
* m1 has an exported package and also internal package
*/
module m1 {
exports p1;
}

View File

@ -66,7 +66,7 @@ public class JmodTest {
static final String CLASSES_PREFIX = "classes/";
static final String CMDS_PREFIX = "bin/";
static final String LIBS_PREFIX = "native/";
static final String LIBS_PREFIX = "lib/";
static final String CONFIGS_PREFIX = "conf/";
@BeforeTest

View File

@ -87,11 +87,16 @@ public class ToolsOpts extends TestHelper {
contents.add(" }\n");
contents.add(" }\n");
contents.add("}\n");
createFile(new File(mainJava), contents);
String mainJavaPath = "patch-src/com/sun/tools/javac/" + mainJava;
File mainJavaFile = new File(mainJavaPath.replace('/', File.separatorChar));
mainJavaFile.getParentFile().mkdirs();
createFile(mainJavaFile, contents);
// compile Main.java into directory to override classes in jdk.compiler
new File("jdk.compiler").mkdir();
compile("-Xmodule:jdk.compiler", "-d", "jdk.compiler", mainJava);
compile("--patch-module", "jdk.compiler=patch-src",
"-d", "jdk.compiler",
mainJavaFile.toString());
}
static void pass(String msg) {

View File

@ -105,22 +105,24 @@ public class PatchTest {
MODS_DIR.resolve("test"));
assertTrue(compiled, "classes did not compile");
// javac -Xmodule:$MODULE -d patches1/$MODULE patches1/$MODULE/**
// javac --patch-module $MODULE=patches1/$MODULE -d patches1/$MODULE patches1/$MODULE/**
// jar cf patches/$MODULE-1.jar -C patches1/$MODULE .
for (Path src : Files.newDirectoryStream(SRC1_DIR)) {
Path output = PATCHES1_DIR.resolve(src.getFileName());
String mn = src.getFileName().toString();
compiled = CompilerUtils.compile(src, output, "-Xmodule:" + mn);
compiled = CompilerUtils.compile(src, output,
"--patch-module", mn + "=" + src.toString());
assertTrue(compiled, "classes did not compile");
JarUtils.createJarFile(PATCHES_DIR.resolve(mn + "-1.jar"), output);
}
// javac -Xmodule:$MODULE -d patches2/$MODULE patches2/$MODULE/**
// javac --patch-module $MODULE=patches2/$MODULE -d patches2/$MODULE patches2/$MODULE/**
// jar cf patches/$MODULE-2.jar -C patches2/$MODULE .
for (Path src : Files.newDirectoryStream(SRC2_DIR)) {
Path output = PATCHES2_DIR.resolve(src.getFileName());
String mn = src.getFileName().toString();
compiled = CompilerUtils.compile(src, output, "-Xmodule:" + mn);
compiled = CompilerUtils.compile(src, output,
"--patch-module", mn + "=" + src.toString());
assertTrue(compiled, "classes did not compile");
JarUtils.createJarFile(PATCHES_DIR.resolve(mn + "-2.jar"), output);
}

View File

@ -93,20 +93,22 @@ public class PatchTestWarningError {
MODS_DIR.resolve("test"));
assertTrue(compiled, "classes did not compile");
// javac -Xmodule:$MODULE -d patches1/$MODULE patches1/$MODULE/**
// javac --patch-module $MODULE=patches1/$MODULE -d patches1/$MODULE patches1/$MODULE/**
Path src = SRC1_DIR.resolve("java.base");
Path output = PATCHES1_DIR.resolve(src.getFileName());
Files.createDirectories(output);
String mn = src.getFileName().toString();
compiled = CompilerUtils.compile(src, output, "-Xmodule:" + mn);
compiled = CompilerUtils.compile(src, output,
"--patch-module", mn + "=" + src.toString());
assertTrue(compiled, "classes did not compile");
// javac -Xmodule:$MODULE -d patches2/$MODULE patches2/$MODULE/**
// javac --patch-module $MODULE=patches2/$MODULE -d patches2/$MODULE patches2/$MODULE/**
src = SRC2_DIR.resolve("java.base");
output = PATCHES2_DIR.resolve(src.getFileName());
Files.createDirectories(output);
mn = src.getFileName().toString();
compiled = CompilerUtils.compile(src, output, "-Xmodule:" + mn);
compiled = CompilerUtils.compile(src, output,
"--patch-module", mn + "=" + src.toString());
assertTrue(compiled, "classes did not compile");
}

View File

@ -73,9 +73,10 @@ public class PatchSystemModules {
}
// compile patched source
String patchDir = PATCH_SRC_DIR.resolve(JAVA_BASE).toString();
assertTrue(CompilerUtils.compile(PATCH_SRC_DIR.resolve(JAVA_BASE),
PATCH_DIR.resolve(JAVA_BASE),
"-Xmodule:java.base"));
"--patch-module", "java.base=" + patchDir));
assertTrue(CompilerUtils.compile(PATCH_SRC_DIR.resolve("m2"),
PATCH_DIR.resolve("m2")));