Skip to content

Commit 97843f0

Browse files
committed
OpenHFT#22 remove states cshared between cached compiler instances.
1 parent b95df7b commit 97843f0

5 files changed

Lines changed: 53 additions & 25 deletions

File tree

compiler/pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727

2828
<modelVersion>4.0.0</modelVersion>
2929
<artifactId>compiler</artifactId>
30-
<version>2.2.6-SNAPSHOT</version>
30+
<version>2.3.0-SNAPSHOT</version>
3131
<packaging>bundle</packaging>
3232

3333
<name>OpenHFT/Java-Runtime-Compiler</name>
@@ -40,7 +40,7 @@
4040
<groupId>net.openhft</groupId>
4141
<artifactId>third-party-bom</artifactId>
4242
<type>pom</type>
43-
<version>3.5.1</version>
43+
<version>3.5.6</version>
4444
<scope>import</scope>
4545
</dependency>
4646

compiler/src/main/java/net/openhft/compiler/CachedCompiler.java

100644100755
Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -26,24 +26,23 @@
2626
import javax.tools.Diagnostic;
2727
import javax.tools.DiagnosticListener;
2828
import javax.tools.JavaFileObject;
29+
import javax.tools.StandardJavaFileManager;
30+
import java.io.Closeable;
2931
import java.io.File;
3032
import java.io.IOException;
3133
import java.io.PrintWriter;
32-
import java.util.Collections;
33-
import java.util.HashMap;
34-
import java.util.LinkedHashMap;
35-
import java.util.Map;
36-
import java.util.WeakHashMap;
34+
import java.util.*;
3735

38-
import static net.openhft.compiler.CompilerUtils.writeBytes;
39-
import static net.openhft.compiler.CompilerUtils.writeText;
36+
import static net.openhft.compiler.CompilerUtils.*;
4037

4138
@SuppressWarnings("StaticNonFinalField")
42-
public class CachedCompiler {
39+
public class CachedCompiler implements Closeable {
4340
private static final Logger LOG = LoggerFactory.getLogger(CachedCompiler.class);
44-
private static final Map<ClassLoader, Map<String, Class>> loadedClassesMap = new WeakHashMap<ClassLoader, Map<String, Class>>();
4541
private static final PrintWriter DEFAULT_WRITER = new PrintWriter(System.err);
4642

43+
private final Map<ClassLoader, Map<String, Class>> loadedClassesMap = Collections.synchronizedMap(new WeakHashMap<ClassLoader, Map<String, Class>>());
44+
private final Map<ClassLoader, MyJavaFileManager> fileManagerMap = Collections.synchronizedMap(new WeakHashMap<ClassLoader, MyJavaFileManager>());
45+
4746
@Nullable
4847
private final File sourceDir;
4948
@Nullable
@@ -57,9 +56,11 @@ public CachedCompiler(@Nullable File sourceDir, @Nullable File classDir) {
5756
this.classDir = classDir;
5857
}
5958

60-
public static void close() {
59+
public void close() {
6160
try {
62-
CompilerUtils.s_fileManager.close();
61+
for (MyJavaFileManager fileManager : fileManagerMap.values()) {
62+
fileManager.close();
63+
}
6364
} catch (IOException e) {
6465
throw new AssertionError(e);
6566
}
@@ -76,35 +77,36 @@ public Class loadFromJava(@NotNull ClassLoader classLoader,
7677
}
7778

7879
@NotNull
79-
Map<String, byte[]> compileFromJava(@NotNull String className, @NotNull String javaCode) {
80-
return compileFromJava(className, javaCode, DEFAULT_WRITER);
80+
Map<String, byte[]> compileFromJava(@NotNull String className, @NotNull String javaCode, MyJavaFileManager fileManager) {
81+
return compileFromJava(className, javaCode, DEFAULT_WRITER, fileManager);
8182
}
8283

8384
@NotNull
8485
Map<String, byte[]> compileFromJava(@NotNull String className,
8586
@NotNull String javaCode,
86-
final @NotNull PrintWriter writer) {
87+
final @NotNull PrintWriter writer,
88+
MyJavaFileManager fileManager) {
8789
Iterable<? extends JavaFileObject> compilationUnits;
8890
if (sourceDir != null) {
8991
String filename = className.replaceAll("\\.", '\\' + File.separator) + ".java";
9092
File file = new File(sourceDir, filename);
9193
writeText(file, javaCode);
92-
compilationUnits = CompilerUtils.s_standardJavaFileManager.getJavaFileObjects(file);
94+
compilationUnits = s_standardJavaFileManager.getJavaFileObjects(file);
9395

9496
} else {
9597
javaFileObjects.put(className, new JavaSourceFromString(className, javaCode));
9698
compilationUnits = javaFileObjects.values();
9799
}
98100
// reuse the same file manager to allow caching of jar files
99-
boolean ok = CompilerUtils.s_compiler.getTask(writer, CompilerUtils.s_fileManager, new DiagnosticListener<JavaFileObject>() {
101+
boolean ok = s_compiler.getTask(writer, fileManager, new DiagnosticListener<JavaFileObject>() {
100102
@Override
101103
public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
102104
if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
103105
writer.println(diagnostic);
104106
}
105107
}
106108
}, null, null, compilationUnits).call();
107-
Map<String, byte[]> result = CompilerUtils.s_fileManager.getAllBuffers();
109+
Map<String, byte[]> result = fileManager.getAllBuffers();
108110
if (!ok) {
109111
// compilation error, so we want to exclude this file from future compilation passes
110112
if (sourceDir == null)
@@ -132,7 +134,13 @@ public Class loadFromJava(@NotNull ClassLoader classLoader,
132134
PrintWriter printWriter = (writer == null ? DEFAULT_WRITER : writer);
133135
if (clazz != null)
134136
return clazz;
135-
for (Map.Entry<String, byte[]> entry : compileFromJava(className, javaCode, printWriter).entrySet()) {
137+
138+
MyJavaFileManager fileManager = fileManagerMap.get(classLoader);
139+
if (fileManager == null) {
140+
StandardJavaFileManager standardJavaFileManager = s_compiler.getStandardFileManager(null, null, null);
141+
fileManagerMap.put(classLoader, fileManager = new MyJavaFileManager(standardJavaFileManager));
142+
}
143+
for (Map.Entry<String, byte[]> entry : compileFromJava(className, javaCode, printWriter, fileManager).entrySet()) {
136144
String className2 = entry.getKey();
137145
synchronized (loadedClassesMap) {
138146
if (loadedClasses.containsKey(className2))

compiler/src/main/java/net/openhft/compiler/CompilerUtils.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ public enum CompilerUtils {
4747
private static final String JAVA_CLASS_PATH = "java.class.path";
4848
static JavaCompiler s_compiler;
4949
static StandardJavaFileManager s_standardJavaFileManager;
50-
static MyJavaFileManager s_fileManager;
5150

5251
static {
5352
try {
@@ -78,9 +77,6 @@ private static void reset() {
7877
throw new AssertionError(e);
7978
}
8079
}
81-
82-
s_standardJavaFileManager = s_compiler.getStandardFileManager(null, null, null);
83-
s_fileManager = new MyJavaFileManager(s_standardJavaFileManager);
8480
}
8581

8682
/**

compiler/src/test/java/net/openhft/compiler/CompilerTest.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import eg.FooBarTee;
2222
import eg.components.Foo;
2323
import junit.framework.TestCase;
24+
import org.junit.Test;
2425

2526
import java.io.*;
2627
import java.lang.reflect.Constructor;
@@ -107,7 +108,9 @@ public static void test_compiler() throws ClassNotFoundException {
107108
assertEquals(text, foo.s);
108109
}
109110

110-
public void test_fromFile() throws ClassNotFoundException, IOException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
111+
public void test_fromFile()
112+
throws ClassNotFoundException, IOException, IllegalAccessException, InstantiationException,
113+
NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
111114
Class clazz = CompilerUtils.loadFromResource("eg.FooBarTee2", "eg/FooBarTee2.jcf");
112115
// turn off System.out
113116
PrintStream out = System.out;
@@ -281,4 +284,17 @@ public void test_compilerErrorsDoNotBreakNextCompilations() throws Exception {
281284
assertEquals("ok", callable.call());
282285
}
283286

287+
@Test
288+
public void testNewCompiler() throws ClassNotFoundException, IllegalAccessException, InstantiationException {
289+
for (int i = 1; i <= 3; i++) {
290+
ClassLoader classLoader = new ClassLoader() {
291+
};
292+
CachedCompiler cc = new CachedCompiler(null, null);
293+
Class a = cc.loadFromJava(classLoader, "A", "public class A { static int i = " + i + "; }");
294+
Class b = cc.loadFromJava(classLoader, "B", "public class B implements net.openhft.compiler.MyIntSupplier { public int get() { return A.i; } }");
295+
MyIntSupplier bi = (MyIntSupplier) b.newInstance();
296+
assertEquals(i, bi.get());
297+
}
298+
}
284299
}
300+
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package net.openhft.compiler;
2+
3+
/**
4+
* Created by peter on 31/12/2016.
5+
*/
6+
public interface MyIntSupplier {
7+
public int get();
8+
}

0 commit comments

Comments
 (0)