Skip to content

Commit 78c9258

Browse files
committed
1.6.8-SNAPSHOT 修改Compiler为javassist
1 parent 2b8dbe3 commit 78c9258

File tree

21 files changed

+279
-58
lines changed

21 files changed

+279
-58
lines changed

build.cmd

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ start mvn clean install -DskipTests
44
echo "LTS: mvn clean install -DskipTests"
55
echo "LTS: After sub window finished, close it , and press any key to continue" & pause>nul
66

7-
set VERSION=1.6.7
7+
set VERSION=1.6.8-SNAPSHOT
88
set BASE_HOME=%~dp0%
99
set DIST_BIN_DIR=lts-%VERSION%-bin
1010

build.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/usr/bin/env bash
22

3-
VERSION="1.6.7"
3+
VERSION="1.6.8-SNAPSHOT"
44

55
LTS_BIN="${BASH_SOURCE-$0}"
66
LTS_BIN="$(dirname "${LTS_BIN}")"

docs/osc&github同时推送数据.txt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,11 @@ git fetch github --tags
1919

2020
# 查询远程标签
2121
git ls-remote --tags osc
22-
git ls-remote --tags github
22+
git ls-remote --tags github
23+
24+
25+
26+
##
27+
~/Data/Software/apache-maven-3.2.5/bin/mvn clean install -U -DskipTests
28+
~/Data/Software/apache-maven-3.2.5/bin/mvn clean deploy -DskipTests
29+
~/Data/Software/apache-maven-3.2.5/bin/mvn clean deploy -P release -Dgpg.passphrase=密码 -DskipTests

lts-admin/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<parent>
66
<artifactId>lts-parent</artifactId>
77
<groupId>com.github.ltsopensource</groupId>
8-
<version>1.6.7</version>
8+
<version>1.6.8-SNAPSHOT</version>
99
</parent>
1010
<modelVersion>4.0.0</modelVersion>
1111
<packaging>war</packaging>

lts-core/pom.xml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<parent>
66
<artifactId>lts-parent</artifactId>
77
<groupId>com.github.ltsopensource</groupId>
8-
<version>1.6.7</version>
8+
<version>1.6.8-SNAPSHOT</version>
99
</parent>
1010
<modelVersion>4.0.0</modelVersion>
1111
<packaging>jar</packaging>
@@ -132,5 +132,9 @@
132132
<artifactId>mysql-connector-java</artifactId>
133133
<scope>provided</scope>
134134
</dependency>
135+
<dependency>
136+
<groupId>org.javassist</groupId>
137+
<artifactId>javassist</artifactId>
138+
</dependency>
135139
</dependencies>
136140
</project>

lts-core/src/main/java/com/github/ltsopensource/core/commons/utils/ClassHelper.java

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,75 @@ public static Class<?> forName(String name, ClassLoader classLoader)
117117
return classLoaderToUse.loadClass(name);
118118
}
119119

120+
public static Class<?> forName(String[] packages, String className) {
121+
try {
122+
return _forName(className);
123+
} catch (ClassNotFoundException e) {
124+
if (packages != null && packages.length > 0) {
125+
for (String pkg : packages) {
126+
try {
127+
return _forName(pkg + "." + className);
128+
} catch (ClassNotFoundException e2) {
129+
}
130+
}
131+
}
132+
throw new IllegalStateException(e.getMessage(), e);
133+
}
134+
}
135+
136+
public static Class<?> _forName(String className) throws ClassNotFoundException {
137+
if ("boolean".equals(className))
138+
return boolean.class;
139+
if ("byte".equals(className))
140+
return byte.class;
141+
if ("char".equals(className))
142+
return char.class;
143+
if ("short".equals(className))
144+
return short.class;
145+
if ("int".equals(className))
146+
return int.class;
147+
if ("long".equals(className))
148+
return long.class;
149+
if ("float".equals(className))
150+
return float.class;
151+
if ("double".equals(className))
152+
return double.class;
153+
if ("boolean[]".equals(className))
154+
return boolean[].class;
155+
if ("byte[]".equals(className))
156+
return byte[].class;
157+
if ("char[]".equals(className))
158+
return char[].class;
159+
if ("short[]".equals(className))
160+
return short[].class;
161+
if ("int[]".equals(className))
162+
return int[].class;
163+
if ("long[]".equals(className))
164+
return long[].class;
165+
if ("float[]".equals(className))
166+
return float[].class;
167+
if ("double[]".equals(className))
168+
return double[].class;
169+
try {
170+
return arrayForName(className);
171+
} catch (ClassNotFoundException e) {
172+
if (className.indexOf('.') == -1) { // 尝试java.lang包
173+
try {
174+
return arrayForName("java.lang." + className);
175+
} catch (ClassNotFoundException e2) {
176+
// 忽略尝试异常, 抛出原始异常
177+
}
178+
}
179+
throw e;
180+
}
181+
}
182+
183+
private static Class<?> arrayForName(String className) throws ClassNotFoundException {
184+
return Class.forName(className.endsWith("[]")
185+
? "[L" + className.substring(0, className.length() - 2) + ";"
186+
: className, true, Thread.currentThread().getContextClassLoader());
187+
}
188+
120189
/**
121190
* Resolve the given class name as primitive class, if appropriate,
122191
* according to the JVM's naming rules for primitive classes.
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package com.github.ltsopensource.core.compiler;
2+
3+
import com.github.ltsopensource.core.commons.utils.ClassHelper;
4+
import com.github.ltsopensource.core.commons.utils.StringUtils;
5+
6+
import java.util.regex.Matcher;
7+
import java.util.regex.Pattern;
8+
9+
/**
10+
* @author william.liangf
11+
*/
12+
public abstract class AbstractCompiler implements Compiler {
13+
14+
private static final Pattern PACKAGE_PATTERN = Pattern.compile("package\\s+([$_a-zA-Z][$_a-zA-Z0-9\\.]*);");
15+
16+
private static final Pattern CLASS_PATTERN = Pattern.compile("class\\s+([$_a-zA-Z][$_a-zA-Z0-9]*)\\s+");
17+
18+
public Class<?> compile(String code) {
19+
code = code.trim();
20+
Matcher matcher = PACKAGE_PATTERN.matcher(code);
21+
String pkg;
22+
if (matcher.find()) {
23+
pkg = matcher.group(1);
24+
} else {
25+
pkg = "";
26+
}
27+
matcher = CLASS_PATTERN.matcher(code);
28+
String cls;
29+
if (matcher.find()) {
30+
cls = matcher.group(1);
31+
} else {
32+
throw new IllegalArgumentException("No such class name in " + code);
33+
}
34+
String className = pkg != null && pkg.length() > 0 ? pkg + "." + cls : cls;
35+
try {
36+
return Class.forName(className, true, ClassHelper.getCallerClassLoader(getClass()));
37+
} catch (ClassNotFoundException e) {
38+
if (!code.endsWith("}")) {
39+
throw new IllegalStateException("The java code not endsWith \"}\", code: \n" + code + "\n");
40+
}
41+
try {
42+
return doCompile(className, code);
43+
} catch (RuntimeException t) {
44+
throw t;
45+
} catch (Throwable t) {
46+
throw new IllegalStateException("Failed to compile class, cause: " + t.getMessage() + ", class: " + className + ", code: \n" + code + "\n, stack: " + StringUtils.toString(t));
47+
}
48+
}
49+
}
50+
51+
protected abstract Class<?> doCompile(String name, String source) throws Throwable;
52+
53+
}
54+
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package com.github.ltsopensource.core.compiler;
2+
3+
public interface Compiler {
4+
5+
Class<?> compile(String code);
6+
7+
}
8+
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
package com.github.ltsopensource.core.compiler;
2+
3+
import com.github.ltsopensource.core.commons.utils.ClassHelper;
4+
import javassist.*;
5+
6+
import java.util.ArrayList;
7+
import java.util.HashMap;
8+
import java.util.List;
9+
import java.util.Map;
10+
import java.util.regex.Matcher;
11+
import java.util.regex.Pattern;
12+
13+
/**
14+
* @author william.liangf
15+
*/
16+
public class JavassistCompiler extends AbstractCompiler {
17+
18+
private static final Pattern IMPORT_PATTERN = Pattern.compile("import\\s+([\\w\\.\\*]+);\n");
19+
20+
private static final Pattern EXTENDS_PATTERN = Pattern.compile("\\s+extends\\s+([\\w\\.]+)[^\\{]*\\{\n");
21+
22+
private static final Pattern IMPLEMENTS_PATTERN = Pattern.compile("\\s+implements\\s+([\\w\\.]+)\\s*\\{\n");
23+
24+
private static final Pattern METHODS_PATTERN = Pattern.compile("\n(private|public|protected)\\s+");
25+
26+
private static final Pattern FIELD_PATTERN = Pattern.compile("[^\n]+=[^\n]+;");
27+
28+
@Override
29+
public Class<?> doCompile(String name, String source) throws Throwable {
30+
int i = name.lastIndexOf('.');
31+
String className = i < 0 ? name : name.substring(i + 1);
32+
ClassPool pool = new ClassPool(true);
33+
pool.appendClassPath(new LoaderClassPath(ClassHelper.getCallerClassLoader(getClass())));
34+
Matcher matcher = IMPORT_PATTERN.matcher(source);
35+
List<String> importPackages = new ArrayList<String>();
36+
Map<String, String> fullNames = new HashMap<String, String>();
37+
while (matcher.find()) {
38+
String pkg = matcher.group(1);
39+
if (pkg.endsWith(".*")) {
40+
String pkgName = pkg.substring(0, pkg.length() - 2);
41+
pool.importPackage(pkgName);
42+
importPackages.add(pkgName);
43+
} else {
44+
int pi = pkg.lastIndexOf('.');
45+
if (pi > 0) {
46+
String pkgName = pkg.substring(0, pi);
47+
pool.importPackage(pkgName);
48+
importPackages.add(pkgName);
49+
fullNames.put(pkg.substring(pi + 1), pkg);
50+
}
51+
}
52+
}
53+
String[] packages = importPackages.toArray(new String[importPackages.size()]);
54+
matcher = EXTENDS_PATTERN.matcher(source);
55+
CtClass cls;
56+
if (matcher.find()) {
57+
String extend = matcher.group(1).trim();
58+
String extendClass;
59+
if (extend.contains(".")) {
60+
extendClass = extend;
61+
} else if (fullNames.containsKey(extend)) {
62+
extendClass = fullNames.get(extend);
63+
} else {
64+
extendClass = ClassHelper.forName(packages, extend).getName();
65+
}
66+
cls = pool.makeClass(name, pool.get(extendClass));
67+
} else {
68+
cls = pool.makeClass(name);
69+
}
70+
matcher = IMPLEMENTS_PATTERN.matcher(source);
71+
if (matcher.find()) {
72+
String[] ifaces = matcher.group(1).trim().split("\\,");
73+
for (String iface : ifaces) {
74+
iface = iface.trim();
75+
String ifaceClass;
76+
if (iface.contains(".")) {
77+
ifaceClass = iface;
78+
} else if (fullNames.containsKey(iface)) {
79+
ifaceClass = fullNames.get(iface);
80+
} else {
81+
ifaceClass = ClassHelper.forName(packages, iface).getName();
82+
}
83+
cls.addInterface(pool.get(ifaceClass));
84+
}
85+
}
86+
String body = source.substring(source.indexOf("{") + 1, source.length() - 1);
87+
String[] methods = METHODS_PATTERN.split(body);
88+
for (String method : methods) {
89+
method = method.trim();
90+
if (method.length() > 0) {
91+
if (method.startsWith(className)) {
92+
cls.addConstructor(CtNewConstructor.make("public " + method, cls));
93+
} else if (FIELD_PATTERN.matcher(method).matches()) {
94+
cls.addField(CtField.make("private " + method, cls));
95+
} else {
96+
cls.addMethod(CtNewMethod.make("public " + method, cls));
97+
}
98+
}
99+
}
100+
return cls.toClass(ClassHelper.getCallerClassLoader(getClass()), JavassistCompiler.class.getProtectionDomain());
101+
}
102+
103+
}

lts-core/src/main/java/com/github/ltsopensource/core/support/bean/JdkCompiler.java renamed to lts-core/src/main/java/com/github/ltsopensource/core/compiler/JdkCompiler.java

Lines changed: 2 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.github.ltsopensource.core.support.bean;
1+
package com.github.ltsopensource.core.compiler;
22

33
import com.github.ltsopensource.core.commons.utils.ClassHelper;
44

@@ -11,10 +11,8 @@
1111
import java.security.AccessController;
1212
import java.security.PrivilegedAction;
1313
import java.util.*;
14-
import java.util.regex.Matcher;
15-
import java.util.regex.Pattern;
1614

17-
public class JdkCompiler {
15+
public class JdkCompiler extends AbstractCompiler {
1816

1917
public static final String CLASS_EXTENSION = ".class";
2018
public static final String JAVA_EXTENSION = ".java";
@@ -61,43 +59,6 @@ public ClassLoaderImpl run() {
6159
javaFileManager = new JavaFileManagerImpl(manager, classLoader);
6260
}
6361

64-
private static final Pattern PACKAGE_PATTERN = Pattern.compile("package\\s+([$_a-zA-Z][$_a-zA-Z0-9\\.]*);");
65-
66-
private static final Pattern CLASS_PATTERN = Pattern.compile("class\\s+([$_a-zA-Z][$_a-zA-Z0-9]*)\\s+");
67-
68-
public Class<?> compile(String code) {
69-
code = code.trim();
70-
Matcher matcher = PACKAGE_PATTERN.matcher(code);
71-
String pkg;
72-
if (matcher.find()) {
73-
pkg = matcher.group(1);
74-
} else {
75-
pkg = "";
76-
}
77-
matcher = CLASS_PATTERN.matcher(code);
78-
String cls;
79-
if (matcher.find()) {
80-
cls = matcher.group(1);
81-
} else {
82-
throw new IllegalArgumentException("No such class name in " + code);
83-
}
84-
String className = pkg != null && pkg.length() > 0 ? pkg + "." + cls : cls;
85-
try {
86-
return Class.forName(className, true, ClassHelper.getCallerClassLoader(getClass()));
87-
} catch (ClassNotFoundException e) {
88-
if (!code.endsWith("}")) {
89-
throw new IllegalStateException("The java code not endsWith \"}\", code: \n" + code + "\n");
90-
}
91-
try {
92-
return doCompile(className, code);
93-
} catch (RuntimeException t) {
94-
throw t;
95-
} catch (Throwable t) {
96-
throw new IllegalStateException("Failed to compile class, cause: " + t.getMessage() + ", class: " + className + ", code: \n" + code + "\n", t);
97-
}
98-
}
99-
}
100-
10162
public Class<?> doCompile(String name, String sourceCode) throws Throwable {
10263
int i = name.lastIndexOf('.');
10364
String packageName = i < 0 ? "" : name.substring(0, i);

0 commit comments

Comments
 (0)