web.xml in OSGi container - spring

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)

Related

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).

How do I start a specific bundle in my own OSGi application deployed in WAS 8.0?

I have quite a sophisticated OSGi application which uses Declarative Services and was designed to be deployed in Equinox. Now the task is to make this application be deployable in WAS 8.
The first try was quite pragmatic: I have deployed an EAR which has started basically the same Equinox and after some WAS class loading policy tweaks it has worked.
Now I want to go further: get rid of the Equinox runtime and deploy my bundles "natively" in WAS 8. So I have composed an EBA, consisting out of my business bundles, their dependencies and Equinox DS runtime. The EBA is deployed as an asset and integrated into a BLA. The application has even started and runs but the components are not initialized.
The point is that one has to start equinox.ds in front of the own business bundles (UPDATE: not a must, s. discussion below) in order to make DS do its job. But how do I tell the bundles which is to be started first within the deployed EBA? I need some analog of Equinox' config.ini file.
I know I can rewire my components with natively supported Blueprint, but frankly this is the last thing I'd like to do. It should be possible to make Equinox DS work, shouldn't it?
Another question is: how to get the OSGi console for one's own application deployed under WAS 8? I want to control my bundles but seems that there is no way to do it from the Management Console.
UPDATE
Thanks to BJ and Neil (s. discussion below), the question takes down to "How do I start a specific bundle in my own OSGi application deployed in WAS 8.0?"
To answer the OSGi console part of your question, a normal OSGi console won't work because the OSGi applications are managed in nested frameworks. WebSphere provides its own console which can navigate the nested applications: http://pic.dhe.ibm.com/infocenter/wasinfo/v8r0/index.jsp?topic=%2Fcom.ibm.websphere.osgi.nd.multiplatform.doc%2Ftopics%2Fta_admin_runtime_console.html

Branding Apache Felix web console

I am trying to brand a Apache Felix web console, but I am not able to find resource for the same. As per Apache Felix website,
Branding for the Web Console can be provided in two ways: By registering a BrandingPlugin service or by providing a branding properties files. The Web Console uses the branding from the BrandingPlugin service registered with the highest ranking.
But I am not understanding how to register a BrandingPlugin service? What and Jar files should I put? Is there any guidance or tutorial available for the same? If yes, can you guide me in this?
Since I am totaly getting confused with Apache Felix's website, since those documents are not clear on this.
You may find it helpful to do some background reading on OSGi services. OSGi provides a service registry, and most interactions in an OSGi environment are handled by registering and consuming services. It doesn't matter what jar file you put the service in; the only thing that matters is the interface name its registered under.
You can register services in lots of ways; programmatically from a BundleActivator, using Declarative Services (also known as SCR), and using Blueprint are some of the most popular patterns. Which one is easiest for you depends on how you're building your jars and what other OSGi facilities you're using. If you've already got an Activator the programmatic route may be the quickest way to get started; if you're using the Maven bundle plugin you may find SCR annotations easiest.
What you'll need to do is include an implementation of the 'BrandingPlugin' interface in a jar which gets started by your OSGi runtime, and register that implementation as an OSGi service. Once you've done this you should see that the Felix console discovers your BrandingPlugin implementation and uses it.

Restlet converter registration in OSGI environment

We run Restlet 2.1 in an OSGi environment (Equinox) as bundle (ie. not as library within a bundle). The problem is that the Restlet Engine does not detect helpers (like converters) that are provided by Restlet extensions. Specifically, the EngineClassLoader#getResources() call does not return any result. The extensions are also deployed as OSGi bundles in the target platform.
Is automatic converter registration actually supposed to work within OSGi environments?
In fact, Restlet supports such feature thanks to a dedicated activator (see the Activator class in the package org.restlet.engine.internal).
This activator introspects bundles to find out the following things:
servers corresponding to registered servers
servers corresponding to registered clients
authenticators corresponding to registered clients
converters
Be aware that to use this feature, we must use the OSGi edition of Restlet since it's the only that has the MANIFEST file of the org.restlet bundle with the activator class specified. Otherwise you don't have to care about the bundle loading order...
Hope it helps you.
Thierry
Unless the Restlet-bundle explicitly imports the packages that contain the extensions (and I doubt it does, and it shouldn't), it wouldn't be able to load them, because bundles have isolated class-spaces.
A possible solution would be to provide the extensions as fragments attached to the Restlet-bundle. Thus, if you make it use the bundle-classloader (the documentation says this can be done by setting the Engines classloader), it would be able to load classes from the fragments.
Indeed it doesn't quite work for OSGi, as it depends on the ability to see the entire class space.
The way to do this in OSGi would be to use the service registry for the extensions, but that only works for OSGi aware libraries.
There is some help on the way: In the recently released OSGi 5 (Service Loader Mediator) there will be support to 'bridge' META-INF/services (I don't know if Restlet uses those, though) onto OSGi services, so 'legacy' libraries should work well within OSGi.
There is an implementation in Apache Aries called Spi-Fly. I looked at it briefly a while back. It might do the trick for you, it might not.

Is an OSGi service still "OSGi managed" when it's obtained by non-OSGi code?

As an OSGi newbie, I'm trying to wrap my head around the boundaries of the OSGi runtime. My app, which is not build on OSGi, i.e. it's not running in an OSGi container, starts an OSGi container into which we deploy OSGi bundles at run time. Some of these bundles register services. Later, in our non-OSGi code, we obtain those services and use them.
I'm having trouble wrapping my feeble mind around the OSGi boundaries here. To be specific, when I obtain a service and invoke one of its methods, can I assume that all of the subsequent execution is executing within the OSGi container (Felix)? In other words, are dependencies in that code resolved via the OSGi modularity mechanisms? Or did I lose that OSGi management because I am using the service from non-OSGi code?
If my question seems founded in obvious mistaken assumptions about OSGi, please feel free to point them out.
Chad, to more effectively answer your question, I'd like to know a few things:
1) How exactly are you getting the service reference from an external application?
2) Is the external application a stand-alone application, or is it inside of a different container? If so, there are ways to make that happen.
The question you pose is interesting. Lets put it into a context. Lets assume you are able to get a reference to an OSGi service from Felix by an external application. When you use this service, you will be interacting with it via an interface. In that interface in OSGi, you will have import statements referenced which will be used in the method signatures of the interface and also in any final attributes. These import statements will have thier matching dependant libraries defined in your pom.xml file.
In order to use the service by an external application, you will need to publish an API ".jar" file that will contain the interface, and will reference the interfaces' dependancies. Your external application will need to use that API, and will likely have it assembled into your .war, .jar, or .ear file's lib directory. Because of this, none of your external application's dependancies can conflict with your API dependancies.
As long as you can use the API, then you're right, none of the SPI's dependencies matter. You can use Spring 3.0.4.RELEASE in your external app and still use Spring 2.5.6.SNAPSHOT in your OSGi application. As long as the API doesn't have any dependancies that conflict with the external application, you should be ok. The trick here is that you need to put your interfaces into a minimal .jar file as your API, and then put your implementation details into an SPI. Your external ap will use the API, and inside OSGI, you will use both the API and SPI.
Please let me know if this helps.
If you can get the service, then the dependencies are satisfied by definition, because bundles cannot provide services unless their dependencies are satisfied. Executing services on the outside doesn't really change anything.

Resources