ClassLoader [message #899590] |
Wed, 01 August 2012 14:18  |
Eclipse User |
|
|
|
Hi,
I have a question about ClassLoader in WindowBuilder.
In ParseFactory, when we initialize classLoader (initializeClassLoader(AstEditor editor)), we get new ClassLoader each time we refresh our design page.
My problem it's, apparently, old classLoader is never kill and I load dll library in my ClassLoader but library cannot be load if it is already load in another classLoader..
Quote:Native Library XXX already loaded in another classloader
I create my toolkit based on windowBuilder for personal jar library. But this jar library depend of native method, so I use JNI and I have a dll to load it in my ClassLoader.
So I want to know If I can kill old ClassLoader or how can I load my dll?
Thanks
|
|
|
Re: ClassLoader [message #899624 is a reply to message #899590] |
Wed, 01 August 2012 15:41   |
Eclipse User |
|
|
|
Can you make sure that JVM does allow you to load native library second time, i.e.
1. Create ClassLoader with class which uses native library;
2. Create some instance which uses it;
3. Lose reference on this instance;
4. Try to create same ClassLoader second time and repeat steps above.
I'm not sure if this is bug in WindowBuilder (holding reference on ClassLoader, kind of leak) or feature of specific JVM implementation, like:
1. Don't allow to do this at all.
2. Don't allow to do this when ClassLoader could be disposed and native library unloaded, but this is not done because GC was not yet performed.
|
|
|
Re: ClassLoader [message #899736 is a reply to message #899624] |
Thu, 02 August 2012 07:18   |
Eclipse User |
|
|
|
Hi and thanks to your answer,
Quote:Can you make sure that JVM does allow you to load native library second time, i.e.
No we cannot, that's why I tried to kill old classLoader before.
Quote:I'm not sure if this is bug in WindowBuilder (holding reference on ClassLoader, kind of leak) or feature of specific JVM implementation, like:
1. Don't allow to do this at all.
2. Don't allow to do this when ClassLoader could be disposed and native library unloaded, but this is not done because GC was not yet performed.
Actually, JVM implementation does not allow to unload library or kill classLoader. We have to create a custom classLoader with specific class who call native method put our classLoader to "null" and call GC. After that we can load a second time our library.
But this don't work because in parseFactory we have only a reference of our classLoader so classLoader is not really null and GC don't work.
|
|
|
Re: ClassLoader [message #899749 is a reply to message #899736] |
Thu, 02 August 2012 08:03   |
Eclipse User |
|
|
|
user Kyle wrote on Thu, 02 August 2012 03:18
Actually, JVM implementation does not allow to unload library or kill classLoader. We have to create a custom classLoader with specific class who call native method put our classLoader to "null" and call GC. After that we can load a second time our library.
But this don't work because in parseFactory we have only a reference of our classLoader so classLoader is not really null and GC don't work.
I'm not quite understand what you mean in the last sentence, but in general you are right.
We actually do something like this for eSWT - create ClassLoader with natives only one time.
See org.eclipse.wb.internal.rcp.parser.ParseFactory.initializeClassLoader_parent() or org.eclipse.wb.internal.ercp.parser.ParseFactory.initializeClassLoader_parent().
It seems (I've not tested this) that you could subclass RCP or Swing (I'm not sure what toolkit you use) ParseFactory, override initializeClassLoader_parent() and provide this ParseFactory using plugin.xml
<extension point="org.eclipse.wb.core.parseFactories">
<factory class="org.eclipse.wb.internal.swing.parser.ParseFactory"/>
</extension>
Probably with "priority="1" to use your ParseFactory before default.
Hm...
Actually there is some implementation in org.eclipse.wb.internal.core.parser.AbstractParseFactory.initializeClassLoader_parent(), it allows to mix Bundle ClassLoader into "parent". For example in MigLayout support we do this to ensure that classes in Design ClassLoader are the same as in WindowBuilder plugin (just to avoid reflection).
Here is part of plugin.xml, interesting element is "classLoader-bundle".
Namespaces and prefixes - optimizations.
<!-- ======================================================== -->
<!-- Toolkit -->
<!-- ======================================================== -->
<extension point="org.eclipse.wb.core.toolkits">
<toolkit id="org.eclipse.wb.swing">
<resourcePrefixes>
<resourcePrefix>net.miginfocom.</resourcePrefix>
</resourcePrefixes>
<classLoader-bundle bundle="org.eclipse.wb.swing.MigLayout.lib"
namespaces="net.miginfocom"/>
<palette>
<component class="net.miginfocom.swing.MigLayout"
category="org.eclipse.wb.swing.layouts">
<library type="net.miginfocom.swing.MigLayout"
bundle="org.eclipse.wb.swing.MigLayout.lib" jar="miglayout15-swing.jar"
src="miglayout-src.zip"/>
</component>
</palette>
</toolkit>
</extension>
|
|
|
Re: ClassLoader [message #899769 is a reply to message #899749] |
Thu, 02 August 2012 09:47  |
Eclipse User |
|
|
|
Thanks a lot,
I saw on org.eclipse.wb.internal.rcp.parser.ParseFactory.initializeClassLoader_parent() source code and I add to parentClassLoader a bundle who load my library and it's work 
@Override
protected void initializeClassLoader_parent(AstEditor editor,
CompositeClassLoader parentClassLoader) throws Exception {
parentClassLoader.add(new BundleClassLoader("myBundle"), null);
}
|
|
|
Powered by
FUDForum. Page generated in 0.25016 seconds