Skip to content

Commit f099ac0

Browse files
authored
Merge pull request #148 from dmitri-gb/master
Make Java agent work with JDK 9+
2 parents cdb21e9 + 2b181dc commit f099ac0

14 files changed

+166
-69
lines changed

Diff for: .idea/libraries/Maven__org_ow2_asm_asm_7_0.xml

+13
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: .idea/libraries/Maven__org_ow2_asm_asm_debug_all_5_2.xml

-13
This file was deleted.

Diff for: .idea/libraries/Maven__org_ow2_asm_asm_tree_7_0.xml

+13
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: end-to-end-tests/end-to-end-tests.iml

+2-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
<orderEntry type="library" name="Maven: com.google.guava:guava:11.0.2" level="project" />
1515
<orderEntry type="library" name="Maven: com.google.code.findbugs:jsr305:1.3.9" level="project" />
1616
<orderEntry type="library" scope="TEST" name="Maven: commons-lang:commons-lang:2.6" level="project" />
17-
<orderEntry type="library" scope="TEST" name="Maven: org.ow2.asm:asm-debug-all:5.2" level="project" />
17+
<orderEntry type="library" scope="TEST" name="Maven: org.ow2.asm:asm:7.0" level="project" />
18+
<orderEntry type="library" scope="TEST" name="Maven: org.ow2.asm:asm-tree:7.0" level="project" />
1819
<orderEntry type="library" scope="TEST" name="Maven: org.apache.bcel:bcel:5.2" level="project" />
1920
<orderEntry type="library" scope="TEST" name="Maven: jakarta-regexp:jakarta-regexp:1.4" level="project" />
2021
<orderEntry type="module-library">

Diff for: end-to-end-tests/pom.xml

+7-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,13 @@
3030

3131
<dependency>
3232
<groupId>org.ow2.asm</groupId>
33-
<artifactId>asm-debug-all</artifactId>
33+
<artifactId>asm</artifactId>
34+
<scope>test</scope>
35+
</dependency>
36+
37+
<dependency>
38+
<groupId>org.ow2.asm</groupId>
39+
<artifactId>asm-tree</artifactId>
3440
<scope>test</scope>
3541
</dependency>
3642

Diff for: parent/pom.xml

+9-3
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,14 @@
8585

8686
<dependency>
8787
<groupId>org.ow2.asm</groupId>
88-
<artifactId>asm-debug-all</artifactId>
89-
<version>5.2</version>
88+
<artifactId>asm</artifactId>
89+
<version>7.0</version>
90+
</dependency>
91+
92+
<dependency>
93+
<groupId>org.ow2.asm</groupId>
94+
<artifactId>asm-tree</artifactId>
95+
<version>7.0</version>
9096
</dependency>
9197

9298
<dependency>
@@ -312,7 +318,7 @@
312318

313319
<plugin>
314320
<artifactId>maven-plugin-plugin</artifactId>
315-
<version>3.4</version>
321+
<version>3.6.0</version>
316322
</plugin>
317323

318324
<plugin>

Diff for: retrolambda-maven-plugin/retrolambda-maven-plugin.iml

+2-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
<orderEntry type="inheritedJdk" />
1414
<orderEntry type="sourceFolder" forTests="false" />
1515
<orderEntry type="module" module-name="retrolambda" />
16-
<orderEntry type="library" name="Maven: org.ow2.asm:asm-debug-all:5.2" level="project" />
16+
<orderEntry type="library" name="Maven: org.ow2.asm:asm:7.0" level="project" />
17+
<orderEntry type="library" name="Maven: org.ow2.asm:asm-tree:7.0" level="project" />
1718
<orderEntry type="library" name="Maven: com.esotericsoftware:minlog:1.3" level="project" />
1819
<orderEntry type="module" module-name="retrolambda-api" />
1920
<orderEntry type="library" name="Maven: org.apache.maven:maven-plugin-api:3.0" level="project" />

Diff for: retrolambda/pom.xml

+7-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,12 @@
2323

2424
<dependency>
2525
<groupId>org.ow2.asm</groupId>
26-
<artifactId>asm-debug-all</artifactId>
26+
<artifactId>asm</artifactId>
27+
</dependency>
28+
29+
<dependency>
30+
<groupId>org.ow2.asm</groupId>
31+
<artifactId>asm-tree</artifactId>
2732
</dependency>
2833

2934
<dependency>
@@ -50,6 +55,7 @@
5055
<mainClass>net.orfjackal.retrolambda.Main</mainClass>
5156
</manifest>
5257
<manifestEntries>
58+
<Can-Retransform-Classes>true</Can-Retransform-Classes>
5359
<Premain-Class>net.orfjackal.retrolambda.PreMain</Premain-Class>
5460
</manifestEntries>
5561
</archive>

Diff for: retrolambda/retrolambda.iml

+2-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
<orderEntry type="inheritedJdk" />
1212
<orderEntry type="sourceFolder" forTests="false" />
1313
<orderEntry type="module" module-name="retrolambda-api" />
14-
<orderEntry type="library" name="Maven: org.ow2.asm:asm-debug-all:5.2" level="project" />
14+
<orderEntry type="library" name="Maven: org.ow2.asm:asm:7.0" level="project" />
15+
<orderEntry type="library" name="Maven: org.ow2.asm:asm-tree:7.0" level="project" />
1516
<orderEntry type="library" name="Maven: com.google.guava:guava:18.0" level="project" />
1617
<orderEntry type="library" name="Maven: com.esotericsoftware:minlog:1.3" level="project" />
1718
<orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.12" level="project" />
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Copyright © 2013-2018 Esko Luontola and other Retrolambda contributors
2+
// This software is released under the Apache License 2.0.
3+
// The license text is at http://www.apache.org/licenses/LICENSE-2.0
4+
5+
package net.orfjackal.retrolambda;
6+
7+
import net.orfjackal.retrolambda.ext.ow2asm.EnhancedClassReader;
8+
import net.orfjackal.retrolambda.lambdas.LambdaClassSaver;
9+
import org.objectweb.asm.ClassReader;
10+
11+
public class Agent {
12+
13+
private static boolean enabled = false;
14+
private static LambdaClassSaver lambdaClassSaver;
15+
private static boolean isJavacHacksEnabled;
16+
17+
public static void enable() {
18+
enabled = true;
19+
}
20+
21+
public static boolean isEnabled() {
22+
return enabled;
23+
}
24+
25+
public static void setLambdaClassSaver(LambdaClassSaver lambdaClassSaver, boolean isJavacHacksEnabled) {
26+
Agent.lambdaClassSaver = lambdaClassSaver;
27+
Agent.isJavacHacksEnabled = isJavacHacksEnabled;
28+
}
29+
30+
public static void saveLambda(byte[] bytes) {
31+
if (lambdaClassSaver != null) {
32+
ClassReader reader = EnhancedClassReader.create(bytes, isJavacHacksEnabled);
33+
lambdaClassSaver.saveIfLambda(reader.getClassName(), bytes);
34+
}
35+
}
36+
}

Diff for: retrolambda/src/main/java/net/orfjackal/retrolambda/PreMain.java

+11-11
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,23 @@
66

77
import net.orfjackal.retrolambda.lambdas.*;
88

9+
import java.io.File;
910
import java.lang.instrument.Instrumentation;
11+
import java.net.URISyntaxException;
12+
import java.util.jar.JarFile;
1013

1114
public class PreMain {
1215

13-
private static final LambdaClassSaverAgent agent = new LambdaClassSaverAgent();
14-
private static boolean agentLoaded = false;
16+
public static void premain(String agentArgs, Instrumentation inst) throws Exception {
17+
// Append the agent JAR to the bootstrap search path so that the instrumented InnerClassLambdaMetaFactory
18+
// could refer to Agent.
19+
inst.appendToBootstrapClassLoaderSearch(new JarFile(getAgentJarFile()));
1520

16-
public static void premain(String agentArgs, Instrumentation inst) {
17-
inst.addTransformer(agent);
18-
agentLoaded = true;
21+
inst.addTransformer(new InnerClassLambdaMetafactoryTransformer(), true);
22+
inst.retransformClasses(Class.forName("java.lang.invoke.InnerClassLambdaMetafactory"));
1923
}
2024

21-
public static boolean isAgentLoaded() {
22-
return agentLoaded;
23-
}
24-
25-
public static void setLambdaClassSaver(LambdaClassSaver lambdaClassSaver, boolean isJavacHacksEnabled) {
26-
agent.setLambdaClassSaver(lambdaClassSaver, isJavacHacksEnabled);
25+
private static File getAgentJarFile() throws URISyntaxException {
26+
return new File(PreMain.class.getProtectionDomain().getCodeSource().getLocation().toURI());
2727
}
2828
}

Diff for: retrolambda/src/main/java/net/orfjackal/retrolambda/Retrolambda.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public static void run(Config config) throws Throwable {
4545
Log.info("Classpath: " + classpath);
4646
Log.info("Included files: " + (includedFiles != null ? includedFiles.size() : "all"));
4747
Log.info("JVM version: " + System.getProperty("java.version"));
48-
Log.info("Agent enabled: " + PreMain.isAgentLoaded());
48+
Log.info("Agent enabled: " + Agent.isEnabled());
4949
Log.info("javac hacks: " + isJavacHacksEnabled);
5050

5151
if (!Files.isDirectory(inputDir)) {
@@ -61,8 +61,8 @@ public static void run(Config config) throws Throwable {
6161
LambdaClassSaver lambdaClassSaver = new LambdaClassSaver(outputDirectory, transformers, isJavacHacksEnabled);
6262

6363
try (LambdaClassDumper dumper = new LambdaClassDumper(lambdaClassSaver)) {
64-
if (PreMain.isAgentLoaded()) {
65-
PreMain.setLambdaClassSaver(lambdaClassSaver, isJavacHacksEnabled);
64+
if (Agent.isEnabled()) {
65+
Agent.setLambdaClassSaver(lambdaClassSaver, isJavacHacksEnabled);
6666
} else {
6767
dumper.install();
6868
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// Copyright © 2013-2018 Esko Luontola and other Retrolambda contributors
2+
// This software is released under the Apache License 2.0.
3+
// The license text is at http://www.apache.org/licenses/LICENSE-2.0
4+
5+
package net.orfjackal.retrolambda.lambdas;
6+
7+
import com.esotericsoftware.minlog.Log;
8+
import net.orfjackal.retrolambda.Agent;
9+
import org.objectweb.asm.*;
10+
11+
import java.lang.instrument.*;
12+
import java.security.ProtectionDomain;
13+
14+
public class InnerClassLambdaMetafactoryTransformer implements ClassFileTransformer {
15+
@Override
16+
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] bytes) throws IllegalClassFormatException {
17+
if (!"java/lang/invoke/InnerClassLambdaMetafactory".equals(className)) {
18+
return null;
19+
}
20+
21+
try {
22+
byte[] transformed = transformMetafactory(bytes);
23+
Agent.enable();
24+
return transformed;
25+
} catch (Throwable e) {
26+
Log.error("Failed to transform " + className, e);
27+
return null;
28+
}
29+
}
30+
31+
private byte[] transformMetafactory(byte[] bytes) {
32+
ClassReader cr = new ClassReader(bytes);
33+
ClassWriter cw = new ClassWriter(cr, 0);
34+
ClassVisitor cv = new ClassVisitor(Opcodes.ASM7, cw) {
35+
@Override
36+
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
37+
MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
38+
if (name.equals("spinInnerClass")) {
39+
mv = new MethodVisitor(Opcodes.ASM7, mv) {
40+
@Override
41+
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
42+
super.visitMethodInsn(opcode, owner, name, desc, itf);
43+
if (name.equals("toByteArray")) {
44+
mv.visitInsn(Opcodes.DUP);
45+
mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(Agent.class), "saveLambda", "([B)V", false);
46+
}
47+
}
48+
49+
@Override
50+
public void visitMaxs(int maxStack, int maxLocals) {
51+
super.visitMaxs(maxStack + 1, maxLocals);
52+
}
53+
};
54+
}
55+
return mv;
56+
}
57+
};
58+
cr.accept(cv, 0);
59+
return cw.toByteArray();
60+
}
61+
}

Diff for: retrolambda/src/main/java/net/orfjackal/retrolambda/lambdas/LambdaClassSaverAgent.java

-34
This file was deleted.

0 commit comments

Comments
 (0)