Issue #1797 - Safety checks for Java 9 and Multi-Release JARs during bytecode scanning
Signed-off-by: Joakim Erdfelt <joakim.erdfelt@gmail.com>
This commit is contained in:
parent
52baec434b
commit
1295dc372d
|
@ -68,10 +68,30 @@ public class AnnotationParser
|
|||
{
|
||||
private static final Logger LOG = Log.getLogger(AnnotationParser.class);
|
||||
|
||||
private static final int JVM_MAJOR_VER;
|
||||
|
||||
protected Set<String> _parsedClassNames = new ConcurrentHashSet<String>();
|
||||
|
||||
protected static int ASM_OPCODE_VERSION = Opcodes.ASM5; //compatibility of api
|
||||
|
||||
|
||||
static
|
||||
{
|
||||
// Determine JVM spec version
|
||||
// Using guidance from http://openjdk.java.net/jeps/223
|
||||
String jvmSpecVer = System.getProperty("java.vm.specification.version");
|
||||
|
||||
if (jvmSpecVer.indexOf('.') >= 0)
|
||||
{
|
||||
// Old spec version (Java 1.8 and older)
|
||||
String parts[] = jvmSpecVer.split("\\.");
|
||||
JVM_MAJOR_VER = Integer.parseInt(parts[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Newer spec version (Java 9+)
|
||||
JVM_MAJOR_VER = Integer.parseInt(jvmSpecVer);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert internal name to simple name
|
||||
|
@ -1028,10 +1048,61 @@ public class AnnotationParser
|
|||
if (path == null || path.length()==0)
|
||||
return false;
|
||||
|
||||
//skip any classfiles that are in a hidden directory
|
||||
if (path.startsWith("META-INF/versions/"))
|
||||
{
|
||||
// Handle JEP 238 - Multi-Release Jars
|
||||
if (JVM_MAJOR_VER < 9)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
{
|
||||
LOG.debug("JEP-238 Multi-Release JAR not supported on Java " +
|
||||
System.getProperty("java.version") + ": " + path);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Safety check for ASM bytecode support level.
|
||||
// When ASM 6.0 is integrated, the below will start to work.
|
||||
if (ASM_OPCODE_VERSION <= Opcodes.ASM5)
|
||||
{
|
||||
// Cannot scan Java 9 classes with ASM version 5
|
||||
if (LOG.isDebugEnabled())
|
||||
{
|
||||
LOG.debug("Unable to scan newer Java bytecode (Java 9?) with ASM 5 (skipping): " + path);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int idxStart = "META-INF/versions/".length();
|
||||
int idxEnd = path.indexOf('/', idxStart + 1);
|
||||
try
|
||||
{
|
||||
int pathVersion = Integer.parseInt(path.substring(idxStart, idxEnd));
|
||||
if (pathVersion < JVM_MAJOR_VER)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
{
|
||||
LOG.debug("JEP-238 Multi-Release JAR version " + pathVersion +
|
||||
" not supported on Java " + System.getProperty("java.version") +
|
||||
": " + path);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
{
|
||||
LOG.debug("Not a valid JEP-238 Multi-Release path: " + path);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// skip any classfiles that are in a hidden directory
|
||||
if (path.startsWith(".") || path.contains("/."))
|
||||
{
|
||||
if (LOG.isDebugEnabled()) LOG.debug("Contains hidden dirs: {}"+path);
|
||||
if (LOG.isDebugEnabled()) LOG.debug("Contains hidden dirs: " + path);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -175,6 +175,26 @@ public class TestAnnotationParser
|
|||
// only the valid classes inside bad-classes.jar should be parsed. If any invalid classes are parsed and exception would be thrown here
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testModuleInfoClassInJar() throws Exception
|
||||
{
|
||||
File badClassesJar = MavenTestingUtils.getTestResourceFile("jdk9/slf4j-api-1.8.0-alpha2.jar");
|
||||
AnnotationParser parser = new AnnotationParser();
|
||||
Set<Handler> emptySet = Collections.emptySet();
|
||||
parser.parse(emptySet, badClassesJar.toURI());
|
||||
// Should throw no exceptions, and happily skip the module-info.class files
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJep238MultiReleaseInJar() throws Exception
|
||||
{
|
||||
File badClassesJar = MavenTestingUtils.getTestResourceFile("jdk9/log4j-api-2.9.0.jar");
|
||||
AnnotationParser parser = new AnnotationParser();
|
||||
Set<Handler> emptySet = Collections.emptySet();
|
||||
parser.parse(emptySet, badClassesJar.toURI());
|
||||
// Should throw no exceptions, and skip the META-INF/versions/9/* files
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBasedirExclusion() throws Exception
|
||||
{
|
||||
|
|
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue