Closed tsdh closed 9 years ago
We never had this problem and the tested it on several systems.
However, I included the suggested change. But I am not sure if this solves the problem.
You never encountered this problem probably because you've never tested with solutions implemented in languages that rely on their own class loaders in order to dynamically load classes, e.g., solutions using Clojure, Scala, or Groovy.
But with the change, ARTE doesn't even start up anymore:
Exception in thread "main" java.lang.NoClassDefFoundError: org/eclipse/xtext/ISetup
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:760)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:467)
at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
at java.net.URLClassLoader$1.run(URLClassLoader.java:368)
at java.net.URLClassLoader$1.run(URLClassLoader.java:362)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:760)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:467)
at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
at java.net.URLClassLoader$1.run(URLClassLoader.java:368)
at java.net.URLClassLoader$1.run(URLClassLoader.java:362)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at arte.Arte.<init>(Arte.java:62)
at arte.Arte.main(Arte.java:88)
Caused by: java.lang.ClassNotFoundException: org.eclipse.xtext.ISetup
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 26 more
How about loading the TestInterface
implementation class with a custom classloader which tries to load it as before your last change, and if that doesn't work out try alternative classloaders. E.g., something like this:
public class FallbackClassLoader extends ClassLoader {
// ^^^^^^^^^^^
// Extend the ClassLoader class you are actually using.
private ClassLoader[] fallbacks;
public FallbackClassLoader(ClassLoader... fallbacks) {
this.fallbacks = fallbacks;
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
try {
return super.findClass(name);
} catch (ClassNotFoundException e) {
for (ClassLoader cl : fallbacks) {
try {
return cl.loadClass(name);
} catch (ClassNotFoundException e2) {}
}
throw e;
}
}
public static void main(String[] args) {
// Use it like so, e.g., use the current threads classloader as fallback
ClassLoader clForServiceLoader = new FallbackClassLoader(Thread
.currentThread().getContextClassLoader());
ServiceLoader<TestInterface> services = ServiceLoader.load(
TestInterface.class, clForServiceLoader);
}
}
Ups, command back. The error above happened with 5f613a8b573a8e4dd0ead764bf103e1b482177a1
. Now with 7d74786024b16c4a68a178d0cb4dd8c4a43ff65c
I'm back to the exception from my original report.
If you make the ARTE sources available to me, I'll try to fix it myself. Or alternatively, I can send you my solution JAR so that you can test yourself.
Ok, I'm marking this as done because I have found a way to set the right classloader from inside my solution. As a reference for others who might run into the same trouble, this is what I do in my TestInterface
implementation:
static {
Thread.currentThread().setContextClassLoader(TestInterfaceImpl.class.getClassLoader());
}
When I do
load --solution /home/horn/Repos/uni/ttc15-java-refactoring-funnyqt/target/ttc15-java-refactoring-funnyqt-0.1.0-SNAPSHOT-standalone.jar
in ARTE, I get the following exception:This looks exactly as discussed in http://blog.mattiasholmqvist.se/?p=631, so could you please make ARTE set the current thread's context class loader before calling
ServiceLoader.load()
?I'd do it myself and submit a patch if I could find the ARTE code somewhere which I don't.