I am very new to OSGi and Karaf and I am still getting my head around the concepts and architecture.
My question is related to the .kar files which are created with the karaf-maven-plugin.
Does a .kar file meant to only install features into a Karaf runtime? What if we create a bundle and rename it to .kar instead of .jar. Is this a valid use case for .kar files?
Thanks
No, a kar file is much more than that as it is a mechanism to provide not only the features.xml but also any related OSGi bundles, configuration files, aso. inside a single artifact.
That's also why it contains a mandatory repository/ directory (basically containing all OSGi bundles necessary for any of the features described by the features.xml in a Maven repository-style structure) and an optional resources/ directory (containing all the additional resources referenced by a feature).
For a fully fledged example, you can have a look at the Apache Karaf framework archive:
https://repo1.maven.org/maven2/org/apache/karaf/features/framework/
That one contains all the basic resources that make up the base for a custom Karaf installation and provide the basic set of features:
META-INF/
...
META-INF/MANIFEST.MF
...
repository/
... OSGi bundles referenced by the features and the features.xml itself ...
resources/
resources/bin/
... scripts ...
resources/data/
...
resources/deploy/
...
resources/etc/
... configuration files ...
resources/lib/
... (non-OSGi) libraries needed (e.g. endorsed, extension, boot classpath) ...
resources/system/
... OSGi framework implementation(s) and related libraries ...
Related
Please go through the scenario given below
I have two maven projects abc-common and abc-service
abc-service has dependency on abc-common project.
abc-common is reading from a properties file named myConfig.properties as follows:
class PropertiesUtil {
.....
Properties props = new Properties();
props.load(PropertiesUtil.class.getClassLoader().getResourceAsStream("myConfig.properties"));
....
}
This works fine, when I test by creating a dummy main method in either of the projects.
But when I deploy this project into an OSGI container (JBOSS Fuse), it is not working. The prime reason is, in OSGI container, PropertiesUtil.class.getLoader() is refering to the bundle corresponding to abc-service project and I can read any file from that project, but not from abc-common project.
So the question is that, how can I change my code such that, It can read properties from class path of abc-common project in an OSGI container.
Note
I'm deploying my project as a karaf feature which lists both abc-service and abc-common bundles as dependencies.
Also, I tried different variants like
Thread.currentThread().getContextClassLoader().getResourceAsStream("myConfig.properties")
and
FrameworkUtil.getBundle(PropertiesUtil.class).getEntry("myConfig.properties.")
But none of them worked actually
In OSGi you need to use import|export of packages to allow loading resources from other bundles. Put the properties file into a package which you export from that bundle. And then from the other bundle, you import that package. You should then be able to load the resource from classpath.
Inside ee.j2se-1.8 the package org.w3c.dom is included.
org.osgi.framework.system.packages = \
...
org.w3c.dom,\
...
org.osgi.framework.bootdelegation = \
...
org.w3c.*,\
org.xml.*,\
....
The bundle xml-apis_1.4.1.20140905-131237.jar contains the same package org.w3c.dom, but with one important class more ... ElementTraversal.class more.
So here my questions...
How can I provide the missing class inside my Equinox OSGi runtime?
You are suffering from the fact that people do not take packages seriously. We have a similar problem in the jta API. The version delivered by the VM is not identical to the version that is delivered as a special package.
The solution is to include the JAR with the extra packages on the class path where the framework resides. It looks like you're using bnd (good!) so this would look like:
-runpath: xml-apis__xml-apis;version="[1.4.1,2.0.0)"
If this had been a bundle with proper exports then you would have automatically gotten its exports as system packages. Looking at the packages in this bundle it seems all packages are already in the standard exports of the VM. However, if you have packages int his JAR that are not exported by the VM then you can add them as follows:
-runsystempackages: javax.xml.foo
How to include an xml file in an OSGi bundle with bndtools without the use of maven ?
You can use the -includeresource or Include-Resource directive, which are explained here:
http://bnd.bndtools.org/chapters/820-instructions.html
http://bnd.bndtools.org/heads/include_resource.html
The -includeresource one is preferred. A simple example:
-includeresource: static=static
Includes the resources which are in the 'static' folder of the project into the bundle in the 'static' folder.
I am using wso2 Application Server 5.1.0.
I have deployed my own bundle having name demo-service which contains import-package definition in its manifest as below:
>Bundle-SymbolicName = demo-service
Import-Package = javax.sql,org.apache.commons.dbcp;version="[1.4,2)"
I tried to diagnose the most popular "uses conflict" in OSGi world for my case and I found that commons-dbcp_1.4.0.wso2v1.jar and commons-dbcp-1.4.jar both were converted to OSGi bundle by container and exported their packages with version "0.0.0" which can be observed from the output below:
>osgi> packages org.apache.commons.dbcp
org.apache.commons.dbcp; version="0.0.0"<commons-dbcp_1.4.0.wso2v1 [49]>
compass_2.0.1.wso2v2 [60] imports
org.wso2.carbon.core_4.1.0 [256] imports
org.wso2.carbon.registry.core_4.1.0 [377] imports
org.wso2.carbon.tenant.mgt_2.1.0 [434] imports
synapse-commons_2.1.1.wso2v3 [528] imports
synapse-core_2.1.1.wso2v3 [529] imports
org.apache.commons.dbcp; version="0.0.0"<commons_dbcp_1.4_1.0.0 [57]>
According to the requirement of my demo-service bundle it's not able to find
org.apache.commons.dbcp;version="[1.4,2)"
Is there any way to export the packages of commons-dbcp-1.4.jar after it gets converted from non-osgi bundle to osgi bundle because I need to make sure that my demo-service bundle should wire with commons-dbcp-1.4.jar..
In brief, any version of thirdparty jar I put in WSO2_HOME\repository\components\lib folder container exports it with version="0.0.0" .. which discourages the main concept for classloading of OSGi
please suggest if any workaround is possible in this case .. :)
Thanks ..
When a version is not specified while exporting packages OSGi defaults to version 0.0.0. In this case as it's automatically converting to osgi bundle it might not be having version explicitly specified. Sometimes this also helps to ensure that multiple versions of packages are not present.
In your case as you need to use the packages in the bundle put in repository\components\lib folder you could manually specify the version. The OSGi-fied bundles of the jars you put in repository\components\lib can be found in repository\components\dropins folder. Inside that bundle you will find the OSGi manifest file. In the manifest file manually specify the versions for the required packages under Export-Package category as follows.
org.apache.commons.dbcp;version=1.4.1
Then on startup, it would use these bundles and you should be able to export packages with specified version.
My problem is as follows I use in my WS app Hibernate-entitymanager-3.5.6-FINAL jar, JBOSS 4.2.3 have in his direction hibernate if i am not wrong 3.3.x which make conflict of versions. Don't redirect me to ClassLoader related articles of JBOSS i have read them, and put this in JBOSS_HOME\server\default\deploy\management\console-mgr.sar\web-console.war\WEB-INF\jboss-web.xml
<class-loading java2ClassLoadingCompliance="false">
<loader-repository>
pl.mycompany:archive=hibernate-entitymanager
<loader-repository-config>java2ParentDelegation=false</loader-repository-config>
</loader-repository>
</class-loading>
can anyone give me a hint what am i missing?
See article ClassLoadingConfiguration:
They mention about unique-archive-name
For jboss-service.xml:
<server>
<loader-repository>
com.example:archive=unique-archive-name
<loader-repository-config>java2ParentDelegation=false</loader-repository-config>
</loader-repository>
...
The isolated EAR or WAR repository will load its libraries in this order:
WEB-INF/lib (for WARs)
libraries in server/default/lib
tomcat-libraries in server/default/deploy/jbossweb-tomcat50.sar (jboss-3.2.6).
The libraries in server/default/lib get mixed together with jbossweb-tomcat50.sar in no specific order (for details look into the loader-repository in the JMX-console).
Second solution: Remove hibernate classes from jboss (move to endorsed).