3 Replies Latest reply on Dec 21, 2012 5:23 AM by jrantav

    Converting WAR to OSGi world: what to do with embedded dependencies

    jrantav

      This relates to JBoss 7.2 snapshot.

       

      I have a war that I need to move to OSGi world to introduce OSGi dependencies,so I've added an OSGi manifest to it.

       

      However the war has also embedded, standard maven dependencies that are in WEB-INF lib folder, like standard wars do. How should I refer to those in OSGi manifest?

       

      Accoring to these stackoverflow discussions:

       

      http://stackoverflow.com/questions/1593074/how-can-i-combine-war-packaging-and-osgi-bundle-creation-in-maven

      http://stackoverflow.com/questions/4842749/osgi-generate-bundle-classpath-in-maven-bundle-plugin

       

      this should do the trick:

       

      <Bundle-ClassPath>.,WEB-INF/classes</Bundle-ClassPath>

      <Embed-Directory>WEB-INF/lib</Embed-Directory>

      <Embed-Dependency>*;scope=compile|runtime</Embed-Dependency>

      <Embed-Transitive>true</Embed-Transitive>

       

      but it doesn't seem to, I still get classnotfoundexceptions. The only way I was able to make it work was to do

       

      <Bundle-ClassPath>.,WEB-INF/classes,WEB-INF/lib/jdom-1.1.jar{,all other dependencies..}</Bundle-ClassPath>

       

      so I'd need to add each and every internal dependency jar manually to Bundle-Classpath. Is this how it is meant to be and Embed-Directory will not be supported?

        • 1. Re: Converting WAR to OSGi world: what to do with embedded dependencies
          thomas.diesler

          Embed-* is not a standard OSGi header. This seems to be a tools issue - maybe you need to ask there.

          • 2. Re: Converting WAR to OSGi world: what to do with embedded dependencies
            jrantav

            Ah. Correct. From http://felix.apache.org/site/apache-felix-maven-bundle-plugin-bnd.html

             

            The plugin uses the <Embed-Dependency> instruction to transform the project dependencies into <Include-Resource> and <Bundle-ClassPath> clauses, which are then appended to the current set of instructions and passed onto BND. If you want the embedded dependencies to be at the start or middle of <Include-Resource> or <Bundle-ClassPath> then you can use {maven-dependencies}, which will automatically expand to the relevant clauses.

             

            Thanks.

            1 of 1 people found this helpful
            • 3. Re: Converting WAR to OSGi world: what to do with embedded dependencies
              jrantav

              For the interested...

               

              To take advantage of those directives, on maven pom, one would transform this kind of pom directive:

               

              <plugin>
                  <groupId>org.apache.maven.plugins</groupId>
                  <artifactId>maven-war-plugin</artifactId>
                  <configuration>
                      <archive>
                        <manifestEntries>
                          <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
                          <Bundle-ClassPath>
              .,
              WEB-INF/classes,
              WEB-INF/lib/slf4j-api-1.6.6.jar,
              WEB-INF/lib/aopalliance-1.0.jar,
              WEB-INF/lib/aspectjrt-1.6.10.jar,
              WEB-INF/lib/spring-aop-3.1.3.RELEASE.jar,
              WEB-INF/lib/spring-asm-3.1.3.RELEASE.jar,
              WEB-INF/lib/spring-beans-3.1.3.RELEASE.jar,
              WEB-INF/lib/spring-context-3.1.3.RELEASE.jar,
              WEB-INF/lib/spring-context-support-3.1.3.RELEASE.jar,
              WEB-INF/lib/spring-core-3.1.3.RELEASE.jar,
              WEB-INF/lib/spring-expression-3.1.3.RELEASE.jar,
              WEB-INF/lib/spring-web-3.1.3.RELEASE.jar,
              WEB-INF/lib/spring-webmvc-3.1.3.RELEASE.jar,
              WEB-INF/lib/org.eclipse.gemini.blueprint.core-1.0.2.RELEASE.jar,
              WEB-INF/lib/org.eclipse.gemini.blueprint.extender-1.0.2.RELEASE.jar,
              WEB-INF/lib/org.eclipse.gemini.blueprint.io-1.0.2.RELEASE.jar
                          </Bundle-ClassPath>
                          <Bundle-ManifestVersion>2</Bundle-ManifestVersion>
                          <Bundle-Version>1.0.0.SNAPSHOT</Bundle-Version>
                          <Import-Package>
                            javax.annotation,
                            javax.servlet;version="[2.5,3.0]",
                            javax.servlet.http;version="[2.5,3.0]",
                            org.osgi.service.http,
                            org.osgi.service.packageadmin,
                            org.osgi.framework;version="[1.5,2.0)",
                            org.jboss.logging;version="[3.0,4.0)",
                            fi.eis.applications.jboss.poc.osgiservice.api;version="[0.0,1.0)",
                            fi.eis.applications.jboss.poc.compositeservice.gemini.api
                          </Import-Package>
                          <Private-Package>fi.eis.applications</Private-Package>
                          <Web-ContextPath>/spring-app</Web-ContextPath>  
                        </manifestEntries>
                      </archive>
                  </configuration>
              </plugin>
              

               

              into this:

               

              <plugin>
                  <groupId>org.apache.maven.plugins</groupId>
                  <artifactId>maven-war-plugin</artifactId>
                  <configuration>
                      <archive>
                        <!-- add the generated manifest to the war -->
                        <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
                      </archive>
                      <failOnMissingWebXml>true</failOnMissingWebXml>
                      <packagingExcludes>WEB-INF/web.xml</packagingExcludes>  
                  </configuration>
              </plugin>
              <plugin>
                  <groupId>org.apache.felix</groupId>
                  <artifactId>maven-bundle-plugin</artifactId>
                  <extensions>true</extensions>
                  <executions>
                    <execution>
                      <id>bundle-manifest</id>
                      <phase>process-classes</phase>
                      <goals>
                        <goal>manifest</goal>
                      </goals>
                    </execution>
                  </executions>
                  <configuration>
                      <supportedProjectTypes>
                        <supportedProjectType>jar</supportedProjectType>
                        <supportedProjectType>bundle</supportedProjectType>
                        <supportedProjectType>war</supportedProjectType>
                      </supportedProjectTypes>
                      <instructions>
                          <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
                          <Bundle-ClassPath>.,WEB-INF/classes,{maven-dependencies}</Bundle-ClassPath>
                          <Bundle-ManifestVersion>2</Bundle-ManifestVersion>
                          <Embed-Directory>WEB-INF/lib</Embed-Directory>
                          <Embed-Dependency>*;scope=compile|runtime</Embed-Dependency>
                          <Embed-Transitive>true</Embed-Transitive>
                          <Import-Package>
                            javax.annotation,
                            javax.servlet;version="[2.5,3.0]",
                            javax.servlet.http;version="[2.5,3.0]",
                            org.osgi.service.http,
                            org.osgi.service.packageadmin,
                            org.osgi.framework;version="[1.5,2.0)",
                            org.jboss.logging;version="[3.0,4.0)",
                            fi.eis.applications.jboss.poc.osgiservice.api;version="[0.0,1.0)",
                            fi.eis.applications.jboss.poc.compositeservice.gemini.api
                          </Import-Package>
                          <Private-Package>fi.eis.applications</Private-Package>
                          <Web-ContextPath>/spring-app</Web-ContextPath>  
                      </instructions>
                  </configuration>
              </plugin>
              

               

              and then maven-bundle-plugin will generate equal manifest, and the app works without issues. Highly valuable knowledge.

              1 of 1 people found this helpful