Jeremy Sweetman
Jeremy Sweetman

Reputation: 11

Has anyone succesfully got Tomcat running via Spring OSGi Web in ServiceMix4?

We've been using Fuse's Apache ServiceMix version 4.2.0-fuse-02-00 for a while now for standard OSGi applications and have been fairly successful. We've also been leveraging CXF for making web services available.

Now we'd like to deploy our webapps to servicemix4 and leverage the OSGi layer for dependencies and services. However it seems that the packed in PAX Web does not support taglibs, which we've used heavily: Richfaces, facelets, etc. It seems that the springDM solution which allows for working taglibs outlined here: http://static.springsource.org/osgi/docs/current/reference/html/web.html should work, however I've had a hard time starting up the webserver, i currently get this error.

Exception in thread "WebExtender-Init" java.lang.NoClassDefFoundError: org/apache/catalina/Loader
 at org.springframework.osgi.web.extender.internal.activator.WarListenerConfiguration.createDefaultWarDeployer(WarListenerConfiguration.java:194)
 at org.springframework.osgi.web.extender.internal.activator.WarListenerConfiguration.<init>(WarListenerConfiguration.java:105)
 at org.springframework.osgi.web.extender.internal.activator.WarLoaderListener$1.run(WarLoaderListener.java:366)
 at java.lang.Thread.run(Thread.java:619)
Caused by: java.lang.ClassNotFoundException: org.apache.catalina.Loader
 at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:494)
 at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:410)
 at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:398)
 at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:105)
 at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
 ... 4 more

I've created 2 Fragments as the Spring documentation suggests. but they will not resolve, they remain as Installed

1) the webserver config fragment has the following fragment host defined:

<Fragment-Host>org.springframework.osgi.web.extender</Fragment-Host>

and has a file META-INF/spring/extender/tomcat-deployer.xml containing

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://www.springframework.org/schema/beans   
       http://www.springframework.org/schema/beans/spring-beans.xsd">
 <bean id="warDeployer"
        class="org.springframework.osgi.web.deployer.tomcat.TomcatWarDeployer" />

</beans>

2) and a Catalina Config fragment with the following host:

<Fragment-Host>org.springframework.osgi.catalina.start.osgi</Fragment-Host>

and a conf/server.xml defined which is mostly a copy of a generic windows install of tomcat 6 server.xml file.

I've also been messing with the dependencies for a few days now, it has been difficult. but here are the features I've been messing with to get this far. I've also been installing the fuse-servicemix default "jpa-hibernate" feature.

<feature name="spring-dependencies" version="1.0.0">
    <bundle>mvn:org.osgi/org.osgi.compendium/4.1.0</bundle>
    <bundle>mvn:javax.el/com.springsource.javax.el/1.0.0</bundle>
    <bundle>mvn:javax.xml.ws/com.springsource.javax.xml.ws/2.1.1</bundle>
    <bundle>mvn:javax.xml.stream/com.springsource.javax.xml.stream/1.0.1</bundle>
    <bundle>mvn:javax.xml.rpc/com.springsource.javax.xml.rpc/1.1.0</bundle>
    <bundle>mvn:javax.xml.soap/com.springsource.javax.xml.soap/1.3.0</bundle>
    <bundle>mvn:javax.persistence/com.springsource.javax.persistence/1.99.0</bundle>
    <bundle>mvn:org.aspectj/com.springsource.org.aspectj.tools/1.6.8.RELEASE</bundle>
    <bundle>mvn:org.apache.commons/com.springsource.org.apache.commons.logging/1.1.1</bundle>
    <bundle>mvn:org.apache.commons/com.springsource.org.apache.commons.lang/2.4.0</bundle>
    <bundle>mvn:org.apache.xmlcommons/com.springsource.org.apache.xmlcommons/1.3.4</bundle>
    <bundle>mvn:org.jboss.el/com.springsource.org.jboss.el/2.0.0.GA</bundle>
    <bundle>mvn:org.jboss.javassist/com.springsource.javassist/3.9.0.GA</bundle>
    <bundle>mvn:org.aopalliance/com.springsource.org.aopalliance/1.0.0</bundle>
</feature>
<feature name="spring" version="1.0.0">
    <!--feature version="1.0.0">spring-dependencies</feature-->
    <!--bundle>mvn:org.springframework.osgi/org.springframework.osgi.core/1.2.1</bundle--> <!-- there is 1.2.1, but servicemix plays the 1.2.0 game -->
    <!--bundle>mvn:org.springframework.osgi/org.springframework.osgi.io/1.2.1</bundle--> <!-- there is 1.2.1, but servicemix plays the 1.2.0 game -->
    <!--bundle>mvn:org.springframework.osgi/org.springframework.osgi.extender/1.2.1</bundle--> <!-- there is 1.2.1, but servicemix plays the 1.2.0 game -->
    <!--bundle>mvn:org.springframework.osgi/org.springframework.osgi.extensions.annotation/1.2.1</bundle--> <!-- there is 1.2.1, but servicemix plays the 1.2.0 game -->
    <!-- commenting the 3.0.4 release to see if i can get by with the prepacked version in servicmeix bundle>mvn:org.springframework/org.springframework.aop/3.0.4.RELEASE</bundle>
    <bundle>mvn:org.springframework/org.springframework.asm/3.0.4.RELEASE</bundle>
    <bundle>mvn:org.springframework/org.springframework.aspects/3.0.4.RELEASE</bundle>
    <bundle>mvn:org.springframework/org.springframework.beans/3.0.4.RELEASE</bundle>
    <bundle>mvn:org.springframework/org.springframework.context/3.0.4.RELEASE</bundle>
    <bundle>mvn:org.springframework/org.springframework.context.support/3.0.4.RELEASE</bundle>
    <bundle>mvn:org.springframework/org.springframework.core/3.0.4.RELEASE</bundle>
    <bundle>mvn:org.springframework/org.springframework.expression/3.0.4.RELEASE</bundle>
    <bundle>mvn:org.springframework/org.springframework.jms/3.0.4.RELEASE</bundle>
    <bundle>mvn:org.springframework/org.springframework.jdbc/3.0.4.RELEASE</bundle>
    <bundle>mvn:org.springframework/org.springframework.transaction/3.0.4.RELEASE</bundle>
    <bundle>mvn:org.springframework/org.springframework.orm/3.0.4.RELEASE</bundle>
    <bundle>mvn:org.springframework.security/org.springframework.security.core/3.0.3.RELEASE</bundle-->
    <bundle>mvn:org.springframework.osgi/org.springframework.osgi.web/1.2.0</bundle> <!-- there is 1.2.1, but servicemix plays the 1.2.0 game -->
    <bundle>mvn:org.springframework.osgi/org.springframework.osgi.web.extender/1.2.0</bundle>  <!-- there is 1.2.1, but servicemix plays the 1.2.0 game -->
</feature>
<feature name="tomcat" version="1.0.0">
    <!--feature version="1.0.0">spring</feature-->
    <bundle>mvn:javax.ejb/com.springsource.javax.ejb/3.0.0</bundle>
    <bundle>mvn:javax.activation/com.springsource.javax.activation/1.1.1</bundle>
    <bundle>mvn:javax.mail/com.springsource.javax.mail/1.4.1</bundle>
    <bundle>mvn:org.apache.coyote/com.springsource.org.apache.coyote/6.0.18</bundle>
    <bundle>mvn:org.apache.juli/com.springsource.org.apache.juli.extras/6.0.18</bundle>
    <bundle>mvn:org.apache.catalina/com.springsource.org.apache.catalina/6.0.18</bundle>
    <bundle>mvn:org.springframework/org.springframework.instrument.tomcat/3.0.4.RELEASE</bundle>
</feature>
<feature name="web-dependencies" version="1.0.0">
    <!--feature version="1.0.0">spring-dependencies</feature-->
    <!--feature version="1.0.0">tomcat-dependencies</feature-->
    <bundle>mvn:javax.servlet/com.springsource.javax.servlet/2.5.0</bundle>
    <!--bundle>mvn:javax.servlet/com.springsource.javax.servlet.jsp/2.1.0</bundle--> <!--we want this but PAX Web -JSP Support claims tooffer the same thing -->
    <!--bundle>mvn:javax.servlet/com.springsource.javax.servlet.jsp.jstl/1.2.0</bundle--> <!--bundle is causing conflict issues on javax.servlet.jsp 2.1.0 in fuse, omitting for now -->

    <!-- I have been having problems getting the following to work because of conflicts with the javax.servlet.jsp package 1.2.0 presented by Pax Web seems to not be able to be found -->
    <bundle>mvn:javax.faces/com.springsource.javax.faces/1.2.0.09</bundle>
    <bundle>mvn:javax.portlet/com.springsource.javax.portlet/2.0.0</bundle>>
    <bundle>mvn:org.springframework/org.springframework.web/3.0.4.RELEASE</bundle>
    <bundle>mvn:org.springframework/org.springframework.web.servlet/3.0.4.RELEASE</bundle>
    <bundle>mvn:org.springframework/org.springframework.web.portlet/3.0.4.RELEASE</bundle>
    <bundle>mvn:org.springframework.webflow/org.springframework.binding/2.0.9.RELEASE</bundle>
    <bundle>mvn:org.springframework.webflow/org.springframework.js/2.0.9.RELEASE</bundle>
    <bundle>mvn:org.springframework.webflow/org.springframework.webflow/2.0.9.RELEASE</bundle>
    <bundle>mvn:org.springframework.webflow/org.springframework.faces/2.0.9.RELEASE</bundle>  <!--2.1.0 and up rely on Java Server Faces API 2.0 Pre-Release right now, so we must stop at 2.0.9 -->
    <bundle>mvn:com.sun.facelets/com.springsource.com.sun.facelets/1.1.14</bundle>
</feature>

I've considered switching to SpringDM but it seems like the project has been moved to Virgo which is only in incubator right now. Plus we've been mostly happy with Sericemix, including it's maven install feature.

Any insight or resources would be appreciated, thanks, Jeremy

Upvotes: 1

Views: 2370

Answers (1)

fei0x
fei0x

Reputation: 4690

So after a break from this I came back and tackled this with some more members of my team. In short we successfully got Tomcat in ServiceMix using SpringDM. I'll list some of the mistakes I made while trying to get this set up.

1) ServiceMix's Refresh function reanalyzes the POM, so fragments will become resolved only after you refresh their host. That's why mine were still in installed

2) I actually didn't need either of the two fragments, there are defaults for both fragments which are suitable for starting up in tomcat.

3) I was missing the catalalina.start.osgi bundle which was required to offer the tomcat services to the osgi layer and more specificly the Spring DM's web extender. However, I missed it because I had missed 3 key repositories. Here are our Nexus info on these repos:

Repository ID: springframework.osgi
Repository Name: Springframework OSGI
Repository Type: proxy
Repository Policy: Release
Repository Format: maven2
Contained in groups: 
   Public Repositories
Remote URL: http://maven.springframework.org/osgi/

Repository ID: com.springsource.repository.bundles.release
Repository Name: SpringSource Enterprise Bundle Repository - SpringSource Bundle Releases
Repository Type: proxy
Repository Policy: Release
Repository Format: maven2
Contained in groups: 
   Public Repositories
Remote URL: http://repository.springsource.com/maven/bundles/release/

Repository ID: com.springsource.repository.bundles.milestones
Repository Name: SpringSource Enterprise Bundle Repository - SpringSource Bundle Milestones
Repository Type: proxy
Repository Policy: Release
Repository Format: maven2
Contained in groups: 
   Public Repositories
Remote URL: http://repository.springsource.com/maven/bundles/milestone/

we also have 4 other SpringSource Enterprise Repos (just in case0

Repository ID: com.springsource.repository.bundles.external
Repository Name: SpringSource Enterprise Bundle Repository - External Bundle Releases
Repository Type: proxy
Repository Policy: Release
Repository Format: maven2
Contained in groups: 
   Public Repositories
Remote URL: http://repository.springsource.com/maven/bundles/external/

Repository ID: com.springsource.repository.libraries.external
Repository Name: SpringSource Enterprise Bundle Repository - External Library Releases
Repository Type: proxy
Repository Policy: Release
Repository Format: maven2
Contained in groups: 
   Public Repositories
Remote URL: http://repository.springsource.com/maven/libraries/external/

Repository ID: com.springsource.snapshot
Repository Name: SpringSource Enterprise Bundle Repository - SpringSource Bundle Snapshots
Repository Type: proxy
Repository Policy: Snapshot
Repository Format: maven2
Contained in groups: 
   Public Repositories
Remote URL: http://repository.springsource.com/maven/bundles/snapshot/

Repository ID: com.springsource.repository.libraries.release
Repository Name: SpringSource Enterprise Bundle Repository - SpringSource Library Releases
Repository Type: proxy
Repository Policy: Release
Repository Format: maven2
Contained in groups: 
   Public Repositories
Remote URL: http://repository.springsource.com/maven/libraries/release/

So we added these two fragments to the catalina bundle in addition to coyote on servicemix:

<bundle>mvn:org.springframework.osgi/catalina.start.osgi/1.0.0</bundle>
<bundle>mvn:org.apache.jasper/com.springsource.org.apache.jasper/6.0.24</bundle>

the jasper bundle is required for jsp.

4) After adding the bundles, refreshing and restarting appropriate bundles, Tomcat got up and running fine. we could hit localhost:8080 and hit a blank page. We decided to try and deploy the simple-web-app that comes in the Spring-DM download here:

http://www.springsource.org/osgi

After resolving some dependency issues, we were able to clean and build this web-app and get it deployed. In our Ubuntu environment you could see it explode the war to the /tmp/ directory from which it will serve the web app. Unfortunately we got 404s when trying to hit the http://localhost:8080/simple-web-app/ after some Tomcat debugging we realized that this installation of tomcat was somehow not seeing the usual default web.xml servlet information. So for the mean time we've had to include the default servlet in our web-app's web.xml:

    <servlet>
        <servlet-name>default</servlet-name>
        <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
        <init-param>
            <param-name>debug</param-name>
            <param-value>0</param-value>
        </init-param>
        <init-param>
            <param-name>listings</param-name>
            <param-value>false</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

<servlet>
    <servlet-name>jsp</servlet-name>
    <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
    <init-param>
        <param-name>fork</param-name>
        <param-value>false</param-value>
    </init-param>
    <init-param>
        <param-name>xpoweredBy</param-name>
        <param-value>false</param-value>
    </init-param>
    <load-on-startup>3</load-on-startup>
</servlet>

    <!-- The mapping for the default servlet -->
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!-- The mapping for the JSP servlet -->
    <servlet-mapping>
        <servlet-name>jsp</servlet-name>
        <url-pattern>*.jsp</url-pattern>
    </servlet-mapping>

    <servlet-mapping>
        <servlet-name>jsp</servlet-name>
        <url-pattern>*.jspx</url-pattern>
    </servlet-mapping>

Further investigation of why our sample app could not find the default servlets is here:

http://forum.springsource.org/showthread.php?p=328657#post328657

So at this time we seemed to have got it all up and running with working tag-libs as required, given this spring example. Although we have still to attempt using the OSGi classpath to load resources from, or using OSGi services from a web app, we at least have the first step down.

Please note this link was very helpful for verifying what I'd done even though we're not using Wicket.

http://kevinwebber.ca/blog/2009/11/11/wicket-osgi-and-spring-dm.html#references

sorry about the links, stackoverflow wont let me have more than 1..

Upvotes: 2

Related Questions