Problem instantiating RemoteServices
Inside a native thread (C DLL) I attach to a previously created JavaVM (JNI AttachCurrentThread). Afterwards, I call a static method of a Java class which attempts to establish a Documentum connection via DFS. The call to "ServiceFactory.getRemoteService" fails with a NullPointerException. Here is the stack trace:
at javax.xml.bind.ContextFinder.find(Unknown Source)
at javax.xml.bind.JAXBContext.newInstance(Unknown Source)
at javax.xml.bind.JAXBContext.newInstance(Unknown Source)
at javax.xml.bind.JAXBContext.newInstance(Unknown Source)
at com.emc.documentum.fs.rt.impl.servicemodel.JavaBeanTreeFactory.getModuleByName(JavaBeanTreeFactory.java:70)
at com.emc.documentum.fs.rt.impl.servicemodel.JavaBeanTreeFactory.getModule(JavaBeanTreeFactory.java:42)
at com.emc.documentum.fs.rt.context.ServiceFactory.makeServiceUrl(ServiceFactory.java:286)
at com.emc.documentum.fs.rt.context.ServiceFactory.getRemoteService(ServiceFactory.java:139)
at com.think_e_solutions.application.documentdirectory.repository.documentum.dfs.Docbase.connect(Docbase.java:224)
If the same method is run from Java directly, i. e. without being triggered by a native thread, everything works fine.
I have attached two DFS trace files (client side) - one which is the result of a successful service instantiation, the other one which results from a failure.
===== SOLVED =====
Fortunately, I could solve this issue myself. Here are the details of the solution:
The JavaVM is created from within a native thread that has no kind of "relation" with a JavaVM other than the one it just created. Therefore, the created Java thread and all the classes instantiated within that thread have the JavaVM's bootstrap class loader assigned as their current context class loader. This bootstrap class loader does not have any notion of a classpath other than the one required to bootstrap the JavaVM. It therefore - in my special case - fails to load resources (e.g. calling getResourceAsStream(String)) from the applications jar files. It won't be able to find the dfs-client.xml file either, regardless where its located.
To solve this type of issue, simply add the following line of code as the very first statement of your Java code (inside the first method) that get's called by the native thread:
Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
This statement will ensure that the current thread gets a proper context class loader assigned.
I leave the attachments attached to this discussion as a reference.
Hope this is helpful and I can avoid that others have to go through the same pain that I went through analyzing this problem ;-)
Categories
- All Categories
- 122 Developer Announcements
- 52 Articles
- 148 General Questions
- 146 Thrust Services
- 56 OpenText Hackathon
- 35 Developer Tools
- 20.6K Analytics
- 4.2K AppWorks
- 9K Extended ECM
- 917 Cloud Fax and Notifications
- 83 Digital Asset Management
- 9.4K Documentum
- 30 eDOCS
- 178 Exstream
- 39.8K TeamSite
- 1.7K Web Experience Management
- 7 XM Fax
- Follow Categories