Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes #5475 Scan for updated ASM version #5479

Merged
merged 3 commits into from Oct 20, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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