OSGi bundles with OSGi WAB
I'm kinda new to develop OSGi bundles and OSGi WAB. I'm using Jboss AS 7.1 server in which I should use both OSGi bundles and WAB together. Few of my dependencies for WAB are OSGi bundles, both the bundles and WAB are inside 'deployments' folder of my server. When I deploy my WAB, it looks for the dependencies inside 'WEB-INF/lib'. How to include the bundles for dependencies which are outside the WAB file without adding those bundles in 'WEB-INF/lib'?
Thanks in advance.
EDIT:
I followed the steps provided in this link:
http://www.rpgnextgen.com/wiki/doku.php?id=vaadin_7.4_osgi_web_application
I was successful in creating a WAB file. I have all the necessary Vaadin dependencies deployed as OSGi bundles in my server under 'deployments' folder. When I deploy my WAB file, the Vaadin dependencies under 'deployments' folder are not included but the WAB file is looking for Vaadin dependencies inside 'WEB-INF/lib' path. The below is the pom.xml I'm using.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.stpl.product.test</groupId>
<artifactId>VaadinWab</artifactId>
<version>1.0</version>
<packaging>war</packaging>
<name>VaadinWab OSGi Bundle</name>
<properties>
<vaadin.version>7.5.7</vaadin.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.core</artifactId>
<version>4.2.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-push</artifactId>
<version>${vaadin.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-server</artifactId>
<version>${vaadin.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-client</artifactId>
<version>${vaadin.version}</version>
<scope>provided</scope>
<type>jar</type>
</dependency>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-themes</artifactId>
<version>${vaadin.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>6.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.compendium</artifactId>
<version>4.2.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<!-- Need to use this plugin to build war files -->
<artifactId>maven-war-plugin</artifactId>
<groupId>org.apache.maven.plugins</groupId>
<version>2.3</version>
<configuration>
<archive>
<!-- add bundle plugin generated manifest to the war -->
<manifestFile>
${project.build.outputDirectory}/META-INF/MANIFEST.MF
</manifestFile>
<!-- Adding Bundle-ClassPath in maven-bundle-plugin confuses that plugin
and it generates wrong Import-Package, etc. So, we generate it here. -->
<manifestEntries>
<Bundle-ClassPath>WEB-INF/classes/</Bundle-ClassPath>
</manifestEntries>
</archive>
<!-- We don't always have a web.xml -->
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<!-- add bundle plugin generated manifest to the jar -->
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>2.3.7</version>
<extensions>true</extensions>
<executions>
<execution>
<id>bundle-manifest</id>
<phase>process-classes</phase>
<goals>
<goal>manifest</goal>
</goals>
</execution>
<execution>
<id>bundle-install</id>
<phase>install</phase>
<goals>
<goal>install</goal>
</goals>
</execution>
</executions>
<configuration>
<supportedProjectTypes>
<supportedProjectType>ejb</supportedProjectType>
<supportedProjectType>war</supportedProjectType>
<supportedProjectType>bundle</supportedProjectType>
<supportedProjectType>jar</supportedProjectType>
</supportedProjectTypes>
<instructions>
<_include>osgi.properties</_include>
<Bundle-PresentationName>${project.artifactId}</Bundle-PresentationName>
<Embed-Dependency>*;scope=compile</Embed-Dependency>
<Embed-Transitive>true</Embed-Transitive>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>build-for-felix</id>
<dependencies>
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.main</artifactId>
<version>4.0.3</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<id>compile</id>
<phase>package</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<pathconvert property="plugins.jars" pathsep="${path.separator}">
<path refid="maven.runtime.classpath"/>
<map from="${project.build.directory}${file.separator}classes" to=""/>
</pathconvert>
<pathconvert pathsep=" " property="bundles">
<path path="${plugins.jars}"/>
<mapper>
<chainedmapper>
<flattenmapper/>
<globmapper from="*" to="file:modules/*" casesensitive="no"/>
</chainedmapper>
</mapper>
</pathconvert>
<propertyfile file="${project.build.directory}/config.properties">
<entry key="felix.auto.start" value="${bundles} file:modules/${project.build.finalName}.jar"/>
<entry key="org.osgi.framework.bootdelegation" value="*"/>
</propertyfile>
<copy file="${maven.dependency.org.apache.felix.org.apache.felix.main.jar.path}" tofile="${project.build.directory}/felix.jar"/>
</target>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<id>create-executable-jar</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>${basedir}/src/main/assembly/felix.xml</descriptor>
</descriptors>
<finalName>${project.build.finalName}</finalName>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>run-on-felix</id>
<dependencies>
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.main</artifactId>
<version>4.0.3</version>
<scope>provided</scope>
</dependency>
<!-- org.apache.felix:org.apache.felix.gogo.shell:0.6.1 useless from Maven since stdin is swallowed -->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<configuration>
<target>
<property name="vm.args" value=""/>
<pathconvert property="plugins.jars" pathsep="${path.separator}">
<path refid="maven.runtime.classpath"/>
<map from="${project.build.directory}${file.separator}classes" to=""/>
</pathconvert>
<makeurl property="urls" separator=" ">
<path path="${plugins.jars}"/>
<path location="${project.build.directory}/${project.build.finalName}.jar"/>
</makeurl>
<propertyfile file="${project.build.directory}/run.properties">
<entry key="felix.auto.start" value="${urls}"/>
<entry key="felix.auto.deploy.action" value="uninstall,install,update,start"/>
<entry key="org.osgi.framework.storage" value="${project.build.directory}${file.separator}felix-cache"/>
<entry key="org.osgi.framework.bootdelegation" value="*"/>
</propertyfile>
<makeurl property="run.properties.url" file="${project.build.directory}/run.properties"/>
<java fork="true" jar="${maven.dependency.org.apache.felix.org.apache.felix.main.jar.path}">
<sysproperty key="felix.config.properties" value="${run.properties.url}"/>
<jvmarg line="${vm.args}"/>
</java>
</target>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
Basically what I'm trying to do is to create a WAB project which uses other bundles for dependencies instead of using 'WEB-INF/lib' inside the .war file.
When I deploy the war file to the server, I end up getting the below exception:
10:52:07,718 WARN [org.ops4j.pax.web.jsp.internal.JasperClassLoader] (Executor: 2) Exception while calculating location of imported bundles: java.net.MalformedURLException: no protocol: vaadin-server-7.5.7.jar
at java.net.URL.<init>(URL.java:585) [rt.jar:1.7.0_65]
at java.net.URL.<init>(URL.java:482) [rt.jar:1.7.0_65]
at java.net.URL.<init>(URL.java:431) [rt.jar:1.7.0_65]
at org.ops4j.pax.web.jsp.internal.JasperClassLoader.getLocationsOfBundlesInClassSpace(JasperClassLoader.java:177)
at org.ops4j.pax.web.jsp.internal.JasperClassLoader.getClassPathJars(JasperClassLoader.java:157)
at org.ops4j.pax.web.jsp.internal.JasperClassLoader.<init>(JasperClassLoader.java:73)
at org.ops4j.pax.web.jsp.JspServletWrapper.<init>(JspServletWrapper.java:59)
at org.ops4j.pax.web.service.internal.HttpServiceStarted.registerJsps(HttpServiceStarted.java:490)
at org.ops4j.pax.web.service.internal.HttpServiceProxy.registerJsps(HttpServiceProxy.java:194)
at org.ops4j.pax.web.extender.war.internal.RegisterWebAppVisitorWC.visit(RegisterWebAppVisitorWC.java:169)
at org.ops4j.pax.web.extender.war.internal.model.WebApp.accept(WebApp.java:590)
at org.ops4j.pax.web.extender.war.internal.WebAppPublisher$HttpServiceListener.register(WebAppPublisher.java:170)
at org.ops4j.pax.web.extender.war.internal.WebAppPublisher$HttpServiceListener.serviceChanged(WebAppPublisher.java:155)
at org.ops4j.pax.web.extender.war.internal.WebAppPublisher$HttpServiceListener.serviceChanged(WebAppPublisher.java:119)
at org.ops4j.pax.swissbox.tracker.ReplaceableService.setService(ReplaceableService.java:114)
at org.ops4j.pax.swissbox.tracker.ReplaceableService.access$100(ReplaceableService.java:28)
at org.ops4j.pax.swissbox.tracker.ReplaceableService$CollectionListener.serviceAdded(ReplaceableService.java:183)
at org.ops4j.pax.swissbox.tracker.ServiceCollection$Tracker.addingService(ServiceCollection.java:181)
at org.osgi.util.tracker.ServiceTracker$Tracked.customizerAdding(ServiceTracker.java:896) [ServiceTracker$Tracked.class:]
at org.osgi.util.tracker.AbstractTracked.trackAdding(AbstractTracked.java:261)
at org.osgi.util.tracker.AbstractTracked.trackInitial(AbstractTracked.java:184)
at org.osgi.util.tracker.ServiceTracker.open(ServiceTracker.java:339) [ServiceTracker.class:]
at org.osgi.util.tracker.ServiceTracker.open(ServiceTracker.java:273) [ServiceTracker.class:]
at org.ops4j.pax.swissbox.tracker.ServiceCollection.onStart(ServiceCollection.java:139)
at org.ops4j.pax.swissbox.lifecycle.AbstractLifecycle$Stopped.start(AbstractLifecycle.java:121)
at org.ops4j.pax.swissbox.lifecycle.AbstractLifecycle.start(AbstractLifecycle.java:49)
at org.ops4j.pax.swissbox.tracker.ReplaceableService.onStart(ReplaceableService.java:146)
at org.ops4j.pax.swissbox.lifecycle.AbstractLifecycle$Stopped.start(AbstractLifecycle.java:121)
at org.ops4j.pax.swissbox.lifecycle.AbstractLifecycle.start(AbstractLifecycle.java:49)
at org.ops4j.pax.web.extender.war.internal.WebAppPublisher.publish(WebAppPublisher.java:81)
at org.ops4j.pax.web.extender.war.internal.WebXmlObserver.deploy(WebXmlObserver.java:200)
at org.ops4j.pax.web.extender.war.internal.WebXmlObserver.addingEntries(WebXmlObserver.java:159)
at org.ops4j.pax.swissbox.extender.BundleWatcher$3.run(BundleWatcher.java:224)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) [rt.jar:1.7.0_65]
at java.util.concurrent.FutureTask.run(FutureTask.java:262) [rt.jar:1.7.0_65]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:178) [rt.jar:1.7.0_65]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:292) [rt.jar:1.7.0_65]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [rt.jar:1.7.0_65]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [rt.jar:1.7.0_65]
at java.lang.Thread.run(Thread.java:745) [rt.jar:1.7.0_65]
Ok, that's a real old version of Pax-Web (current version is 4).
The reason for this behavior is, to also give an explanation to @NeilBartlett, to be able to get a hold of all possible taglibs.
The Pax-Web Container traverses the imported bundles and does look for taglibs in this bundle to make them available to the JSP JasperCompiler.
This is one of the parts that has been improved over time. The way it's done in 1.x of Pax-Web was a bit "brute-force" but requires the container to give back valid "bundle" URIs. Looks like JBoss container compared to std. Felix and Equinox works different.
上一篇: Jsp tld文件无法解析
下一篇: OSGi与OSGi WAB捆绑在一起