6 Replies Latest reply on Jun 24, 2010 4:13 PM by 392 Guest

    Embed Apache Felix in a Web Application

    dboltri
      Hi all, I'm trying to develop an OSGI based WebApp embedding Apache Felix in it using Apache Felix Http Bridge to register a simple servlet. When deploying application on Glassfish V3 i get following exception when the bundle containing the servlet starts: [#|2010-06-22T17:07:07.281+0200|INFO|glassfish3.0.1|javax.enterprise.system.std.com.sun.enterprise.v3.services.impl|_ThreadID=39;_ThreadName=Thread-1;|org.osgi.framework.BundleException: Activator start error in bundle com.test.basic.servlet [10].      at org.apache.felix.framework.Felix.activateBundle(Felix.java:1751)      at org.apache.felix.framework.Felix.startBundle(Felix.java:1622)      at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:915)      at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:902)      at org.apache.felix.fileinstall.internal.DirectoryWatcher.start(DirectoryWatcher.java:1027)      at org.apache.felix.fileinstall.internal.DirectoryWatcher.start(DirectoryWatcher.java:1013)      at org.apache.felix.fileinstall.internal.DirectoryWatcher.startAllBundles(DirectoryWatcher.java:1006)      at org.apache.felix.fileinstall.internal.DirectoryWatcher.process(DirectoryWatcher.java:396)      at org.apache.felix.fileinstall.internal.DirectoryWatcher.run(DirectoryWatcher.java:206) Caused by: java.lang.NoClassDefFoundError: javax/servlet/Servlet      at java.lang.Class.getDeclaredConstructors0(Native Method)      at java.lang.Class.privateGetDeclaredConstructors(Class.java:2389)      at java.lang.Class.getConstructor0(Class.java:2699)      at java.lang.Class.newInstance0(Class.java:326)      at java.lang.Class.newInstance(Class.java:308)      at org.apache.felix.framework.Felix.createBundleActivator(Felix.java:3520)      at org.apache.felix.framework.Felix.activateBundle(Felix.java:1695)      ... 8 more Caused by: java.lang.ClassNotFoundException: *** Package 'javax.servlet' is imported by bundle 10 from bundle 0, but the exported package from bundle 0 does not contain the requested class 'javax.servlet.Servlet'. Please verify that the class name is correct in the importing bundle 10 and/or that the exported package is correctly bundled in 0. ***      at org.apache.felix.framework.ModuleImpl$ModuleClassLoader.loadClass(ModuleImpl.java:1670)      at java.lang.ClassLoader.loadClass(ClassLoader.java:252)      at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)      ... 15 more Caused by: java.lang.ClassNotFoundException: javax.servlet.Servlet      at java.net.URLClassLoader$1.run(URLClassLoader.java:200)      at java.security.AccessController.doPrivileged(Native Method)      at java.net.URLClassLoader.findClass(URLClassLoader.java:188)      at java.lang.ClassLoader.loadClass(ClassLoader.java:307)      at java.lang.ClassLoader.loadClass(ClassLoader.java:252)      at org.apache.felix.framework.ExtensionManager$ExtensionManagerModule.getClassByDelegation(ExtensionManager.java:670)      at org.apache.felix.framework.searchpolicy.R4Wire.getClass(R4Wire.java:108)      at org.apache.felix.framework.ModuleImpl.searchImports(ModuleImpl.java:1370)      at org.apache.felix.framework.ModuleImpl.findClassOrResourceByDelegation(ModuleImpl.java:683)      at org.apache.felix.framework.ModuleImpl.access$100(ModuleImpl.java:61)      at org.apache.felix.framework.ModuleImpl$ModuleClassLoader.loadClass(ModuleImpl.java:1656)      ... 17 more |#] Looks like Glassfish is not exporting J2EE classes to Felix. I attach my eclipse test project. Any help is appreciated. P.S. The same code works well with Jetty (by mvn jetty:run) Message was edited by: dboltri
        • 1. Re: Embed Apache Felix in a Web Application
          392 Guest
          You must have configured system bundle to export javax.servlet package for embedded Felix. What class loader have you configured as the parent class loader for embedded Felix? Try setting org.osgi.framework.bundle.parent=framework in your felix config file. Having said that why would you embed Felix in your webapp deployed in GlassFish v3 when GlassFish v3 is already deployed inside Felix? Your web app can already be deployed as an OSGi bundle allowing it to take advantage of both Java EE and OSGi APIs. Sahoo On Tuesday 22 June 2010 09:25 PM, glassfish@javadesktop.org wrote: > Hi all, > I'm trying to develop an OSGI based WebApp embedding Apache Felix in it using Apache Felix Http Bridge to register a simple servlet. When deploying application on Glassfish V3 i get following exception when the bundle containing the servlet starts: > > [#|2010-06-22T17:07:07.281+0200|INFO|glassfish3.0.1|javax.enterprise.system.std.com.sun.enterprise.v3.services.impl|_ThreadID=39;_ThreadName=Thread-1;|org.osgi.framework.BundleException: Activator start error in bundle com.test.basic.servlet [10]. >      at org.apache.felix.framework.Felix.activateBundle(Felix.java:1751) >      at org.apache.felix.framework.Felix.startBundle(Felix.java:1622) >      at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:915) >      at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:902) >      at org.apache.felix.fileinstall.internal.DirectoryWatcher.start(DirectoryWatcher.java:1027) >      at org.apache.felix.fileinstall.internal.DirectoryWatcher.start(DirectoryWatcher.java:1013) >      at org.apache.felix.fileinstall.internal.DirectoryWatcher.startAllBundles(DirectoryWatcher.java:1006) >      at org.apache.felix.fileinstall.internal.DirectoryWatcher.process(DirectoryWatcher.java:396) >      at org.apache.felix.fileinstall.internal.DirectoryWatcher.run(DirectoryWatcher.java:206) > Caused by: java.lang.NoClassDefFoundError: javax/servlet/Servlet >      at java.lang.Class.getDeclaredConstructors0(Native Method) >      at java.lang.Class.privateGetDeclaredConstructors(Class.java:2389) >      at java.lang.Class.getConstructor0(Class.java:2699) >      at java.lang.Class.newInstance0(Class.java:326) >      at java.lang.Class.newInstance(Class.java:308) >      at org.apache.felix.framework.Felix.createBundleActivator(Felix.java:3520) >      at org.apache.felix.framework.Felix.activateBundle(Felix.java:1695) >      ... 8 more > Caused by: java.lang.ClassNotFoundException: *** Package 'javax.servlet' is imported by bundle 10 from bundle 0, but the exported package from bundle 0 does not contain the requested class 'javax.servlet.Servlet'. Please verify that the class name is correct in the importing bundle 10 and/or that the exported package is correctly bundled in 0. *** >      at org.apache.felix.framework.ModuleImpl$ModuleClassLoader.loadClass(ModuleImpl.java:1670) >      at java.lang.ClassLoader.loadClass(ClassLoader.java:252) >      at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320) >      ... 15 more > Caused by: java.lang.ClassNotFoundException: javax.servlet.Servlet >      at java.net.URLClassLoader$1.run(URLClassLoader.java:200) >      at java.security.AccessController.doPrivileged(Native Method) >      at java.net.URLClassLoader.findClass(URLClassLoader.java:188) >      at java.lang.ClassLoader.loadClass(ClassLoader.java:307) >      at java.lang.ClassLoader.loadClass(ClassLoader.java:252) >      at org.apache.felix.framework.ExtensionManager$ExtensionManagerModule.getClassByDelegation(ExtensionManager.java:670) >      at org.apache.felix.framework.searchpolicy.R4Wire.getClass(R4Wire.java:108) >      at org.apache.felix.framework.ModuleImpl.searchImports(ModuleImpl.java:1370) >      at org.apache.felix.framework.ModuleImpl.findClassOrResourceByDelegation(ModuleImpl.java:683) >      at org.apache.felix.framework.ModuleImpl.access$100(ModuleImpl.java:61) >      at org.apache.felix.framework.ModuleImpl$ModuleClassLoader.loadClass(ModuleImpl.java:1656) >      ... 17 more > |#] > > > Looks like Glassfish is not exporting J2EE classes to Felix. I attach my eclipse test project. Any help is appreciated. > [Message sent by forum member 'dboltri'] > > http://forums.java.net/jive/thread.jspa?messageID=475373 > > --------------------------------------------------------------------- > To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net > For additional commands, e-mail: users-help@glassfish.dev.java.net > >    --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net For additional commands, e-mail: users-help@glassfish.dev.java.net
          • 2. Re: Embed Apache Felix in a Web Application
            dboltri
            Thanks for your answer. This is the Felix configuration file I'm currently using: ############## org.osgi.framework.storage.clean=onFirstInit org.osgi.framework.bundle.parent=framework felix.bootdelegation.implicit=true felix.log.level=4 org.apache.felix.http.debug=true osgi.shell.telnet.port=7789 ############## Reading the glassfish log what i can see is that Apache Felix HTTP Bridge doesn't load with such errror: [#|2010-06-23T10:56:13.312+0200|INFO|glassfish3.0.1|javax.enterprise.system.std.com.sun.enterprise.v3.services.impl|_ThreadID=44;_ThreadName=Thread-1;|ERROR: Error starting file:/C:/glassfishv3/glassfish/domains/domain1/applications/webapp.felix/WEB-INF/bundles/org.apache.felix.http.bridge-2.0.4.jar (org.osgi.framework.BundleException: Unresolved constraint in bundle org.apache.felix.http.bridge [3]: package; (package=javax.servlet))|#] [#|2010-06-23T10:56:13.312+0200|SEVERE|glassfish3.0.1|javax.enterprise.system.std.com.sun.enterprise.v3.services.impl|_ThreadID=44;_ThreadName=Thread-1;|org.osgi.framework.BundleException: Unresolved constraint in bundle org.apache.felix.http.bridge [3]: package; (package=javax.servlet)      at org.apache.felix.framework.Felix.resolveBundle(Felix.java:3263)      at org.apache.felix.framework.Felix.startBundle(Felix.java:1597)      at org.apache.felix.framework.Felix.setActiveStartLevel(Felix.java:1077)      at org.apache.felix.framework.StartLevelImpl.run(StartLevelImpl.java:264)      at java.lang.Thread.run(Thread.java:619) |#] I've also tried to put "app" as org.osgi.framework.bundle.parent value in place of "framework" but nothing changes. Adding following line to Felix configuration file: org.osgi.framework.system.packages.extra=javax.servlet, javax.servlet.http doesn't help :( Have you any other suggestions? Reason why I want to embed Felix in my WebApp is that I want to use it as a plugin framework and I need it to be independent from the underlying application server. Thanks in advance > You must have configured system bundle to export > javax.servlet package > for embedded Felix. What class loader have you > configured as the parent > class loader for embedded Felix? Try setting > > org.osgi.framework.bundle.parent=framework > > in your felix config file. > > Having said that why would you embed Felix in your > webapp deployed in > GlassFish v3 when GlassFish v3 is already deployed > inside Felix? Your > web app can already be deployed as an OSGi bundle > allowing it to take > advantage of both Java EE and OSGi APIs. > > Sahoo >
            • 3. Re: Embed Apache Felix in a Web Application
              392 Guest
              I think I know what's going on here. Since GlassFish is already running on top of Felix, when you are trying to load Felix, Felix actually gets loaded by one of GlassFish class loader that's parent of web app class loader. The class loader that loads Felix classes does not really have visibility to Java EE APIs like javax.servlet. So, even if you set org.osgi.framework.bundle.parent=framework it's not making any difference. You may like to launch Felix using a custom class loader in OsgiManager.java: ClassLoader cl = new ClassLoader(Thread.currentThread().getContextClassLoader()) {       protected Class loadClass(String className) throws ClassNotFoundException() {              if(className.startsWith("org.apache.felix")) {                     URL url = findResource(convertClassNameToResource(className));                     if(url != null) {                          byte[] bytes = readData(url);                          defineClass(...);                     }              }               return super.loadClass(className);       } } Use this class to load org.apache.felix.main.Main and FrameworkFactory class. I understand this is really not an elegant solution. An easier option is to switch off delegation flag in web app class loader. You can do it by having a suitable sun-web.xml file in your web app. Just google for it. I understand you don't want to depend on specific container behavior, but can you detect that your code is running inside an OSGi enabled container and use that instead of launching a new one? e.g., the code below gets you a BundleContext object in glassfish: org.osgi.framework.BundleReference ref = (BundleReference)javax.servlet.class.getClassLoader(); Bundle b = ref.getBundle(); BundleContext bctx = b.getBundleContext(); Use it to load your management bundle and pass control to it. Thanks, Sahoo p.s: I have not really thought hard about this problem - so I am not sure if all these will work or not in reality. On Wednesday 23 June 2010 02:49 PM, glassfish@javadesktop.org wrote: > Thanks for your answer. > > This is the Felix configuration file I'm currently using: > > ############## > org.osgi.framework.storage.clean=onFirstInit > org.osgi.framework.bundle.parent=framework > felix.bootdelegation.implicit=true > felix.log.level=4 > org.apache.felix.http.debug=true > osgi.shell.telnet.port=7789 > ############## > > Reading the glassfish log what i can see is that Apache Felix HTTP Bridge doesn't load with such errror: > > [#|2010-06-23T10:56:13.312+0200|INFO|glassfish3.0.1|javax.enterprise.system.std.com.sun.enterprise.v3.services.impl|_ThreadID=44;_ThreadName=Thread-1;|ERROR: Error starting file:/C:/glassfishv3/glassfish/domains/domain1/applications/webapp.felix/WEB-INF/bundles/org.apache.felix.http.bridge-2.0.4.jar (org.osgi.framework.BundleException: Unresolved constraint in bundle org.apache.felix.http.bridge [3]: package; (package=javax.servlet))|#] > > [#|2010-06-23T10:56:13.312+0200|SEVERE|glassfish3.0.1|javax.enterprise.system.std.com.sun.enterprise.v3.services.impl|_ThreadID=44;_ThreadName=Thread-1;|org.osgi.framework.BundleException: Unresolved constraint in bundle org.apache.felix.http.bridge [3]: package; (package=javax.servlet) >      at org.apache.felix.framework.Felix.resolveBundle(Felix.java:3263) >      at org.apache.felix.framework.Felix.startBundle(Felix.java:1597) >      at org.apache.felix.framework.Felix.setActiveStartLevel(Felix.java:1077) >      at org.apache.felix.framework.StartLevelImpl.run(StartLevelImpl.java:264) >      at java.lang.Thread.run(Thread.java:619) > |#] > > I've also tried to put "app" as org.osgi.framework.bundle.parent value in place of "framework" but nothing changes. > > Adding following line to Felix configuration file: > > org.osgi.framework.system.packages.extra=javax.servlet, javax.servlet.http > > doesn't help :( > > Have you any other suggestions? > > Reason why I want to embed Felix in my WebApp is that I want to use it as a plugin framework and I need it to be independent from the underlying application server. > > Thanks in advance > >    >> You must have configured system bundle to export >> javax.servlet package >> for embedded Felix. What class loader have you >> configured as the parent >> class loader for embedded Felix? Try setting >> >> org.osgi.framework.bundle.parent=framework >> >> in your felix config file. >> >> Having said that why would you embed Felix in your >> webapp deployed in >> GlassFish v3 when GlassFish v3 is already deployed >> inside Felix? Your >> web app can already be deployed as an OSGi bundle >> allowing it to take >> advantage of both Java EE and OSGi APIs. >> >> Sahoo >> >>      > [Message sent by forum member 'dboltri'] > > http://forums.java.net/jive/thread.jspa?messageID=475486 > > --------------------------------------------------------------------- > To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net > For additional commands, e-mail: users-help@glassfish.dev.java.net > >    --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net For additional commands, e-mail: users-help@glassfish.dev.java.net