Skip to content

Commit

Permalink
Linkage Checker to verify method references to JRE classes (#1607)
Browse files Browse the repository at this point in the history
* Validate system class in target

* GraalVM references in exclusion rule

* Applied review

* Removing irrelevant comment
  • Loading branch information
suztomo authored Aug 26, 2020
1 parent fdf2ddb commit 354bfee
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,7 @@ JavaClass loadJavaClass(String className) throws ClassNotFoundException {
/** Returns true if {@code className} is available in the system class loader. */
boolean isSystemClass(String className) {
try {
if (className.startsWith("[")) {
// Array class
if (isArrayClass(className)) {
return true;
}
extensionClassLoader.loadClass(className);
Expand All @@ -137,6 +136,11 @@ boolean isSystemClass(String className) {
}
}

/** Returns true if {@code className} is a binary name for array types. */
static boolean isArrayClass(String className) {
return className.startsWith("[");
}

/**
* Returns a map from classes to the symbol references they contain.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -239,8 +239,7 @@ Optional<LinkageProblem> findLinkageProblem(
String targetClassName = symbol.getClassBinaryName();
String methodName = symbol.getName();

// Skip references to Java runtime class. For example, java.lang.String.
if (classDumper.isSystemClass(targetClassName)) {
if (ClassDumper.isArrayClass(targetClassName)) {
return Optional.empty();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,62 @@
<Package name="org.graalvm" />
</Source>
</LinkageError>

<LinkageError>
<Target>
<Class name="java.lang.invoke.MethodHandle" />
</Target>
<Source>
<Package name="com.oracle.svm" />
</Source>
<Reason>
GraalVM-related libraries depend on Java Compiler Interface (JVMCI) that
only exists in special JDK. These missing classes are false positives, because
the code is only invoked when running in a GraalVM.
https://github.com/GoogleCloudPlatform/cloud-opensource-java/issues/929
</Reason>
</LinkageError>
<LinkageError>
<Target>
<Class name="java.lang.invoke.MethodHandle" />
</Target>
<Source>
<Package name="com.oracle.graal" />
</Source>
<Reason>
GraalVM-related libraries depend on Java Compiler Interface (JVMCI) that
only exists in special JDK. These missing classes are false positives, because
the code is only invoked when running in a GraalVM.
https://github.com/GoogleCloudPlatform/cloud-opensource-java/issues/929
</Reason>
</LinkageError>
<LinkageError>
<Target>
<Class name="java.lang.invoke.MethodHandle" />
</Target>
<Source>
<Package name="org.graalvm" />
</Source>
<Reason>
GraalVM-related libraries depend on Java Compiler Interface (JVMCI) that
only exists in special JDK. These missing classes are false positives, because
the code is only invoked when running in a GraalVM.
https://github.com/GoogleCloudPlatform/cloud-opensource-java/issues/929
</Reason>
</LinkageError>
<LinkageError>
<Target>
<Class name="java.lang.invoke.MethodHandle" />
</Target>
<Source>
<Package name="com.oracle.truffle" />
</Source>
<Reason>
GraalVM-related libraries depend on Java Compiler Interface (JVMCI) that
only exists in special JDK. These missing classes are false positives, because
the code is only invoked when running in a GraalVM.
https://github.com/GoogleCloudPlatform/cloud-opensource-java/issues/929
</Reason>
</LinkageError>
<LinkageError>
<Target>
<Class name="org.mockito.internal.creation.bytebuddy.MockMethodDispatcher" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1120,4 +1120,24 @@ public void testFindLinkageProblems_grpcAndGuava() throws IOException {
"has class binary name"))
.contains("io.grpc.internal.DnsNameResolver");
}

@Test
public void testFindLinkageProblems_referenceToJava11Method() throws IOException {
// protobuf-java 3.12.4 references a Java 11 method that does not exist in Java 8
// https://github.com/protocolbuffers/protobuf/issues/7827
ImmutableList<ClassPathEntry> jars =
TestHelper.resolve("com.google.protobuf:protobuf-java:3.12.4");

LinkageChecker linkageChecker = LinkageChecker.create(jars);
ImmutableSet<LinkageProblem> linkageProblems = linkageChecker.findLinkageProblems();

MethodSymbol methodSymbol =
new MethodSymbol("java.nio.CharBuffer", "flip", "()Ljava/nio/CharBuffer;", false);

SymbolNotFoundProblem expectedProblem =
new SymbolNotFoundProblem(
new ClassFile(jars.get(0), "com.google.protobuf.TextFormat"), null, methodSymbol);

Truth.assertThat(linkageProblems).contains(expectedProblem);
}
}

0 comments on commit 354bfee

Please sign in to comment.