How to make Axis2 run in an OSGi environment? - osgi

I need to access an webservice in an OSGi-Environment (Equinox). I do already have the code for using the webservice as a stand-alone application.
The sample code uses Axis2 this seems to be a problem as I need to add all required libraries as separate bundles. This does not work with Axis2 because the jar files provided by the project are not prepared for OSGi.
I tried to "bundelize" the JAR files via BND but in the end the bundles do not work because of a "Package uses conflict error: org.apache.axis2.addressing"
How to I make Axis2 OSGi-aware?
Alternatively - what is a simple and fool-proof variant for accessing a (soap) webservice in Equinox (plain not Eclipse)? I already tried Apache CXF which failed because it looks like it tries to generate code at runtime and Axis2 is also very difficult as my post shows.

You should consider to embed the Axis2 libraries (and dependencies) into your bundle. In this case Axis2 will not be deployed as own bundle - instead the classes/jars will be copied to into your bundle.
If you are using maven to build your bundle you should have a look at the maven-bundle-plugin and the Embedding dependencies section.
I also would recommend to have a closer look if no OSGi enabled Axis2 libraries are around (I do not use it, so I don't know it but a quick search results in org.apache.axis2.osgi).

Related

Add external jar in pom.xml

I have a spring boot application with maven.
I need to use an external jar say "tp.jar". I have used the method of system scope to do the same but seems it has been deprecated. Is there any better alternative which doesn't involve running maven commands to do the same. I found some solutions here Can I add jars to maven 2 build classpath without installing them?
But the posts are pretty old was wondering if any new solution and convenient solution has been found.
If you are in a company doing Java, you probably have a Nexus or Artifactory server running. This is the place to put the jar. Then you can use all Maven mechanisms to use it.

WebSphere 7 org.apache.axis2.deployment.WarBasedAxisConfigurator <init> org.apache.commons.fileupload.FileUploadException

This is a strange problem. I have an existing JEE project that is and has been in production on WebSphere 7. It is a multi-module EAR file. It has 2 WARs and 1 shared Java project. Most of it is Spring 4 based, but we have some web services we host using axis2 (1.5.4). This project does not use Maven. It does use a WebSphere deployment.xml (in the EAR) with the warClassloaderPolicy="SINGLE" and the classloader mode="PARENT_LAST". This controls the classloader policies for this EAR. All the jar files that the Java project and the WARs rely on are stored at the EAR level and referenced at the module level via the manifest files. That all works fine and has for several years.
Now I was trying to convert this project to a Maven project after all these years. Initially, I left the deployment.xml file settings as they always have been. But with these settings I was getting:
java.lang.VerifyError at com.sun.xml.bind.v2.model.impl.RuntimeBuiltinLeafInfoImpl "org.springframework.oxm.jaxb.Jaxb2Marshaller".
After much googling on this site and all around and trying 50,000 things, I tried one thing, which worked for most of the app. I switched the classloader mode to "PARENT_FIRST" and all of a sudden the WAR that exclusively uses Spring 4 worked. It started up without error and I was able to run it.
But, the other WAR which hosts the axis2 web services started getting the error:
org.apache.axis2.deployment.WarBasedAxisConfigurator <init> org.apache.commons.fileupload.FileUploadException....Caused by: java.lang.NoClassDefFoundError: org.apache.commons.fileupload.FileUploadException....Caused by: java.lang.ClassNotFoundException: org.apache.commons.fileupload.FileUploadException
This class (org.apache.commons.fileupload.FileUploadException) is in both the compile and runtime classpath. In eclipse I can see it in the "Maven Dependencies" library that the m2e eclipse plugin creates from the POM files. I can also see this jar in the WebSphere runtime module classpath inspector (it shows up in there 3 times! Once under each WAR and once just in a list from the Maven repository location.)
One thing of note is that I've configured the project with a parent POM, where most of the dependencies are declared at the parent and then are inherited for each of the modules. In the EAR project, the POM is using the maven-ear-plugin with skinnyWars=true. However, it appears the skinnyWars directive is not respected when the m2e eclipse plugin deploys the EAR into the local WebSphere server (that is evident because I see these jars showing up in the classpath 3 times). But when I create an EAR using the Maven build, the EAR comes out correctly with each jar only showing up in the EAR one time.
This is my last hope to post something here and see if someone has an idea for something to try, otherwise I can't think of anything else to try.
Thanks...
Is there a particular reason you need to run with a single class loader for all the WAR modules, other than convenience? If not, you could rework the application in order to allow you to run PARENT_FIRST in the Spring WAR and PARENT_LAST in the Axis2 WAR.
If that's not an option for some reason, the path of least resistance might be to go back to PARENT_LAST and remove some libraries from the app or module. The VerifyError generally occurs if you're running with PARENT_LAST and have a library in the app that is also present in the server - in this case, the exception looks like it's coming out of JAXB, so you might want to see if simply removing JAXB (and perhaps JAXP, if present, since it's heavily used by JAXB) from the application resolves the issue with your default setup.
You could also stick with PARENT_FIRST and move the Axis2 jars to an shared library with an isolated class loader, associated with the app. An isolated shared library would make just the stuff in the shared library PARENT_LAST, so you can avoid the VerifyError and still get PARENT_LAST for Axis2. The issue in the PARENT_FIRST case appears to be because you're picking up WebSphere's copy of Axis2 but somehow have a dependency inserted from your app's copy - the failing class load is occurring in a server-level loader, so it doesn't see the copy in your app.

How can I include a resource file (logback.xml) in a project when building JAR but not when embedded in a WAR?

I'm working on a project that uses two maven projects (named core and webapp); core is built with JAR packaging and used for two different purposes: as a stand-alone app (essentially an executable JAR), and also embedded into webapp.
For its purpose as a stand-alone app, core needs to have its own logback configuration (a logback.xml file) that needs to be included on the classpath. Normal Maven convention would have me put it in src/main/resources/logback.xml. That works fine, but causes a problem when the core JAR is included in webapp. webapp needs to have its own logback configuration, but the container (tc Server or Jetty) is picking up the one from core.jar first.
I realize that logback can be told about a custom config location via a system property (-D on the command line) but that's not viable in a app container like Tomcat or Jetty.
I've read some other people asking about this situation, but none of the solutions I've seen sits well with me. One solution involved setting up a context listener that runs early in the webapp initialization and explicitly configures logback based on a <context-param>. That's a bit brutish in my opinion, and probably a hard sell to my fellow dev team when log4j "just works" in this situation.
I'm far from a Maven expert, so I'm hoping there is some elegant way to get Maven to help me here. Or perhaps some logback extension or add-on that makes it more web-app friendly. Or even a clever idea that I haven't thought of.
There are a number of possible solutions, but the easiest is to put the file in its own module and mark the dependency as provided. The, conspire to have it on the classpath when running the standalone version of the app.
The solution that we ended up using was to leave only the common "non-app" pieces (code and configuration) in core and then extract the other "app" pieces into a new module (batch-app).
The logging configuration only lives in the 2 app projects (webapp and batch-app) that depend on core. core has a logback-test.xml configuration in it, but that's excluded from the JAR that maven builds (since it's in the src/test/resources folder).

OSGI Embedded Equinox - Bundle to access pojos not instantiated in osgi framework

I have a server side application and want to embed an osgi framework into for dynamic bundle loading.
Suppose I want to expose a QuoteImpl implementing IQuote(instantiated as part of the server container bootstrap/Spring) to be used by different Bundles.
Q1. Is there a clean way of exposing server-application instances to Bundles ? (btw because of legacy it is not possible to make server code into bundle :) and donot want to make entire application osgi'ed.
Tried exposing via a service and bundle to cast into an IQuote. Not sure I am doing it well but fails with unresolved compilation problems as IQuote resides in the core app projects as opposed to the bundle project. any ideas?
Yes the way to do this is with a service. The "host" application would publish the service and the bundles inside OSGi would consume the service in the normal way.
The key to get this working is that the service API (i.e. the package containing IQuote) must be exported by the host application through the system bundle exports. You can control this by setting the org.osgi.framework.system.packages.extra property when you create the embedded OSGi framework. I wrote a blog post on this subject that should help you get started (look for the heading "Exposing Application Packages").
You state that you have compilation problems. To fix those it's necessary to know how you have structured your projects and build system.
This is how I embedded Equinox OSGi runtime in my Java class. I suppose you could do the same. https://github.com/sarxos/equinox-launcher/blob/master/src/main/java/com/github/sarxos/equinox/Launcher.java

web.xml in OSGi container

pros! Looks like basic question, but I just can't find what I am looking for.
I have Equinox and want to run Spring in it (bootstraped in Servlet).
I can't use dm-server, nor can I use the http-bridge, just plain standalone Equinox.
On the other side, using plugin.xml http registry servlet extension is not good enough, since I need the fully-blown web.xml in order to bootstrap Spring.
Where should I dig?
Thanks!
Baruch.
To support "traditional" (aka legacy) web.xml file for webapp deployment you need an implementation of the OSGi Web Applications spec, part of the OSGi R4.2 Enterprise spec. This will allow you to deploy "Web Application Bundles" (WABs) or even plain old WAR files.
There are implementations of this container in both the Eclipse Gemini and Apache Aries projects. Note that the one found in Eclipse Gemini is also found in Eclipse Virgo (the new name for dm Server). You may find that using Virgo will give you a cleaner out-of-the-box experience rather than having to assemble components yourself. Then again I fully understand if it also provides an awful lot more than you really want!
An alternative to this is to move away from web.xml and to register servlets programmatically with the OSGi HttpService. This should be a lot more lightweight, but I don't know whether it will work for "bootstrapping Spring" — quite a vague requirement.
Or you can use the tomcat OSGi bundle that will make you to be able to load bundles as war files. The problem there is that your web bundle's name must end with ".war" and all that stands before that suffix is the application name. So if your bundle's name is myapp.war you connect to it with http://your.server.cc/myapp (and as far as i know there's no way to change that)

Resources