Skip to content

Make Java agent work with JDK 9+ #148

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

Merged
merged 1 commit into from
Nov 30, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions .idea/libraries/Maven__org_ow2_asm_asm_7_0.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 0 additions & 13 deletions .idea/libraries/Maven__org_ow2_asm_asm_debug_all_5_2.xml

This file was deleted.

13 changes: 13 additions & 0 deletions .idea/libraries/Maven__org_ow2_asm_asm_tree_7_0.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion end-to-end-tests/end-to-end-tests.iml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
<orderEntry type="library" name="Maven: com.google.guava:guava:11.0.2" level="project" />
<orderEntry type="library" name="Maven: com.google.code.findbugs:jsr305:1.3.9" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: commons-lang:commons-lang:2.6" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.ow2.asm:asm-debug-all:5.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.ow2.asm:asm:7.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.ow2.asm:asm-tree:7.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.apache.bcel:bcel:5.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: jakarta-regexp:jakarta-regexp:1.4" level="project" />
<orderEntry type="module-library">
Expand Down
8 changes: 7 additions & 1 deletion end-to-end-tests/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,13 @@

<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm-debug-all</artifactId>
<artifactId>asm</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm-tree</artifactId>
<scope>test</scope>
</dependency>

Expand Down
12 changes: 9 additions & 3 deletions parent/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,14 @@

<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm-debug-all</artifactId>
<version>5.2</version>
<artifactId>asm</artifactId>
<version>7.0</version>
</dependency>

<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm-tree</artifactId>
<version>7.0</version>
</dependency>

<dependency>
Expand Down Expand Up @@ -312,7 +318,7 @@

<plugin>
<artifactId>maven-plugin-plugin</artifactId>
<version>3.4</version>
<version>3.6.0</version>
</plugin>

<plugin>
Expand Down
2 changes: 1 addition & 1 deletion retrolambda-maven-plugin/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.5</version>
<version>3.8.1</version>
</dependency>

</dependencies>
Expand Down
5 changes: 3 additions & 2 deletions retrolambda-maven-plugin/retrolambda-maven-plugin.iml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="retrolambda" />
<orderEntry type="library" name="Maven: org.ow2.asm:asm-debug-all:5.2" level="project" />
<orderEntry type="library" name="Maven: org.ow2.asm:asm:7.0" level="project" />
<orderEntry type="library" name="Maven: org.ow2.asm:asm-tree:7.0" level="project" />
<orderEntry type="library" name="Maven: com.esotericsoftware:minlog:1.3" level="project" />
<orderEntry type="module" module-name="retrolambda-api" />
<orderEntry type="library" name="Maven: org.apache.maven:maven-plugin-api:3.0" level="project" />
Expand Down Expand Up @@ -41,7 +42,7 @@
<orderEntry type="library" name="Maven: org.sonatype.plexus:plexus-sec-dispatcher:1.3" level="project" />
<orderEntry type="library" name="Maven: org.sonatype.plexus:plexus-cipher:1.4" level="project" />
<orderEntry type="library" name="Maven: com.google.guava:guava:18.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.5" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.8.1" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.12" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-library:1.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
Expand Down
8 changes: 7 additions & 1 deletion retrolambda/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,12 @@

<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm-debug-all</artifactId>
<artifactId>asm</artifactId>
</dependency>

<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm-tree</artifactId>
</dependency>

<dependency>
Expand All @@ -50,6 +55,7 @@
<mainClass>net.orfjackal.retrolambda.Main</mainClass>
</manifest>
<manifestEntries>
<Can-Retransform-Classes>true</Can-Retransform-Classes>
<Premain-Class>net.orfjackal.retrolambda.PreMain</Premain-Class>
</manifestEntries>
</archive>
Expand Down
3 changes: 2 additions & 1 deletion retrolambda/retrolambda.iml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="retrolambda-api" />
<orderEntry type="library" name="Maven: org.ow2.asm:asm-debug-all:5.2" level="project" />
<orderEntry type="library" name="Maven: org.ow2.asm:asm:7.0" level="project" />
<orderEntry type="library" name="Maven: org.ow2.asm:asm-tree:7.0" level="project" />
<orderEntry type="library" name="Maven: com.google.guava:guava:18.0" level="project" />
<orderEntry type="library" name="Maven: com.esotericsoftware:minlog:1.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.12" level="project" />
Expand Down
36 changes: 36 additions & 0 deletions retrolambda/src/main/java/net/orfjackal/retrolambda/Agent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright © 2013-2018 Esko Luontola and other Retrolambda contributors
// This software is released under the Apache License 2.0.
// The license text is at http://www.apache.org/licenses/LICENSE-2.0

package net.orfjackal.retrolambda;

import net.orfjackal.retrolambda.ext.ow2asm.EnhancedClassReader;
import net.orfjackal.retrolambda.lambdas.LambdaClassSaver;
import org.objectweb.asm.ClassReader;

public class Agent {

private static boolean enabled = false;
private static LambdaClassSaver lambdaClassSaver;
private static boolean isJavacHacksEnabled;

public static void enable() {
enabled = true;
}

public static boolean isEnabled() {
return enabled;
}

public static void setLambdaClassSaver(LambdaClassSaver lambdaClassSaver, boolean isJavacHacksEnabled) {
Agent.lambdaClassSaver = lambdaClassSaver;
Agent.isJavacHacksEnabled = isJavacHacksEnabled;
}

public static void saveLambda(byte[] bytes) {
if (lambdaClassSaver != null) {
ClassReader reader = EnhancedClassReader.create(bytes, isJavacHacksEnabled);
lambdaClassSaver.saveIfLambda(reader.getClassName(), bytes);
}
}
}
22 changes: 11 additions & 11 deletions retrolambda/src/main/java/net/orfjackal/retrolambda/PreMain.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,23 @@

import net.orfjackal.retrolambda.lambdas.*;

import java.io.File;
import java.lang.instrument.Instrumentation;
import java.net.URISyntaxException;
import java.util.jar.JarFile;

public class PreMain {

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

public static void premain(String agentArgs, Instrumentation inst) {
inst.addTransformer(agent);
agentLoaded = true;
inst.addTransformer(new InnerClassLambdaMetafactoryTransformer(), true);
inst.retransformClasses(Class.forName("java.lang.invoke.InnerClassLambdaMetafactory"));
}

public static boolean isAgentLoaded() {
return agentLoaded;
}

public static void setLambdaClassSaver(LambdaClassSaver lambdaClassSaver, boolean isJavacHacksEnabled) {
agent.setLambdaClassSaver(lambdaClassSaver, isJavacHacksEnabled);
private static File getAgentJarFile() throws URISyntaxException {
return new File(PreMain.class.getProtectionDomain().getCodeSource().getLocation().toURI());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public static void run(Config config) throws Throwable {
Log.info("Classpath: " + classpath);
Log.info("Included files: " + (includedFiles != null ? includedFiles.size() : "all"));
Log.info("JVM version: " + System.getProperty("java.version"));
Log.info("Agent enabled: " + PreMain.isAgentLoaded());
Log.info("Agent enabled: " + Agent.isEnabled());
Log.info("javac hacks: " + isJavacHacksEnabled);

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

try (LambdaClassDumper dumper = new LambdaClassDumper(lambdaClassSaver)) {
if (PreMain.isAgentLoaded()) {
PreMain.setLambdaClassSaver(lambdaClassSaver, isJavacHacksEnabled);
if (Agent.isEnabled()) {
Agent.setLambdaClassSaver(lambdaClassSaver, isJavacHacksEnabled);
} else {
dumper.install();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Copyright © 2013-2018 Esko Luontola and other Retrolambda contributors
// This software is released under the Apache License 2.0.
// The license text is at http://www.apache.org/licenses/LICENSE-2.0

package net.orfjackal.retrolambda.lambdas;

import com.esotericsoftware.minlog.Log;
import net.orfjackal.retrolambda.Agent;
import org.objectweb.asm.*;

import java.lang.instrument.*;
import java.security.ProtectionDomain;

public class InnerClassLambdaMetafactoryTransformer implements ClassFileTransformer {
@Override
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] bytes) throws IllegalClassFormatException {
if (!"java/lang/invoke/InnerClassLambdaMetafactory".equals(className)) {
return null;
}

try {
byte[] transformed = transformMetafactory(bytes);
Agent.enable();
return transformed;
} catch (Throwable e) {
Log.error("Failed to transform " + className, e);
return null;
}
}

private byte[] transformMetafactory(byte[] bytes) {
ClassReader cr = new ClassReader(bytes);
ClassWriter cw = new ClassWriter(cr, 0);
ClassVisitor cv = new ClassVisitor(Opcodes.ASM7, cw) {
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
if (name.equals("spinInnerClass")) {
mv = new MethodVisitor(Opcodes.ASM7, mv) {
@Override
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
super.visitMethodInsn(opcode, owner, name, desc, itf);
if (name.equals("toByteArray")) {
mv.visitInsn(Opcodes.DUP);
mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(Agent.class), "saveLambda", "([B)V", false);
}
}

@Override
public void visitMaxs(int maxStack, int maxLocals) {
super.visitMaxs(maxStack + 1, maxLocals);
}
};
}
return mv;
}
};
cr.accept(cv, 0);
return cw.toByteArray();
}
}

This file was deleted.