Skip to content

Commit 987ef34

Browse files
committed
Build Recompile Environment
1 parent 3c4ce10 commit 987ef34

File tree

19 files changed

+404
-60
lines changed

19 files changed

+404
-60
lines changed

src/main/java/cn/enaium/joe/JavaOctetEditor.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
* @author Enaium
4242
*/
4343
public class JavaOctetEditor {
44+
public static final ClassLoader classLoader = JavaOctetEditor.class.getClassLoader();
4445
private static JavaOctetEditor instance;
4546

4647
public static final String TITLE = "JavaOctetEditor";
@@ -143,4 +144,13 @@ public void setJar(Jar jar) {
143144
public static JavaOctetEditor getInstance() {
144145
return instance;
145146
}
147+
148+
public static boolean isClassExist(String canonicalName){
149+
try {
150+
Class.forName(canonicalName, false, classLoader);
151+
return true;
152+
} catch (ClassNotFoundException e) {
153+
return false;
154+
}
155+
}
146156
}

src/main/java/cn/enaium/joe/gui/panel/file/tabbed/tab/classes/ASMifierTablePanel.java

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,19 @@
1717
package cn.enaium.joe.gui.panel.file.tabbed.tab.classes;
1818

1919
import cn.enaium.joe.JavaOctetEditor;
20-
import cn.enaium.joe.compiler.Compiler;
20+
import cn.enaium.joe.util.compiler.Compiler;
2121
import cn.enaium.joe.config.extend.KeymapConfig;
2222
import cn.enaium.joe.event.events.EditSaveSuccessEvent;
2323
import cn.enaium.joe.gui.panel.CodeAreaPanel;
2424
import cn.enaium.joe.util.*;
25+
import cn.enaium.joe.util.classes.ASMClassLoader;
2526
import org.fife.ui.rsyntaxtextarea.SyntaxConstants;
2627
import org.objectweb.asm.ClassReader;
2728
import org.objectweb.asm.tree.ClassNode;
2829
import org.objectweb.asm.util.ASMifier;
2930
import org.objectweb.asm.util.TraceClassVisitor;
3031

31-
import javax.swing.*;
3232
import java.awt.*;
33-
import java.awt.event.InputEvent;
34-
import java.awt.event.KeyEvent;
3533
import java.io.PrintWriter;
3634
import java.io.StringWriter;
3735

@@ -46,7 +44,9 @@ public ASMifierTablePanel(ClassNode classNode) {
4644
CodeAreaPanel codeAreaPanel = this.codeAreaPanel = new CodeAreaPanel() {{
4745
KeyStrokeUtil.register(getTextArea(), JavaOctetEditor.getInstance().config.getByClass(KeymapConfig.class).save.getValue(), () -> {
4846
try {
49-
String stringBuilder = "import org.objectweb.asm.AnnotationVisitor;" +
47+
String className = "ASMifier" + Integer.toHexString(classNode.name.hashCode()) + Integer.toHexString(getTextArea().getText().hashCode());
48+
String stringBuilder =
49+
"import org.objectweb.asm.AnnotationVisitor;" +
5050
"import org.objectweb.asm.Attribute;" +
5151
"import org.objectweb.asm.ClassReader;" +
5252
"import org.objectweb.asm.ClassWriter;" +
@@ -60,26 +60,15 @@ public ASMifierTablePanel(ClassNode classNode) {
6060
"import org.objectweb.asm.ModuleVisitor;" +
6161
"import org.objectweb.asm.Type;" +
6262
"import org.objectweb.asm.TypePath;" +
63-
"public class" + " " + ASMifier.class.getSimpleName() + " " + "implements Opcodes" +
63+
"public class " + className + " implements Opcodes" +
6464
"{" +
6565
"public static byte[] dump() throws Exception {" +
6666
getTextArea().getText() +
6767
"return classWriter.toByteArray();" +
6868
"}" +
6969
"}";
70-
Compiler compiler = new Compiler();
71-
compiler.addSource(ASMifier.class.getSimpleName(), stringBuilder);
72-
compiler.compile();
7370

74-
ClassLoader loader = new ClassLoader() {
75-
@Override
76-
protected Class<?> findClass(String name) {
77-
byte[] bytes = compiler.getClasses().get(ASMifier.class.getSimpleName());
78-
return defineClass(name, bytes, 0, bytes.length);
79-
}
80-
};
81-
82-
byte[] dumps = (byte[]) loader.loadClass(ASMifier.class.getSimpleName()).getMethod("dump").invoke(null);
71+
byte[] dumps = (byte[])new ASMClassLoader().defineClass(className, Compiler.compileSingle(className, stringBuilder)).getMethod("dump").invoke(null);
8372
ReflectUtil.copyAllMember(classNode, ASMUtil.acceptClassNode(new ClassReader(dumps)));
8473
MessageUtil.info(LangUtil.i18n("success"));
8574
EditSaveSuccessEvent.trigger(classNode.name);
@@ -94,6 +83,13 @@ protected Class<?> findClass(String name) {
9483
add(codeAreaPanel);
9584
}
9685

86+
public static String getSimpleName(String name){
87+
int idx = name.lastIndexOf('/');
88+
if (idx != -1){
89+
return name.substring(idx + 1, name.length() - 1);
90+
} else return name.substring(name.lastIndexOf('.') + 1, name.length() - 1);
91+
}
92+
9793
public void update(){
9894
StringWriter stringWriter = new StringWriter();
9995

src/main/java/cn/enaium/joe/gui/panel/file/tabbed/tab/classes/ClassTabPanel.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ public ClassTabPanel(ClassNode classNode) {
6666
public void update(boolean forced){
6767
if (forced || classTabIndex != 0) traceBytecodeTabPanel.update();
6868
if (forced || classTabIndex != 1) decompileTabPanel.update();
69-
if (forced || cclassTabIndex != 2) asmTablePanel.update();
69+
if (forced || classTabIndex != 2) asmTablePanel.update();
7070
}
7171

7272
static {

src/main/java/cn/enaium/joe/gui/panel/file/tabbed/tab/classes/DecompileTabPanel.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
package cn.enaium.joe.gui.panel.file.tabbed.tab.classes;
1818

1919
import cn.enaium.joe.JavaOctetEditor;
20-
import cn.enaium.joe.compiler.Compiler;
20+
import cn.enaium.joe.util.compiler.Compiler;
2121
import cn.enaium.joe.config.extend.KeymapConfig;
2222
import cn.enaium.joe.event.events.EditSaveSuccessEvent;
2323
import cn.enaium.joe.gui.panel.CodeAreaPanel;
@@ -26,10 +26,7 @@
2626
import org.objectweb.asm.ClassReader;
2727
import org.objectweb.asm.tree.ClassNode;
2828

29-
import javax.swing.*;
3029
import java.awt.*;
31-
import java.awt.event.InputEvent;
32-
import java.awt.event.KeyEvent;
3330

3431
/**
3532
* @author Enaium

src/main/java/cn/enaium/joe/jar/Jar.java

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,10 @@
1616

1717
package cn.enaium.joe.jar;
1818

19-
import cn.enaium.joe.JavaOctetEditor;
20-
import cn.enaium.joe.config.extend.ApplicationConfig;
21-
import cn.enaium.joe.util.Util;
22-
import org.objectweb.asm.ClassReader;
2319
import org.objectweb.asm.tree.ClassNode;
2420

25-
import java.io.ByteArrayOutputStream;
26-
import java.io.File;
27-
import java.io.IOException;
28-
import java.io.InputStream;
29-
import java.util.Enumeration;
3021
import java.util.LinkedHashMap;
3122
import java.util.Map;
32-
import java.util.jar.JarEntry;
33-
import java.util.jar.JarFile;
3423

3524
/**
3625
* @author Enaium

src/main/java/cn/enaium/joe/task/AbstractTask.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
package cn.enaium.joe.task;
1818

19-
import java.util.concurrent.Callable;
2019
import java.util.function.Supplier;
2120

2221
/**
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package cn.enaium.joe.task;
2+
3+
import cn.enaium.joe.jar.Jar;
4+
import cn.enaium.joe.util.compiler.environment.RecompileEnvironment;
5+
6+
import java.util.Map;
7+
8+
public class BuildEnvironmentTask extends AbstractTask<Map<String, byte[]>> {
9+
Jar jar;
10+
public BuildEnvironmentTask(Jar jar) {
11+
super(" BuildEnvironment");
12+
this.jar = jar;
13+
}
14+
15+
@Override
16+
public Map<String, byte[]> get() {
17+
RecompileEnvironment.environment = RecompileEnvironment.build(jar, this::setProgress);
18+
this.setProgress(100);
19+
return RecompileEnvironment.getEnvironment();
20+
}
21+
}

src/main/java/cn/enaium/joe/task/InputJarTask.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ public Jar get() {
7272
JavaOctetEditor.getInstance().config.getByClass(ApplicationConfig.class).loadRecent.getValue().add(file.getAbsolutePath());
7373
JavaOctetEditor.getInstance().setJar(jar);
7474
JavaOctetEditor.getInstance().window.setTitle(JavaOctetEditor.TITLE + "-" + file.getName());
75+
76+
JavaOctetEditor.getInstance().task.submit(new BuildEnvironmentTask(jar));
77+
7578
return jar;
7679
}
7780
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package cn.enaium.joe.util.asm;
2+
3+
import org.objectweb.asm.ClassReader;
4+
import org.objectweb.asm.ClassVisitor;
5+
import org.objectweb.asm.ClassWriter;
6+
import org.objectweb.asm.Opcodes;
7+
8+
public class ClassVersionVisitor extends ClassVisitor {
9+
public final int version;
10+
public ClassVersionVisitor(int jdkVersion) {
11+
super(Opcodes.ASM9);
12+
this.version = jdkVersion;
13+
}
14+
15+
@Override
16+
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
17+
super.visit(this.version, access, name, signature, superName, interfaces);
18+
}
19+
20+
public static byte[] processVersion(byte[] clazz, int version){
21+
ClassReader classReader = new ClassReader(clazz);
22+
classReader.accept(new ClassVersionVisitor(version), 0);
23+
ClassWriter writer = new ClassWriter(classReader, 0);
24+
return writer.toByteArray();
25+
}
26+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package cn.enaium.joe.util.classes;
2+
3+
public class ASMClassLoader extends ClassLoader{
4+
public Class<?> defineClass(String canonicalName, byte[] clazz){
5+
return defineClass(canonicalName, clazz, 0, clazz.length);
6+
}
7+
8+
}

0 commit comments

Comments
 (0)