Skip to content

Commit acfd863

Browse files
committed
设置 javassist 为默认编译器
1 parent 258d01a commit acfd863

File tree

13 files changed

+230
-34
lines changed

13 files changed

+230
-34
lines changed

lts-admin/src/main/java/com/github/ltsopensource/admin/support/SystemInitListener.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import com.github.ltsopensource.core.commons.file.FileUtils;
44
import com.github.ltsopensource.core.commons.utils.PlatformUtils;
55
import com.github.ltsopensource.core.commons.utils.StringUtils;
6+
import com.github.ltsopensource.core.compiler.AbstractCompiler;
7+
import com.github.ltsopensource.core.constant.Constants;
68
import com.github.ltsopensource.core.json.JSONFactory;
79
import com.github.ltsopensource.core.logger.LoggerFactory;
810
import com.github.ltsopensource.core.spi.SpiExtensionKey;
@@ -26,6 +28,11 @@ public void contextInitialized(ServletContextEvent servletContextEvent) {
2628
}
2729
AppConfigurer.load(confPath);
2830

31+
String compiler = AppConfigurer.getProperty("configs." + Constants.COMPILER);
32+
if (StringUtils.isNotEmpty(compiler)) {
33+
AbstractCompiler.setCompiler(compiler);
34+
}
35+
2936
String jsonAdapter = AppConfigurer.getProperty("configs." + SpiExtensionKey.LTS_JSON);
3037
if (StringUtils.isNotEmpty(jsonAdapter)) {
3138
JSONFactory.setJSONAdapter(jsonAdapter);

lts-core/pom.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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/cluster/AbstractJobNode.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
import com.github.ltsopensource.core.commons.utils.GenericsUtils;
99
import com.github.ltsopensource.core.commons.utils.NetUtils;
1010
import com.github.ltsopensource.core.commons.utils.StringUtils;
11+
import com.github.ltsopensource.core.compiler.AbstractCompiler;
12+
import com.github.ltsopensource.core.constant.Constants;
1113
import com.github.ltsopensource.core.constant.EcTopic;
1214
import com.github.ltsopensource.core.factory.JobNodeConfigFactory;
1315
import com.github.ltsopensource.core.factory.NodeFactory;
@@ -140,6 +142,12 @@ public void destroy() {
140142
}
141143

142144
protected void initConfig() {
145+
146+
String compiler = config.getParameter(Constants.COMPILER);
147+
if (StringUtils.isNotEmpty(compiler)) {
148+
AbstractCompiler.setCompiler(compiler);
149+
}
150+
143151
appContext.setEventCenter(ServiceLoader.load(EventCenter.class, config));
144152

145153
appContext.setCommandBodyWrapper(new CommandBodyWrapper(config));

lts-core/src/main/java/com/github/ltsopensource/core/compiler/AbstractCompiler.java

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,33 @@
88

99
/**
1010
* @author william.liangf
11+
* @author Robert HG ([email protected]) on 9/12/15.
1112
*/
1213
public abstract class AbstractCompiler implements Compiler {
1314

15+
private static Compiler COMPILER = new JavassistCompiler();
16+
17+
public static void setCompiler(Compiler compiler) {
18+
if (compiler == null) {
19+
throw new IllegalArgumentException("compiler should not be null");
20+
}
21+
AbstractCompiler.COMPILER = compiler;
22+
}
23+
24+
public static Compiler getCompiler() {
25+
return AbstractCompiler.COMPILER;
26+
}
27+
28+
public static void setCompiler(String compiler) {
29+
if ("javassist".equals(compiler)) {
30+
setCompiler(new JavassistCompiler());
31+
} else if ("jdk".equals(compiler)) {
32+
setCompiler(new JdkCompiler());
33+
} else {
34+
throw new IllegalArgumentException("compiler[" + compiler +"] error ");
35+
}
36+
}
37+
1438
private static final Pattern PACKAGE_PATTERN = Pattern.compile("package\\s+([$_a-zA-Z][$_a-zA-Z0-9\\.]*);");
1539

1640
private static final Pattern CLASS_PATTERN = Pattern.compile("class\\s+([$_a-zA-Z][$_a-zA-Z0-9]*)\\s+");
@@ -36,18 +60,19 @@ public Class<?> compile(String code) {
3660
return Class.forName(className, true, ClassHelper.getCallerClassLoader(getClass()));
3761
} catch (ClassNotFoundException e) {
3862
if (!code.endsWith("}")) {
39-
throw new IllegalStateException("The java code not endsWith \"}\", code: \n" + code + "\n");
63+
throw new IllegalStateException("The java code not endsWith \"}\", code: " + code + "");
4064
}
4165
try {
4266
return doCompile(className, code);
4367
} catch (RuntimeException t) {
4468
throw t;
4569
} catch (Throwable t) {
46-
throw new IllegalStateException("Failed to compile class, cause: " + t.getMessage() + ", class: " + className + ", code: \n" + code + "\n, stack: " + StringUtils.toString(t));
70+
throw new IllegalStateException("Failed to compile class, cause: " + t.getMessage() + ", class: " + className + ", code: " + code + ", stack: " + StringUtils.toString(t));
4771
}
4872
}
4973
}
5074

5175
protected abstract Class<?> doCompile(String name, String source) throws Throwable;
76+
5277
}
5378

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
/*
2+
* Copyright 1999-2011 Alibaba Group.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.github.ltsopensource.core.compiler;
17+
18+
import com.github.ltsopensource.core.commons.utils.ClassHelper;
19+
import javassist.*;
20+
21+
import java.util.ArrayList;
22+
import java.util.HashMap;
23+
import java.util.List;
24+
import java.util.Map;
25+
import java.util.regex.Matcher;
26+
import java.util.regex.Pattern;
27+
28+
/**
29+
* @author william.liangf
30+
*/
31+
public class JavassistCompiler extends AbstractCompiler {
32+
33+
private static final Pattern IMPORT_PATTERN = Pattern.compile("import\\s+([\\w\\.\\*]+);\n");
34+
35+
private static final Pattern EXTENDS_PATTERN = Pattern.compile("\\s+extends\\s+([\\w\\.]+)[^\\{]*\\{\n");
36+
37+
private static final Pattern IMPLEMENTS_PATTERN = Pattern.compile("\\s+implements\\s+([\\w\\.]+)\\s*\\{\n");
38+
39+
private static final Pattern METHODS_PATTERN = Pattern.compile("\n(private|public|protected)\\s+");
40+
41+
private static final Pattern FIELD_PATTERN = Pattern.compile("[^\n]+=[^\n]+;");
42+
43+
@Override
44+
public Class<?> doCompile(String name, String source) throws Throwable {
45+
int i = name.lastIndexOf('.');
46+
String className = i < 0 ? name : name.substring(i + 1);
47+
ClassPool pool = new ClassPool(true);
48+
pool.appendClassPath(new LoaderClassPath(ClassHelper.getCallerClassLoader(getClass())));
49+
Matcher matcher = IMPORT_PATTERN.matcher(source);
50+
List<String> importPackages = new ArrayList<String>();
51+
Map<String, String> fullNames = new HashMap<String, String>();
52+
while (matcher.find()) {
53+
String pkg = matcher.group(1);
54+
if (pkg.endsWith(".*")) {
55+
String pkgName = pkg.substring(0, pkg.length() - 2);
56+
pool.importPackage(pkgName);
57+
importPackages.add(pkgName);
58+
} else {
59+
int pi = pkg.lastIndexOf('.');
60+
if (pi > 0) {
61+
String pkgName = pkg.substring(0, pi);
62+
pool.importPackage(pkgName);
63+
importPackages.add(pkgName);
64+
fullNames.put(pkg.substring(pi + 1), pkg);
65+
}
66+
}
67+
}
68+
String[] packages = importPackages.toArray(new String[importPackages.size()]);
69+
matcher = EXTENDS_PATTERN.matcher(source);
70+
CtClass cls;
71+
if (matcher.find()) {
72+
String extend = matcher.group(1).trim();
73+
String extendClass;
74+
if (extend.contains(".")) {
75+
extendClass = extend;
76+
} else if (fullNames.containsKey(extend)) {
77+
extendClass = fullNames.get(extend);
78+
} else {
79+
extendClass = ClassHelper.forName(packages, extend).getName();
80+
}
81+
cls = pool.makeClass(name, pool.get(extendClass));
82+
} else {
83+
cls = pool.makeClass(name);
84+
}
85+
matcher = IMPLEMENTS_PATTERN.matcher(source);
86+
if (matcher.find()) {
87+
String[] ifaces = matcher.group(1).trim().split("\\,");
88+
for (String iface : ifaces) {
89+
iface = iface.trim();
90+
String ifaceClass;
91+
if (iface.contains(".")) {
92+
ifaceClass = iface;
93+
} else if (fullNames.containsKey(iface)) {
94+
ifaceClass = fullNames.get(iface);
95+
} else {
96+
ifaceClass = ClassHelper.forName(packages, iface).getName();
97+
}
98+
cls.addInterface(pool.get(ifaceClass));
99+
}
100+
}
101+
String body = source.substring(source.indexOf("{") + 1, source.length() - 1);
102+
String[] methods = METHODS_PATTERN.split(body);
103+
for (String method : methods) {
104+
method = method.trim();
105+
if (method.length() > 0) {
106+
if (method.startsWith(className)) {
107+
cls.addConstructor(CtNewConstructor.make("public " + method, cls));
108+
} else if (FIELD_PATTERN.matcher(method).matches()) {
109+
cls.addField(CtField.make("private " + method, cls));
110+
} else {
111+
cls.addMethod(CtNewMethod.make(method, cls));
112+
}
113+
}
114+
}
115+
return cls.toClass(ClassHelper.getCallerClassLoader(getClass()), JavassistCompiler.class.getProtectionDomain());
116+
}
117+
118+
}

lts-core/src/main/java/com/github/ltsopensource/core/compiler/JdkCompiler.java

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
package com.github.ltsopensource.core.compiler;
22

33
import com.github.ltsopensource.core.commons.utils.ClassHelper;
4+
import com.github.ltsopensource.core.logger.LoggerFactory;
45

56
import javax.tools.*;
67
import java.io.*;
7-
import java.lang.reflect.Method;
88
import java.net.URI;
99
import java.net.URISyntaxException;
1010
import java.net.URL;
@@ -18,7 +18,7 @@ public class JdkCompiler extends AbstractCompiler {
1818
public static final String CLASS_EXTENSION = ".class";
1919
public static final String JAVA_EXTENSION = ".java";
2020

21-
private JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
21+
private final JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
2222

2323
private final DiagnosticCollector<JavaFileObject> diagnosticCollector = new DiagnosticCollector<JavaFileObject>();
2424

@@ -30,13 +30,9 @@ public class JdkCompiler extends AbstractCompiler {
3030

3131
public JdkCompiler() {
3232
if (compiler == null) {
33-
try {
34-
Class<?> javacTool = Class.forName("com.sun.tools.javac.api.JavacTool");
35-
Method create = javacTool.getMethod("create");
36-
compiler = (JavaCompiler) create.invoke(null);
37-
} catch (Exception e) {
38-
throw new AssertionError(e);
39-
}
33+
throw new IllegalStateException(
34+
"Cannot find the system Java compiler. "
35+
+ "Check that your class path includes tools.jar");
4036
}
4137
options = new ArrayList<String>();
4238
// options.add("-target");

lts-core/src/main/java/com/github/ltsopensource/core/constant/Constants.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ public interface Constants {
6969
String PROCESSOR_THREAD = "job.processor.thread";
7070
int DEFAULT_PROCESSOR_THREAD = 32 + AVAILABLE_PROCESSOR * 5;
7171

72-
int LATCH_TIMEOUT_MILLIS = 60 * 1000; // 60s
72+
int LATCH_TIMEOUT_MILLIS = 60 * 1000; // 60s
7373

7474
// 任务最多重试次数
7575
String JOB_MAX_RETRY_TIMES = "job.max.retry.times";
@@ -114,4 +114,6 @@ public interface Constants {
114114
String ONCE = "__LTS_ONCE";
115115

116116
String IS_RETRY_JOB = "__LTS_Is_Retry_Job";
117+
118+
String COMPILER = "java.compiler";
117119
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.github.ltsopensource.core.support.bean;
2+
3+
/**
4+
* @author Robert HG ([email protected]) on 4/17/16.
5+
*/
6+
public abstract class BeanCopierAdapter implements BeanCopier<Object, Object> {
7+
8+
public abstract void copyProps(Object sourceObj, Object targetObj);
9+
}

0 commit comments

Comments
 (0)