I want to create an OSGi bundle for log4j2. I need to use some additional jars along with log4j2 such as log4j2-jcl, log4j2-jul, log4j2-web etc. I want to clarify some confusions listed below about this.
However this is not specific to log4j2 I'm asking this as a general procedure.
Do I need to create separate OSGi bundles for each jar or can I use one bundle for all the jars? (What is the best practice)
How can I know whether OSGi bundles are already available for these jars ? (So that I don't need to re create bundles, can use existing ones)
I'm quite new to OSGi so can anyone please clarify these things no need to specific for log4j2.
Thanks!
Do I need to create separate OSGi bundles for each jar or can I use one bundle for all the jars? (What is the best practice)
I recommend to create one bundle per JAR, if possible. This gives you the greatest flexibility and makes sure that each JAR is properly designed.
How can I know whether OSGi bundles are already available for these jars ? (So that I don't need to re create bundles, can use
existing ones)
Just have a look at the Manifest file.
If it contains the OSGi Metadata -> it's a OSGi bundle.
If it doesn't contain the OSGi Metadata -> it's not a OSGi bundle.
I think the Log4J JARs already provide the OSGi Metadata (-> they are already bundles), but I haven't double-checked.
just a recommendation.
before you do any bundle, check if it exists.
https://jpm4j.org/#!/search?q=log4j2
also, I recommend slf4j
Related
Maybe it is a silly question, but what is the best way to test if a Java Archive (jar) file is an OSGi bundle? That is, what are the minimal requirements for the jar to be fully compatible? Is it the mere presence of a META-INF/MANIFEST.MF (I don't think so)? If not, what are the minimal fields that must be provided by this file?
Practically, how should I test if the jar is an OSGi jar?
Look for the Bundle-SymbolicName header in the MANIFEST.MF. This is the only mandatory header in an OSGi bundle, at least since Release 4.0 of the OSGi specification. Therefore if the Bundle-SymbolicName header is defined, then the JAR is an OSGi bundle. If not, then it is just a JAR.
A bundle is a group of Java classes and additional resources equipped with a detailed manifest MANIFEST.MF file on all its contents, as well as additional services needed to give the included group of Java classes more sophisticated behaviors, to the extent of deeming the entire aggregate a component.
The OSGi spec describes the bundle as a "unit of modularization" that "is comprised of Java classes and other resources which together can provide functions to end users.".
a bundle is a JAR file that:
Contains [...] resources
Contains a manifest file describing the contents of the JAR file and providing information about the bundle
Can contain optional documentation in the OSGI-OPT directory of the JAR file or one of its sub-directories
In short, a bundle = jar + OSGI information (specified in the JAR manifest file - META-INF/MANIFEST.MF), no extra files or predefined folder layout are required.
I guess the only qualification be required is that there are a bundle of classes and that it contains a MANIFEST.MF file which contains valid OSGi headers.
Consider this link
As well as this
Answering your question, the only way to test the bundle it to check if the MANIFEST.MF file exists and contains valid headers.
How can resource of a bundle be shared with other bundle(but not just one)?
For example I don't want to duplicate the images or properties file to all bundles, instead I want to access them from a single place.
I tried to use Fragment-Host, but there is not possible to specify multiple bundles(at least I do not know how)
eg:
<!-rest of the pom-->
<instructions>
<Fragment-Host>
com.bundlehost
</Fragment-Host>
</instructions>
As Dmytro notes, you can use OSGi API methods to access the resources in any bundle. However the harder question is this: how do you know from which bundle to access these resources, and how do you know where they are located within the bundle?
If you just make assumptions or hard-code the answer, then you end up with a very brittle system and a hidden coupling between the bundles. Then when somebody deploys your bundles into an application but doesn't include the resource bundle, everything breaks. This defeats the point of modularity.
You can use Bundle.getEntryPaths() and Bundle.getEntry() to get bundle resources. To read content use URL.openStream()
You can also use normal package imports and exports to ensure the resources are on the class path of the consuming bundle. See, for example, access common property file inside bundle with osgi.
I am developing a simple web application, using Spring Framework.
When I add Spring framework to my class path, I see that it has lot of jars which I never use (for example: spring-aop-3.2.3.RELEASE.jar).
Is it a good idea to keep the entire framework intact or remove unused jars?
If you need to remove unused jars, the best way is to use some dependency management tool like Ivy or Maven, and let the tool decide what the required dependencies are. Otherwise it will not be apparent what is really unused or not until you break something.
For instance, if you are using declarative transactions, then removing the AOP jar will cause breakage, because AOP is used to implement that functionality.
If you would rather not use dependency management, it's better to leave everything intact.
There are some cases where you do want to remove/exclude jars. Replacing commons-logging with slf4j is one example. Another example is excluding the log4j dependencies that get dragged in on account of some appender that's packaged with log4j but that you know you will never use. Dependency management tools allow you to tell them what needs to be excluded.
Doing without dependency management management and removing things because you never use them directly is too dangerous.
I am learning osgi framework. It says osgi works on strict class loading environment. I am unable to get what is Strict ClassLoading. Please help i am unable to get the concept
Thanks
Strict classloading means that a module (bundle) has to explicitly specify what it needs. In OSGi this is done using Manifest headers. Import-Package lists the packages and their version ranges the bundle needs and Export-Package lists the packages and their versions the bundle offers. In the OSGi runtime you then have a classloader per bundle that wires the bundles according to the exports and imports.
You should not define these headers by hand though. There is a nice tool named bnd or in maven the maven bundle plugin from felix which does most of the work for you. In this tutorial you find how this works in practice:
http://www.liquid-reality.de/x/DIBZ
You will see that I actually do not define to much by hand there. So build the code and into the meta-inf/Manifest to see what it does.
strict class loading environment means that the appropriate headers of the class need to be specified. for example the class path and the import-package
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)