Skip to content

Commit

Permalink
Merge pull request #5479 from eclipse/jetty-9.4.x-5475-ScanForAsmVersion
Browse files Browse the repository at this point in the history
Fixes #5475 Scan for updated ASM version
  • Loading branch information
joakime committed Oct 20, 2020
2 parents 936cd46 + 7155066 commit 4ecaf30
Showing 1 changed file with 34 additions and 63 deletions.
Expand Up @@ -30,12 +30,12 @@
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import org.eclipse.jetty.util.JavaVersion;
import org.eclipse.jetty.util.Loader;
import org.eclipse.jetty.util.ManifestUtils;
import org.eclipse.jetty.util.MultiException;
import org.eclipse.jetty.util.MultiReleaseJarFile;
import org.eclipse.jetty.util.StringUtil;
Expand Down Expand Up @@ -71,80 +71,51 @@
public class AnnotationParser
{
private static final Logger LOG = Log.getLogger(AnnotationParser.class);
private static final int ASM_OPCODE_VERSION = Opcodes.ASM9; //compatibility of api
private static final String ASM_OPCODE_VERSION_STR = "ASM9";
private static final int ASM_VERSION = asmVersion();

/**
* Map of classnames scanned and the first location from which scan occurred
*/
protected Map<String, Resource> _parsedClassNames = new ConcurrentHashMap<>();
private final int _javaPlatform;
private int _asmVersion;
private final int _asmVersion;

/**
* Determine the runtime version of asm.
*
* @return the org.objectweb.asm.Opcode matching the runtime version of asm.
* @return the {@link org.objectweb.asm.Opcodes} ASM value matching the runtime version of asm.
*/
public static int asmVersion()
private static int asmVersion()
{
int asmVersion = ASM_OPCODE_VERSION;
String version = ManifestUtils.getVersion(Opcodes.class).orElse(null);
if (version == null)
{
LOG.warn("Unknown ASM version, assuming {}", ASM_OPCODE_VERSION_STR);
// Find the highest available ASM version on the runtime/classpath, because
// if we run with a lower than available ASM version, against a class with
// new language features we'll get an UnsupportedOperationException, even if
// the ASM version supports the new language features.
// Also, if we run with a higher than available ASM version, we'll get
// an IllegalArgumentException from org.objectweb.asm.ClassVisitor.
// So must find exactly the maximum ASM api version available.

Optional<Integer> asmVersion = Arrays.stream(Opcodes.class.getFields()).sequential()
.filter((f) -> f.getName().matches("ASM[0-9]+"))
.map((f) -> f.getName().substring(3))
.map(Integer::parseInt)
.max(Integer::compareTo);

if (!asmVersion.isPresent())
throw new IllegalStateException("Invalid " + Opcodes.class.getName());

int asmFieldId = asmVersion.get();
try
{
String fieldName = "ASM" + asmFieldId;
if (LOG.isDebugEnabled())
LOG.debug("Using ASM API from {}.{}", Opcodes.class.getName(), fieldName);
return (int)Opcodes.class.getField(fieldName).get(null);
}
else
catch (Throwable e)
{
int dot = version.indexOf('.');
version = version.substring(0, (dot < 0 ? version.length() : dot)).trim();
try
{
int v = Integer.parseInt(version);
switch (v)
{
case 4:
{
asmVersion = Opcodes.ASM4;
break;
}
case 5:
{
asmVersion = Opcodes.ASM5;
break;
}
case 6:
{
asmVersion = Opcodes.ASM6;
break;
}
case 7:
{
asmVersion = Opcodes.ASM7;
break;
}
case 8:
{
asmVersion = Opcodes.ASM8;
break;
}
case 9:
{
asmVersion = Opcodes.ASM9;
break;
}
default:
{
LOG.warn("Unrecognized ASM version, assuming {}", ASM_OPCODE_VERSION_STR);
}
}
}
catch (NumberFormatException e)
{
LOG.warn("Unable to parse ASM version, assuming {}", ASM_OPCODE_VERSION_STR);
}
throw new IllegalStateException(e);
}
return asmVersion;
}

/**
Expand Down Expand Up @@ -490,7 +461,7 @@ public AnnotationVisitor visitAnnotation(String desc, boolean visible)
*/
public class MyClassVisitor extends ClassVisitor
{
int _asmVersion;
final int _asmVersion;
final Resource _containingResource;
final Set<? extends Handler> _handlers;
ClassInfo _ci;
Expand Down Expand Up @@ -569,7 +540,7 @@ public AnnotationParser()
*/
public AnnotationParser(int javaPlatform)
{
_asmVersion = asmVersion();
_asmVersion = ASM_VERSION;
if (javaPlatform == 0)
javaPlatform = JavaVersion.VERSION.getPlatform();
_javaPlatform = javaPlatform;
Expand All @@ -581,7 +552,7 @@ public AnnotationParser(int javaPlatform, int asmVersion)
javaPlatform = JavaVersion.VERSION.getPlatform();
_javaPlatform = javaPlatform;
if (asmVersion == 0)
asmVersion = ASM_OPCODE_VERSION;
asmVersion = ASM_VERSION;
_asmVersion = asmVersion;
}

Expand Down

0 comments on commit 4ecaf30

Please sign in to comment.