2

I have my datasource configured in tomcat\context.xml. I have deployed a bridge.war provided by Eclipse to get servletbridge environment.

I have developed another osgi bundle which contains servlet registation code and my aim is to do JNDI look up for datasource from this servlet bundle.

However I get

javax.naming.NoInitialContextException:Cannot instantiate class: org.apache.naming.java.javaURLContextFactory (root cause classnotfound for org.apache.naming.java.javaURLContextFactory)

when I try following code in my OSGI bundle

        Context initContext = new InitialContext();
        Context envContext = (Context) initContext.lookup("java:/comp/env");
        DataSource ds = (DataSource) envContext.lookup("jdbc/TestDB");

I have added catalina.jar in my osgi container an also as a dependency in my osgi bundle.

My launch.ini of bridge.war looks like this:

osgi.*=@null
org.osgi.*=@null
eclipse.*=@null

osgi.parentClassloader=ext
osgi.contextClassLoaderParent=ext
org.osgi.framework.system.packages.extra=org.apache.naming.java

Can someone help me with it?

WillMcavoy
  • 1,795
  • 4
  • 22
  • 34
  • Try adding org.osgi.framework.system.packages.extra=org.apache.naming.java to launch.ini in the war. I have never tried this bridge but havin a one minute look into the war, I think this will solve your problem. If yes, I will make an answer from the comment. – Balazs Zsoldos Jul 24 '14 at 20:25
  • Nope.I am still having the same issue after trying that.Do you suggest adding any other jar? – WillMcavoy Jul 24 '14 at 20:39
  • This one can be relevant: http://wiki.eclipse.org/FAQ_How_do_I_add_a_library_to_the_classpath_of_a_plug-in%3F. The parent classloader is ext that does not contain the required package. You can try playing around with the other classloaders like app or fwk. They say: "This is also generally a bad idea", however, I do not think you can access the JNDI of Tomcat otherwise. Please note again, that this is only a tip, not the solution that was tried by myself. – Balazs Zsoldos Jul 24 '14 at 21:08
  • And it worked when I changed the classloader to fwk.Thank you so much!! – WillMcavoy Jul 25 '14 at 03:24
  • I made an answer from it. – Balazs Zsoldos Jul 25 '14 at 08:43

1 Answers1

2

The parent of the embedded OSGi container is ext: The Java extension class loader

To be able to see the classes of Tomcat, the parent classloader must be changed in launch.ini to fwk: The OSGi framework class loader.

By doing that, the parent classloader of the embedded OSGi container be the classloader of the web application. If a bundle in the embedded OSGi container wants to use a class from the webapp or Tomcat directly, you might have to list the package of the class with org.osgi.system.packages.extra setting.

More information about parent classloaders of embedded Equinox: http://wiki.eclipse.org/FAQ_How_do_I_add_a_library_to_the_classpath_of_a_plug-in%3F

More information about the class loader hierarchy of Tomcat: http://tomcat.apache.org/tomcat-6.0-doc/class-loader-howto.html

Balazs Zsoldos
  • 6,036
  • 2
  • 23
  • 31
  • Hi,I read through the link you have provided but could not get how exactly "fwk" makes it work? I mean as per the link its classpath is not strictly specified.Could you help me understand that? – WillMcavoy Jul 28 '14 at 18:31
  • 1
    If you use 'ext', the parent classloader of your OSGi framework will be the ext classloader of JDK that does not see the JNDI implementation. If you use 'fwk', the parent classloader the parent classloader of the system bundle will be the classloader of the webapp. All packages that do not come from bundles (e.g. JNDI API) come from the system bundle. The system bundle sees the JNDI Tomcat impl even if it does not export the packages of it. – Balazs Zsoldos Jul 29 '14 at 11:31
  • i changed mine to ccl and it works.. could you explain this to me? – Khan Jul 03 '17 at 08:02
  • 1
    ccl means: "ccl - the original context classloader that was set when the framework launched". In your case, I guess the thread context classloader that is used when the OSGi container starts is the classloader is the classloader of the webapp, so that can work, too. – Balazs Zsoldos Jul 03 '17 at 12:22