From 7e682a66e6a3d5924104c3bdad2561e5a029c5e5 Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov Date: Sun, 12 Aug 2018 02:33:13 +0200 Subject: [PATCH 1/3] PoC --- .../net/orfjackal/retrolambda/ClassAnalyzer.java | 2 +- .../net/orfjackal/retrolambda/ClassReader2.java | 14 ++++++++++++++ .../retrolambda/files/OutputDirectory.java | 3 ++- .../retrolambda/lambdas/LambdaClassSaver.java | 4 +++- .../retrolambda/lambdas/LambdaClassSaverAgent.java | 3 ++- 5 files changed, 22 insertions(+), 4 deletions(-) create mode 100644 retrolambda/src/main/java/net/orfjackal/retrolambda/ClassReader2.java diff --git a/retrolambda/src/main/java/net/orfjackal/retrolambda/ClassAnalyzer.java b/retrolambda/src/main/java/net/orfjackal/retrolambda/ClassAnalyzer.java index fc92732a..ce8f212a 100644 --- a/retrolambda/src/main/java/net/orfjackal/retrolambda/ClassAnalyzer.java +++ b/retrolambda/src/main/java/net/orfjackal/retrolambda/ClassAnalyzer.java @@ -22,7 +22,7 @@ public class ClassAnalyzer { private final Map renamedLambdaMethods = new HashMap<>(); public void analyze(byte[] bytecode) { - analyze(new ClassReader(bytecode)); + analyze(new ClassReader2(bytecode)); } public void analyze(ClassReader cr) { diff --git a/retrolambda/src/main/java/net/orfjackal/retrolambda/ClassReader2.java b/retrolambda/src/main/java/net/orfjackal/retrolambda/ClassReader2.java new file mode 100644 index 00000000..0fa5c30e --- /dev/null +++ b/retrolambda/src/main/java/net/orfjackal/retrolambda/ClassReader2.java @@ -0,0 +1,14 @@ +package net.orfjackal.retrolambda; + +import org.objectweb.asm.*; + +public class ClassReader2 extends ClassReader { + public ClassReader2(byte[] b) { + super(b); + } + + @Override + protected Label readLabel(int offset, Label[] labels) { + return super.readLabel(Math.min(offset, labels.length - 1), labels); + } +} diff --git a/retrolambda/src/main/java/net/orfjackal/retrolambda/files/OutputDirectory.java b/retrolambda/src/main/java/net/orfjackal/retrolambda/files/OutputDirectory.java index 88cec60e..406fe38c 100644 --- a/retrolambda/src/main/java/net/orfjackal/retrolambda/files/OutputDirectory.java +++ b/retrolambda/src/main/java/net/orfjackal/retrolambda/files/OutputDirectory.java @@ -5,6 +5,7 @@ package net.orfjackal.retrolambda.files; import org.objectweb.asm.ClassReader; +import net.orfjackal.retrolambda.ClassReader2; import java.io.IOException; import java.nio.file.*; @@ -21,7 +22,7 @@ public void writeClass(byte[] bytecode) throws IOException { if (bytecode == null) { return; } - ClassReader cr = new ClassReader(bytecode); + ClassReader cr = new ClassReader2(bytecode); Path relativePath = outputDir.getFileSystem().getPath(cr.getClassName() + ".class"); writeFile(relativePath, bytecode); } diff --git a/retrolambda/src/main/java/net/orfjackal/retrolambda/lambdas/LambdaClassSaver.java b/retrolambda/src/main/java/net/orfjackal/retrolambda/lambdas/LambdaClassSaver.java index f2d02a90..af9242a4 100644 --- a/retrolambda/src/main/java/net/orfjackal/retrolambda/lambdas/LambdaClassSaver.java +++ b/retrolambda/src/main/java/net/orfjackal/retrolambda/lambdas/LambdaClassSaver.java @@ -7,7 +7,9 @@ import com.esotericsoftware.minlog.Log; import net.orfjackal.retrolambda.Transformers; import net.orfjackal.retrolambda.files.OutputDirectory; + import org.objectweb.asm.ClassReader; +import net.orfjackal.retrolambda.ClassReader2; import java.io.IOException; @@ -29,7 +31,7 @@ public void saveIfLambda(String className, byte[] bytecode) { private void reifyLambdaClass(String className, byte[] bytecode) { Log.info("Saving lambda class: " + className); - bytecode = transformers.backportLambdaClass(new ClassReader(bytecode)); + bytecode = transformers.backportLambdaClass(new ClassReader2(bytecode)); try { saver.writeClass(bytecode); } catch (IOException e) { diff --git a/retrolambda/src/main/java/net/orfjackal/retrolambda/lambdas/LambdaClassSaverAgent.java b/retrolambda/src/main/java/net/orfjackal/retrolambda/lambdas/LambdaClassSaverAgent.java index 6cb2b90e..b23a4096 100644 --- a/retrolambda/src/main/java/net/orfjackal/retrolambda/lambdas/LambdaClassSaverAgent.java +++ b/retrolambda/src/main/java/net/orfjackal/retrolambda/lambdas/LambdaClassSaverAgent.java @@ -5,6 +5,7 @@ package net.orfjackal.retrolambda.lambdas; import org.objectweb.asm.ClassReader; +import net.orfjackal.retrolambda.ClassReader2; import java.lang.instrument.*; import java.security.ProtectionDomain; @@ -22,7 +23,7 @@ public byte[] transform(ClassLoader loader, String className, Class classBein if (className == null) { // Since JDK 8 build b121 or so, lambda classes have a null class name, // but we can read it from the bytecode where the name still exists. - className = new ClassReader(classfileBuffer).getClassName(); + className = new ClassReader2(classfileBuffer).getClassName(); } if (lambdaClassSaver != null) { lambdaClassSaver.saveIfLambda(className, classfileBuffer); From 410a7a5a72bddd8ca784c43502c32ca11ad1daba Mon Sep 17 00:00:00 2001 From: Lyubomyr Shaydariv Date: Sun, 12 Aug 2018 17:26:24 +0300 Subject: [PATCH 2/3] Introduced retrolambda.javacHacks to work around javac issues --- README.md | 4 +++ .../retrolambda/api/RetrolambdaApi.java | 1 + .../orfjackal/retrolambda/ClassAnalyzer.java | 13 ++++----- .../orfjackal/retrolambda/ClassReader2.java | 14 ---------- .../net/orfjackal/retrolambda/Config.java | 2 ++ .../net/orfjackal/retrolambda/PreMain.java | 4 +-- .../orfjackal/retrolambda/Retrolambda.java | 12 ++++++--- .../retrolambda/SystemPropertiesConfig.java | 15 +++++++++++ .../orfjackal/retrolambda/Transformers.java | 9 ++++--- .../ext/ow2asm/EnhancedClassReader.java | 27 +++++++++++++++++++ .../retrolambda/files/OutputDirectory.java | 7 +++-- .../retrolambda/interfaces/ClassInfo.java | 5 ++-- .../retrolambda/lambdas/LambdaClassSaver.java | 11 ++++---- .../lambdas/LambdaClassSaverAgent.java | 9 ++++--- .../retrolambda/ClassAnalyzerTest.java | 2 +- 15 files changed, 89 insertions(+), 46 deletions(-) delete mode 100644 retrolambda/src/main/java/net/orfjackal/retrolambda/ClassReader2.java create mode 100644 retrolambda/src/main/java/net/orfjackal/retrolambda/ext/ow2asm/EnhancedClassReader.java diff --git a/README.md b/README.md index 4668cf12..a6e2775f 100644 --- a/README.md +++ b/README.md @@ -140,6 +140,10 @@ Configurable system properties: Alternative to retrolambda.includedFiles for avoiding the command line length limit. The file must list one file per line with UTF-8 encoding. + retrolambda.javacHacks + Attempts to fix javac bugs (type-annotation emission for local variables). + Disabled by default. Enable by setting to "true" + retrolambda.quiet Reduces the amount of logging. Disabled by default. Enable by setting to "true" diff --git a/retrolambda-api/src/main/java/net/orfjackal/retrolambda/api/RetrolambdaApi.java b/retrolambda-api/src/main/java/net/orfjackal/retrolambda/api/RetrolambdaApi.java index 00e5209b..7276b978 100644 --- a/retrolambda-api/src/main/java/net/orfjackal/retrolambda/api/RetrolambdaApi.java +++ b/retrolambda-api/src/main/java/net/orfjackal/retrolambda/api/RetrolambdaApi.java @@ -16,4 +16,5 @@ public class RetrolambdaApi { public static final String INPUT_DIR = PREFIX + "inputDir"; public static final String DEFAULT_METHODS = PREFIX + "defaultMethods"; public static final String BYTECODE_VERSION = PREFIX + "bytecodeVersion"; + public static final String JAVAC_HACKS = PREFIX + "javacHacks"; } diff --git a/retrolambda/src/main/java/net/orfjackal/retrolambda/ClassAnalyzer.java b/retrolambda/src/main/java/net/orfjackal/retrolambda/ClassAnalyzer.java index ce8f212a..ab241824 100644 --- a/retrolambda/src/main/java/net/orfjackal/retrolambda/ClassAnalyzer.java +++ b/retrolambda/src/main/java/net/orfjackal/retrolambda/ClassAnalyzer.java @@ -4,6 +4,7 @@ package net.orfjackal.retrolambda; +import net.orfjackal.retrolambda.ext.ow2asm.EnhancedClassReader; import net.orfjackal.retrolambda.interfaces.*; import net.orfjackal.retrolambda.lambdas.*; import net.orfjackal.retrolambda.util.*; @@ -21,11 +22,11 @@ public class ClassAnalyzer { private final Map relocatedMethods = new HashMap<>(); private final Map renamedLambdaMethods = new HashMap<>(); - public void analyze(byte[] bytecode) { - analyze(new ClassReader2(bytecode)); + public void analyze(byte[] bytecode, boolean isJavacHacksEnabled) { + analyze(new EnhancedClassReader(bytecode, isJavacHacksEnabled)); } - public void analyze(ClassReader cr) { + public void analyze(EnhancedClassReader cr) { ClassInfo c = new ClassInfo(cr); classes.put(c.type, c); @@ -37,7 +38,7 @@ public void analyze(ClassReader cr) { analyzeClassOrInterface(c, cr); } - private void analyzeClass(ClassInfo c, ClassReader cr) { + private void analyzeClass(ClassInfo c, EnhancedClassReader cr) { cr.accept(new ClassVisitor(ASM5) { private String owner; @@ -64,7 +65,7 @@ public MethodVisitor visitMethod(int access, String name, String desc, String si }, ClassReader.SKIP_CODE); } - private void analyzeInterface(ClassInfo c, ClassReader cr) { + private void analyzeInterface(ClassInfo c, EnhancedClassReader cr) { cr.accept(new ClassVisitor(ASM5) { private String owner; private String companion; @@ -100,7 +101,7 @@ public MethodVisitor visitMethod(int access, String name, String desc, String si }, ClassReader.SKIP_CODE); } - private void analyzeClassOrInterface(ClassInfo c, ClassReader cr) { + private void analyzeClassOrInterface(ClassInfo c, EnhancedClassReader cr) { cr.accept(new ClassVisitor(ASM5) { private String owner; diff --git a/retrolambda/src/main/java/net/orfjackal/retrolambda/ClassReader2.java b/retrolambda/src/main/java/net/orfjackal/retrolambda/ClassReader2.java deleted file mode 100644 index 0fa5c30e..00000000 --- a/retrolambda/src/main/java/net/orfjackal/retrolambda/ClassReader2.java +++ /dev/null @@ -1,14 +0,0 @@ -package net.orfjackal.retrolambda; - -import org.objectweb.asm.*; - -public class ClassReader2 extends ClassReader { - public ClassReader2(byte[] b) { - super(b); - } - - @Override - protected Label readLabel(int offset, Label[] labels) { - return super.readLabel(Math.min(offset, labels.length - 1), labels); - } -} diff --git a/retrolambda/src/main/java/net/orfjackal/retrolambda/Config.java b/retrolambda/src/main/java/net/orfjackal/retrolambda/Config.java index 208ee6b1..e5d2c983 100644 --- a/retrolambda/src/main/java/net/orfjackal/retrolambda/Config.java +++ b/retrolambda/src/main/java/net/orfjackal/retrolambda/Config.java @@ -21,5 +21,7 @@ public interface Config { List getIncludedFiles(); + boolean isJavacHacksEnabled(); + boolean isQuiet(); } diff --git a/retrolambda/src/main/java/net/orfjackal/retrolambda/PreMain.java b/retrolambda/src/main/java/net/orfjackal/retrolambda/PreMain.java index 971e8c6f..bd8d228e 100644 --- a/retrolambda/src/main/java/net/orfjackal/retrolambda/PreMain.java +++ b/retrolambda/src/main/java/net/orfjackal/retrolambda/PreMain.java @@ -22,7 +22,7 @@ public static boolean isAgentLoaded() { return agentLoaded; } - public static void setLambdaClassSaver(LambdaClassSaver lambdaClassSaver) { - agent.setLambdaClassSaver(lambdaClassSaver); + public static void setLambdaClassSaver(LambdaClassSaver lambdaClassSaver, boolean isJavacHacksEnabled) { + agent.setLambdaClassSaver(lambdaClassSaver, isJavacHacksEnabled); } } diff --git a/retrolambda/src/main/java/net/orfjackal/retrolambda/Retrolambda.java b/retrolambda/src/main/java/net/orfjackal/retrolambda/Retrolambda.java index cccf24df..68fc4d9c 100644 --- a/retrolambda/src/main/java/net/orfjackal/retrolambda/Retrolambda.java +++ b/retrolambda/src/main/java/net/orfjackal/retrolambda/Retrolambda.java @@ -32,6 +32,7 @@ public static void run(Config config) throws Throwable { Path outputDir = config.getOutputDir(); List classpath = config.getClasspath(); List includedFiles = config.getIncludedFiles(); + boolean isJavacHacksEnabled = config.isJavacHacksEnabled(); if (config.isQuiet()) { Log.WARN(); } else { @@ -45,6 +46,9 @@ public static void run(Config config) throws Throwable { Log.info("Included files: " + (includedFiles != null ? includedFiles.size() : "all")); Log.info("JVM version: " + System.getProperty("java.version")); Log.info("Agent enabled: " + PreMain.isAgentLoaded()); + if (isJavacHacksEnabled) { + Log.info("javac hacks: " + isJavacHacksEnabled); + } if (!Files.isDirectory(inputDir)) { Log.info("Nothing to do; not a directory: " + inputDir); @@ -56,11 +60,11 @@ public static void run(Config config) throws Throwable { ClassAnalyzer analyzer = new ClassAnalyzer(); OutputDirectory outputDirectory = new OutputDirectory(outputDir); Transformers transformers = new Transformers(bytecodeVersion, defaultMethodsEnabled, analyzer); - LambdaClassSaver lambdaClassSaver = new LambdaClassSaver(outputDirectory, transformers); + LambdaClassSaver lambdaClassSaver = new LambdaClassSaver(outputDirectory, transformers, isJavacHacksEnabled); try (LambdaClassDumper dumper = new LambdaClassDumper(lambdaClassSaver)) { if (PreMain.isAgentLoaded()) { - PreMain.setLambdaClassSaver(lambdaClassSaver); + PreMain.setLambdaClassSaver(lambdaClassSaver, isJavacHacksEnabled); } else { dumper.install(); } @@ -68,7 +72,7 @@ public static void run(Config config) throws Throwable { visitFiles(inputDir, includedFiles, new ClasspathVisitor() { @Override protected void visitClass(byte[] bytecode) { - analyzer.analyze(bytecode); + analyzer.analyze(bytecode, isJavacHacksEnabled); } @Override @@ -95,7 +99,7 @@ protected void visitResource(Path relativePath, byte[] content) throws IOExcepti // We need to load some of the classes (for calling the lambda metafactory) // so we need to take care not to modify any bytecode before loading them. for (byte[] bytecode : transformed) { - outputDirectory.writeClass(bytecode); + outputDirectory.writeClass(bytecode, isJavacHacksEnabled); } } } diff --git a/retrolambda/src/main/java/net/orfjackal/retrolambda/SystemPropertiesConfig.java b/retrolambda/src/main/java/net/orfjackal/retrolambda/SystemPropertiesConfig.java index 566c851a..18afb719 100644 --- a/retrolambda/src/main/java/net/orfjackal/retrolambda/SystemPropertiesConfig.java +++ b/retrolambda/src/main/java/net/orfjackal/retrolambda/SystemPropertiesConfig.java @@ -191,6 +191,21 @@ public List getIncludedFiles() { } + // useJavac8ReadLabelHack + + static { + optionalParameterHelp(JAVAC_HACKS, + "Attempts to fix javac bugs (type-annotation emission for local variables).", + "Disabled by default. Enable by setting to \"true\""); + + } + + @Override + public boolean isJavacHacksEnabled() { + return Boolean.parseBoolean(p.getProperty(JAVAC_HACKS, "false")); + } + + // quiet static { diff --git a/retrolambda/src/main/java/net/orfjackal/retrolambda/Transformers.java b/retrolambda/src/main/java/net/orfjackal/retrolambda/Transformers.java index 92eb91a3..3a070820 100644 --- a/retrolambda/src/main/java/net/orfjackal/retrolambda/Transformers.java +++ b/retrolambda/src/main/java/net/orfjackal/retrolambda/Transformers.java @@ -4,6 +4,7 @@ package net.orfjackal.retrolambda; +import net.orfjackal.retrolambda.ext.ow2asm.EnhancedClassReader; import net.orfjackal.retrolambda.interfaces.*; import net.orfjackal.retrolambda.lambdas.*; import net.orfjackal.retrolambda.requirenonnull.RequireNonNull; @@ -26,7 +27,7 @@ public Transformers(int targetVersion, boolean defaultMethodsEnabled, ClassAnaly this.analyzer = analyzer; } - public byte[] backportLambdaClass(ClassReader reader) { + public byte[] backportLambdaClass(EnhancedClassReader reader) { return transform(reader, (next) -> { if (defaultMethodsEnabled) { // Lambda classes are generated dynamically, so they were not @@ -43,7 +44,7 @@ public byte[] backportLambdaClass(ClassReader reader) { }); } - public byte[] backportClass(ClassReader reader) { + public byte[] backportClass(EnhancedClassReader reader) { return transform(reader, (next) -> { if (defaultMethodsEnabled) { next = new UpdateRelocatedMethodInvocations(next, analyzer); @@ -54,7 +55,7 @@ public byte[] backportClass(ClassReader reader) { }); } - public List backportInterface(ClassReader reader) { + public List backportInterface(EnhancedClassReader reader) { // The lambdas must be backported only once, because bad things will happen if a lambda // is called by different class name in the interface and its companion class, and then // the wrong one of them is written to disk last. @@ -103,7 +104,7 @@ private byte[] transform(ClassNode node, ClassVisitorChain chain) { return transform(node.name, node::accept, chain); } - private byte[] transform(ClassReader reader, ClassVisitorChain chain) { + private byte[] transform(EnhancedClassReader reader, ClassVisitorChain chain) { return transform(reader.getClassName(), cv -> reader.accept(cv, 0), chain); } diff --git a/retrolambda/src/main/java/net/orfjackal/retrolambda/ext/ow2asm/EnhancedClassReader.java b/retrolambda/src/main/java/net/orfjackal/retrolambda/ext/ow2asm/EnhancedClassReader.java new file mode 100644 index 00000000..28736885 --- /dev/null +++ b/retrolambda/src/main/java/net/orfjackal/retrolambda/ext/ow2asm/EnhancedClassReader.java @@ -0,0 +1,27 @@ +// Copyright © 2013-2015 Esko Luontola +// 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.ext.ow2asm; + +import org.objectweb.asm.*; + +public class EnhancedClassReader extends ClassReader { + + private final boolean isJavacHacksEnabled; + + public EnhancedClassReader(byte[] b, boolean isJavacHacksEnabled) { + super(b); + this.isJavacHacksEnabled = isJavacHacksEnabled; + } + + @Override + protected Label readLabel(int offset, Label[] labels) { + if (!isJavacHacksEnabled) { + return super.readLabel(offset, labels); + } + // A workaround suggested by Evgeny Mandrikov. See more: https://gitlab.ow2.org/asm/asm/issues/317845 + return super.readLabel(Math.min(offset, labels.length - 1), labels); + } + +} diff --git a/retrolambda/src/main/java/net/orfjackal/retrolambda/files/OutputDirectory.java b/retrolambda/src/main/java/net/orfjackal/retrolambda/files/OutputDirectory.java index 406fe38c..2300cfe6 100644 --- a/retrolambda/src/main/java/net/orfjackal/retrolambda/files/OutputDirectory.java +++ b/retrolambda/src/main/java/net/orfjackal/retrolambda/files/OutputDirectory.java @@ -4,8 +4,7 @@ package net.orfjackal.retrolambda.files; -import org.objectweb.asm.ClassReader; -import net.orfjackal.retrolambda.ClassReader2; +import net.orfjackal.retrolambda.ext.ow2asm.EnhancedClassReader; import java.io.IOException; import java.nio.file.*; @@ -18,11 +17,11 @@ public OutputDirectory(Path outputDir) { this.outputDir = outputDir; } - public void writeClass(byte[] bytecode) throws IOException { + public void writeClass(byte[] bytecode, boolean isJavacHacksEnabled) throws IOException { if (bytecode == null) { return; } - ClassReader cr = new ClassReader2(bytecode); + EnhancedClassReader cr = new EnhancedClassReader(bytecode, isJavacHacksEnabled); Path relativePath = outputDir.getFileSystem().getPath(cr.getClassName() + ".class"); writeFile(relativePath, bytecode); } diff --git a/retrolambda/src/main/java/net/orfjackal/retrolambda/interfaces/ClassInfo.java b/retrolambda/src/main/java/net/orfjackal/retrolambda/interfaces/ClassInfo.java index ae8804dd..31b176b5 100644 --- a/retrolambda/src/main/java/net/orfjackal/retrolambda/interfaces/ClassInfo.java +++ b/retrolambda/src/main/java/net/orfjackal/retrolambda/interfaces/ClassInfo.java @@ -4,6 +4,7 @@ package net.orfjackal.retrolambda.interfaces; +import net.orfjackal.retrolambda.ext.ow2asm.EnhancedClassReader; import net.orfjackal.retrolambda.util.Flags; import org.objectweb.asm.*; @@ -11,7 +12,7 @@ public class ClassInfo { - public final ClassReader reader; + public final EnhancedClassReader reader; private final int access; public final Type type; public final Type superclass; @@ -26,7 +27,7 @@ public ClassInfo() { this.superclass = null; } - public ClassInfo(ClassReader cr) { + public ClassInfo(EnhancedClassReader cr) { this.reader = cr; this.access = cr.getAccess(); this.type = Type.getObjectType(cr.getClassName()); diff --git a/retrolambda/src/main/java/net/orfjackal/retrolambda/lambdas/LambdaClassSaver.java b/retrolambda/src/main/java/net/orfjackal/retrolambda/lambdas/LambdaClassSaver.java index af9242a4..2e1dcba2 100644 --- a/retrolambda/src/main/java/net/orfjackal/retrolambda/lambdas/LambdaClassSaver.java +++ b/retrolambda/src/main/java/net/orfjackal/retrolambda/lambdas/LambdaClassSaver.java @@ -8,8 +8,7 @@ import net.orfjackal.retrolambda.Transformers; import net.orfjackal.retrolambda.files.OutputDirectory; -import org.objectweb.asm.ClassReader; -import net.orfjackal.retrolambda.ClassReader2; +import net.orfjackal.retrolambda.ext.ow2asm.EnhancedClassReader; import java.io.IOException; @@ -17,10 +16,12 @@ public class LambdaClassSaver { private final OutputDirectory saver; private final Transformers transformers; + private final boolean isJavacHacksEnabled; - public LambdaClassSaver(OutputDirectory saver, Transformers transformers) { + public LambdaClassSaver(OutputDirectory saver, Transformers transformers, boolean isJavacHacksEnabled) { this.saver = saver; this.transformers = transformers; + this.isJavacHacksEnabled = isJavacHacksEnabled; } public void saveIfLambda(String className, byte[] bytecode) { @@ -31,9 +32,9 @@ public void saveIfLambda(String className, byte[] bytecode) { private void reifyLambdaClass(String className, byte[] bytecode) { Log.info("Saving lambda class: " + className); - bytecode = transformers.backportLambdaClass(new ClassReader2(bytecode)); + bytecode = transformers.backportLambdaClass(new EnhancedClassReader(bytecode, isJavacHacksEnabled)); try { - saver.writeClass(bytecode); + saver.writeClass(bytecode, isJavacHacksEnabled); } catch (IOException e) { throw new RuntimeException(e); } diff --git a/retrolambda/src/main/java/net/orfjackal/retrolambda/lambdas/LambdaClassSaverAgent.java b/retrolambda/src/main/java/net/orfjackal/retrolambda/lambdas/LambdaClassSaverAgent.java index b23a4096..5e545bd4 100644 --- a/retrolambda/src/main/java/net/orfjackal/retrolambda/lambdas/LambdaClassSaverAgent.java +++ b/retrolambda/src/main/java/net/orfjackal/retrolambda/lambdas/LambdaClassSaverAgent.java @@ -4,8 +4,7 @@ package net.orfjackal.retrolambda.lambdas; -import org.objectweb.asm.ClassReader; -import net.orfjackal.retrolambda.ClassReader2; +import net.orfjackal.retrolambda.ext.ow2asm.EnhancedClassReader; import java.lang.instrument.*; import java.security.ProtectionDomain; @@ -13,9 +12,11 @@ public class LambdaClassSaverAgent implements ClassFileTransformer { private LambdaClassSaver lambdaClassSaver; + private boolean isJavacHacksEnabled; - public void setLambdaClassSaver(LambdaClassSaver lambdaClassSaver) { + public void setLambdaClassSaver(LambdaClassSaver lambdaClassSaver, boolean isJavacHacksEnabled) { this.lambdaClassSaver = lambdaClassSaver; + this.isJavacHacksEnabled = isJavacHacksEnabled; } @Override @@ -23,7 +24,7 @@ public byte[] transform(ClassLoader loader, String className, Class classBein if (className == null) { // Since JDK 8 build b121 or so, lambda classes have a null class name, // but we can read it from the bytecode where the name still exists. - className = new ClassReader2(classfileBuffer).getClassName(); + className = new EnhancedClassReader(classfileBuffer, isJavacHacksEnabled).getClassName(); } if (lambdaClassSaver != null) { lambdaClassSaver.saveIfLambda(className, classfileBuffer); diff --git a/retrolambda/src/test/java/net/orfjackal/retrolambda/ClassAnalyzerTest.java b/retrolambda/src/test/java/net/orfjackal/retrolambda/ClassAnalyzerTest.java index 0b70f713..9e438786 100644 --- a/retrolambda/src/test/java/net/orfjackal/retrolambda/ClassAnalyzerTest.java +++ b/retrolambda/src/test/java/net/orfjackal/retrolambda/ClassAnalyzerTest.java @@ -513,7 +513,7 @@ private void analyze(Class... classes) { Collections.shuffle(inAnyOrder); for (Class clazz : inAnyOrder) { byte[] bytecode = readBytecode(clazz); - analyzer.analyze(bytecode); + analyzer.analyze(bytecode, false); } } From d605bfe72d62162bc1de164f53121559c7c33d86 Mon Sep 17 00:00:00 2001 From: Lyubomyr Shaydariv Date: Sun, 12 Aug 2018 18:41:34 +0300 Subject: [PATCH 3/3] Added retrolambda.javacHacks support to the Maven plugin --- .../orfjackal/retrolambda/maven/ProcessClassesMojo.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/retrolambda-maven-plugin/src/main/java/net/orfjackal/retrolambda/maven/ProcessClassesMojo.java b/retrolambda-maven-plugin/src/main/java/net/orfjackal/retrolambda/maven/ProcessClassesMojo.java index dd5e1393..06b94aab 100644 --- a/retrolambda-maven-plugin/src/main/java/net/orfjackal/retrolambda/maven/ProcessClassesMojo.java +++ b/retrolambda-maven-plugin/src/main/java/net/orfjackal/retrolambda/maven/ProcessClassesMojo.java @@ -79,6 +79,14 @@ abstract class ProcessClassesMojo extends AbstractMojo { @Parameter(defaultValue = "false", property = "retrolambdaDefaultMethods", required = true) public boolean defaultMethods; + /** + * Whether to apply experimental javac issues workarounds. + * + * @since 2.5.5 + */ + @Parameter(defaultValue = "false", property = "retrolambdaJavacHacks", required = true) + public boolean javacHacks; + /** * Reduces the amount of logging. * @@ -117,6 +125,7 @@ public void execute() throws MojoExecutionException { config.setProperty(RetrolambdaApi.INPUT_DIR, getInputDir().getAbsolutePath()); config.setProperty(RetrolambdaApi.OUTPUT_DIR, getOutputDir().getAbsolutePath()); config.setProperty(RetrolambdaApi.CLASSPATH, getClasspath()); + config.setProperty(RetrolambdaApi.JAVAC_HACKS, "" + javacHacks); if (fork) { processClassesInForkedProcess(config);