|Setting the classpath for Java scripting engine [message #533986]
||Mon, 17 May 2010 15:56
| Stefan Reinhold
Registered: May 2010
I'm trying to create a scripted Java class in an Eclipse RCP application.|
ScriptEngineManager sem = new ScriptEngineManager();
ScriptEngine javaEngine = sem.getEngineByName("java");
ScriptContext scriptContext = new SimpleScriptContext();
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
scriptContext.setAttribute("parentLoader", contextClassLoader, ScriptContext.ENGINE_SCOPE);
javaEngine.eval("some java class' source code");
The eval call fails with a ScriptException since classes referenced in import statements of the java source code can't be found.
I digged through the code and found that the classpath passed to the Java compiler is System.getProperty("java.class.path") with at runtime just contains " C:\Programme\IBM\RTC-2.0\eclipse\plugins\org.eclipse.equinox .launcher_1.0.201.R35x_v20090715.jar ".
When I try contextClassLoader.loadClass("importedClass") the class will be loaded sucessfully since it's plug-in is listed as a dependency of my plug-in.
How can I construct a (String) classpath to pass it to the Java compiler?
|Re: Setting the classpath for Java scripting engine [message #534131 is a reply to message #533997]
||Tue, 18 May 2010 08:11
| Stefan Reinhold
Registered: May 2010
Maybe I haven't been clear enough.|
- plug-in my.bundle.one containing class com.mycompany.bundleone.ClassA and exporting package com.mycompany.bundleone
- plug-in my.bundle.two containing class com.mycompany.bundletwo.ClassB and exporting package com.mycompany.bundletwo
- plug-in my.bundle.three containing classes com.mycompany.bundlethree.pkgone.ClassC and com.mycompany.bundlethree.pkgtwo.ScriptRunner and exporting packages com.mycompany.bundlethree.pkgone and com.mycompany.bundlethree.pkgtwo
Plug-in my.bundle.three's MANIFEST.MF states:
(scripting-libs/tools.jar is the JDK's tools.jar containing JavaC.)
Class com.mycompany.bundlethree.pkgtwo.ScriptRunner constructs the Java script engine and evaluates the scripted class as mentioned in my first post.
Loading class com.mycompany.bundleone.ClassA in com.mycompany.bundlethree.pkgtwo.ScriptRunner via Thread.currentThread().getContextClassLoader().loadClass(" com.mycompany.bundleone.ClassA"); returns a valid class object I can create an instance from.
My scripted java class I feed into javax.script.ScriptEngine.eval(String script) contains the import statements import com.mycompany.bundleone.ClassA; import com.mycompany.bundletwo.ClassB; import com.mycompany.bundlethree.pkgone.ClassC; which the compailer complains about stating package com.mycompany.bundleone does not exist, package com.mycompany.bundletwo does not exist, package com.mycompany.bundlethree.pkgone does not exist
Trying either value (except registered) of Eclipse-BuddyPolicy didn't help.
The Java script engine will parse the given script by feeding it into com.sun.script.java.JavaCompiler.compile(String fileName, String source, Writer err, String sourcePath, String classPath). So no classloader is being consulted. Instead I could pass a classpath string which defaults to the value of the system property "java.class.path".
So I would have to create a classpath from file URLs of the bundles plug-in my.bundle.three depends on.
How would this be possible?
|Re: Setting the classpath for Java scripting engine [message #534246 is a reply to message #534137]
||Tue, 18 May 2010 13:05
| Paul Webster
Registered: July 2009
Stefan Reinhold wrote:|
> Is it possible to convert the list of bundles my product consists of
> (osgi.bundles entry in config.ini) to a java classpath?
No, at least not easily. The problem: OSGi supports 2 mechanisms,
Require-Bundle and Import-Package.
Require-Bundle lets your bundle classloader "see" what those required
bundles export. The worst case: org.eclipse.ui, which re-exports
packages from swt, jface, the workbench, all different jars that you can
never find from your MANIFEST.MF
Import-Package allows your OSGi classloader to look up a Class from any
bundle in the system that exports the matching package ... sometimes,
multiple bundles export the same package (a split package :-)
If you are want to use your scripting engine against your 3 bundles, you
can probably hard-wire some classpath that will work reliably. The
general case would require the ability of the scripting engine to get
Class information from the scripting bundle's ClassLoader, where it is
extended by buddy classloading.
Option 2. Every bundle that wants to participate your scripting must
provide an extension of some kind that your scripting bundle can read.
You can use that information to construct a useful path for the
scripting engine. But that only works if everything needed for the
classpath can be deduced from the bundles contributiong extensions.
Powered by FUDForum
. Page generated in 0.08361 seconds