Beginner starting large OSGi migration - osgi.wiring.package=android.dalvik? - osgi

I have a large Java application that's mostly networking and file processing with lots of DB access. There's no UI. We expose a few web services (embedded Netty) and call some external rest web services. The project is built with Ant. It's about 10 different jars plus maybe 30-40 libraries.
My current task is to move the project to the OSGi framework. I am startling slowly.
Following the examples in "OSGi In Action" chapter 6, I have used the BND ant task to put the entire project into one huge jar file. This worked. I am able to run the program using java -jar. Here's my current .bnd file:
-output: bundle/MerchantServicesBundle.jar
-include: manifest/merchantservices.manifest
Bundle-Name: MerchantServices
Bundle-SymbolicName: com.shopping.services.merchant
Bundle-Version: 4.1
Main-Class: com.shopping.merchant.services.netty.MerchantServices
Class-Path: /home/ppantera/repositories/MerchantJava/modules/MerchantServices/conf/
Private-Package: *
I am using Apache Felix 4.0.3. From the Gogo shell I can install the bundle but when I start it I get this:
org.osgi.framework.BundleException: Unresolved constraint in bundle com.shopping.services.merchant [8]: Unable to resolve 8.0: missing requirement [8.0] osgi.wiring.package; (osgi.wiring.package=android.dalvik)
Why does Felix think this is an Android project?
There doesn't seem to be much about this on the 'net. Would you recommend using an older version of Felix so I'm sheltered from the newer OSGi features that could cause me confusion?
I tried adding this to my .bnd file:
Require-Capability: osgi.ee; filter:="(&(osgi.ee=JavaSE)(version>=1.7))"
That didn't help. What am I doing wrong? Any other pointers?

It looks like somehow bnd detected a requirement to an Android package, and added that to the MANIFEST.MF, it could be in your code, but could also be in one of your 3rd party libraries.
Check your manifest to be sure, I guess you'll find something like
Import-Package:android.dalvik.
If that's the case you can test the bundle by manually removing that header and see if that helps. When you've got that clear, you can resolve it for example by making that import optional in bnd.

One of easy solution is:
Go to FuseESB console:
Type the command:
osgi:install mvn:commons-io/commons-io/2.1
Replace 'common's-io' with your your dependency's group id and artifact id (Maven)
e.g my dependency was:
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>
Cheers

Related

Maven (Tycho) cannot resolve OSGi Core bundle

I have a dependency on "org.osgi:osgi.core" (7.0.0) in my POM. The reason is that I need access to the "org.osgi.framework" package. I am using Maven (3.6) and Tycho (1.5.1) for building. The build platform runs Debian 10 and Java 11.
I get the following error:
Missing requirement: osgi.core 7.0.0.201802012106 requires 'osgi.unresolvable; (&(!(must.not.resolve=*))(must.not.resolve=*))' but it could not be found
However, if I remove the dependency I get the following error:
Missing requirement: my.bundle 0.0.0.qualifier requires 'java.package; org.osgi.framework 1.7.0' but it could not be found
What is going wrong? How can I resolve this problem?
I get the following error:
Missing requirement: osgi.core 7.0.0.201802012106 requires 'osgi.unresolvable; (&(!(must.not.resolve=*))(must.not.resolve=*))' but it could not be found
The "companion jars" are not meant for runtime and since resolving is a runtime operation (even when performed during build, i.e. for deployment purposes) should not be included (and are therefore marked with the unresolvable requirement).
However, if I remove the dependency I get the following error:
Missing requirement: my.bundle 0.0.0.qualifier requires 'java.package; org.osgi.framework 1.7.0' but it could not be found
This means you have no runtime framework available! Add a runtime dependency on the equinox framework (not intentionally being biased, but since you're using tycho I'm assuming eclipse/equinox landscape. If you have Apache Felix framework available to p2/tycho then use that if you like):
<dependency>
<groupId>org.eclipse.platform</groupId>
<artifactId>org.eclipse.osgi</artifactId>
<version>3.x.0</version>
<scope>runtime</scope>
</dependency>
// of course use tycho mechanism for above.

Added dependency in Gradle, Liferay says "Unresolved requirement: Import-Package"

I wrote a Liferay module and deployed it successfully.
Then I added this line in build.gradle's dependencies section:
compileOnly group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.3'
After running ./gradlew eclipse I can use the library with no problem in Eclipse. But deployment fails:
12:29:35,454 WARN [fileinstall-/home/nico/liferay/osgi/modules][org_apache_felix_fileinstall:103] Error while starting bundle: file:/home/nico/liferay-dxp-digital-enterprise-7.0-sp3/osgi/modules/de.nico.mymodule-1.0.0.jar
org.osgi.framework.BundleException: Could not resolve module: de.nico.mymodule [1085]_ Unresolved requirement: Import-Package: org.apache.http; version="4.5.3"_ [Sanitized]
at org.eclipse.osgi.container.Module.start(Module.java:429)
at org.eclipse.osgi.internal.framework.EquinoxBundle.start(EquinoxBundle.java:402)
at org.apache.felix.fileinstall.internal.DirectoryWatcher.startBundle(DirectoryWatcher.java:1253)
at org.apache.felix.fileinstall.internal.DirectoryWatcher.startBundles(DirectoryWatcher.java:1225)
at org.apache.felix.fileinstall.internal.DirectoryWatcher.doProcess(DirectoryWatcher.java:512)
at org.apache.felix.fileinstall.internal.DirectoryWatcher.process(DirectoryWatcher.java:361)
at org.apache.felix.fileinstall.internal.DirectoryWatcher.run(DirectoryWatcher.java:312)
I have no idea why it is looking for org.apache.http and not org.apache.httpcomponents.
Here is my bnd.bnd:
Bundle-SymbolicName: de.nico.mymodule
Bundle-Version: 1.0.0
Liferay-Require-SchemaVersion: 1.0.0
How to investigate this problem?
I don't want to download/add the JAR manually.
In your bnd.bnd
add this code ..
Import-Package:\
!org.apache.*,\
\
*
the further investigations will start at the exception messsage. It says that the following requirement is not present at RUNTIME:
Import-Package: org.apache.http; version="4.5.3"
I'm assuming that it's one of the following:
you didn't deploy the httpcomponents (or a version you need .. see Semantic Versioning) libraries to Liferay (as compile works, while deployment fails)
httpcomponents might not be packaged as OSGi bundles. In that case you'll have to decide how to make the code available. Good starting points for more information are the official docs (thanks Andrea, promoting this from the comments) and David Nebinger's blog article
How you add those dependencies to Liferay's runtime is up to you. If the dependencies are OSGi bundles, you can download&deploy them directly. If they're no OSGi bundles, follow one of the techniques described in the linked articles.

OSGI bundle dependency issue

I have got the project for migration. Currently, version is CQ5.6. Maven build is deploying successfully. However, after build, bundles in osgi show in installed state. Two dependencies causing the issue.
org.apache.felix.shell,version=[1.0,2) -- Cannot be resolved
I was getting an error earlier as below during build.
ERROR
[INFO] --- maven-bundle-plugin:2.3.4:bundle (default-bundle) # myPRJ-taglib ---
[ERROR] Error building bundle com.mypack.deewealth:myPRJ-taglib:bundle:1.0.0-SNAPSHOT : Unresolved references to [org.apache.felix.shell] by class
(es) on the Bundle-Classpath[Jar:dot, Jar:OSGI-INF/lib/recaptcha4j-0.0.8-kohsuke-1.jar, Jar:OSGI-INF/lib/commons-io-2.1.jar, Jar:OSGI-INF/lib/commons-
lang-2.4.jar, Jar:OSGI-INF/lib/crx-packagemgr-1.0.22.jar, Jar:OSGI-INF/lib/squeakysand-osgi-0.4.0.jar, Jar:OSGI-INF/lib/jsoup-1.6.1.jar, Jar:OSGI-INF/
lib/stax-api-1.0-2.jar, Jar:OSGI-INF/lib/org.apache.sling.settings-1.1.0.jar, Jar:OSGI-INF/lib/cq-compat-runmode-0.2.0.jar, Jar:OSGI-INF/lib/commons-c
ollections-3.2.1.jar, Jar:OSGI-INF/lib/squeakysand-jsp-0.4.0.jar, Jar:OSGI-INF/lib/squeakysand-commons-0.4.0.jar]: [org/apache/sling/settings/impl/Run
ModeCommand.class]
To solve this I added below dependancy in pom.xml, as we added in
Dependency
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.shell</artifactId>
<version>1.4.2</version>
<scope>provided</scope>
</dependency>
Under import statement.
<Import-Package>
....
....
org.apache.felix.shell
</Import-Package>
After that, build was successful, but bundle was in resolved state because of
org.apache.felix.shell,version=[1.0,2) -- Cannot be resolved
Any suggestion, why this is causing the problem.
org.apache.felix.shell,version=[1.0,2) -- Cannot be resolved
mean that you are trying to use these felix packages from within AEM. However - there are no OSGi bundles in AEM that exports these packages.
You can download the bundle from maven repo and upload it into the AEM Felix console and use it.
OR you can create it as your parent pom dependency as one of module and wrap along with your project jar and use it.
To veify the availability of any package and dependencies use AEM Dependency finder.
I don't know CQ but I can explain why this happens in general. You had the error during build time because of missing dependency. You correctly solved it by adding the dependency which fixed your build. What happened behind the scenes is your bundle was updated with information that it needs (imports) org.apache.felix.shell,version=[1.0,2) package and that package will be provided by some other bundle at runtime.
Then at runtime the resolver got that information and tried to find a bundle that provides (exports) org.apache.felix.shell,version=[1.0,2) package. It couldn't find one and so the resolution failed and your bundle was left in installed (I believe that's what you meant to write instaed of resolved in your last sentence) state!
To solve that, you need to make sure org.apache.felix.shell,version=[1.0,2) package is available at runtime. I don't know CQ and how to install bundles in it but since you can install your own bundle I assume you can also install org.apache.felix.shell bundle the same way.
The shell jar you have installed is still unresolved as it depends on some jars that might not be present. You need to find the depth of all dependencies and resolve them.

JBoss Fuse vs. standard Maven dependency

I'm just learning OSGi, JBoss Fuse (6.1) and Karaf. How can I use a standard (not bundle) Maven dependencies without changing them?
I have a simple Maven bundle project. It depends on some third party libraries. It uses them via its blueprint.xml . I understand if the manifest.mf marks packages in the Import-Package entry then there have to be installed bundle with Export-Package in its manifest.mf. In my case if I install these standard Maven projects they won't export the required packages. So I've got the "Unresolved constraint in bundle" error message during the installation. Is the Maven Bundle or Shade plugin able to solve this issue? Or if they can't which is the most elegant way to resolve the dependencies?
Somewhere I've read the Jboss Fuse is able to resolve dependencies from the Maven repository. Can I use this mechanism somehow?
Thank you!
This may be a bit late now, but you can do that using features.
<features>
<feature name="wrap_features" version="1.0">
<bundle>mvn:org.apache.commons/com.springsource.org.apache.commons.logging/1.1.1</bundle>
<bundle>wrap:mvn:org.jdbi/jdbi/2.70</bundle>
<bundle>wrap:mvn:com.microsoft/sqljdbc4/4.2</bundle>
<bundle>wrap:mvn:org.springframework/spring-web/4.2.4.RELEASE</bundle>
<bundle>wrap:mvn:org.springframework.security/spring-security-core/4.0.3.RELEASE</bundle>
<bundle>mvn:com.doi.ws/mssql-fragment/1.0.0</bundle>
<bundle>mvn:com.doi.ws/mssql-impl/1.0.0</bundle>
<bundle>mvn:com.doi.ws/doi-services/1.0</bundle>
</feature>
</features>
You install the features before deploying your project to the fuse server using the features command
Meanwhile I found an almost good solution: with wrap: namespace/prefix Fuse automatically generates a bundle during installation:
osgi:install -s wrap:mvn:cglib/cglib/2.2.2
But I still have to install each dependency manually. Is there any way to automatize the installation of dependencies?
Thx!
Use Bundle-ClassPath manifest header.
Make sure all your maven dependencies are available in the final jar file under a single directory called 'lib'.( This can be achieved using maven resources plugin that copies maven dependencies in any output directory).
Use maven-bundle-plugin and customize the bundle manifest Bundle-ClassPath attribute with its element. Add a path to lib folder so that all the plain vanilla jars are available as a part of bundle classpath.

Karaf development

Im currently develop bundles for karaf and have some questions...
I wrote a bundle/webservice based on cxf, I try to deploy it in karaf but it could not start that bundle because it could not resolve some packages e.g.
org.osgi.framework.BundleException: Unresolved constraint in bundle org.springframework.aop [56]: Unable to resolve 56.0: missing
requirement [56.0] package; (&(package=org.aopalliance.aop)(version>=1.0.0)(!(version>=2.0.0)))
so here is a question, this package dependency comes from spring-aop (3.1.0.RELEASE), so where is the problem? what dependency is missing? how can I solve such problems?
In that case i did not clearly understand the development process. should i deploy all missing bundles in deploy? because i would like to keep thirdparty libs spereated from my developed bundles. And what bundles i have to deploy? Is it a trial and error process? Is there a common way to let maven do the dependency stuff?
I discovered a folder "system" and read on the docu that it is a repository like maven, is it for the features?
I had for test cases a karaf with some pre deployed bundles and put my webservice bundle into it, but again execeptions...
Caused by: java.lang.ClassNotFoundException: javax.servlet.http.HttpServlet
What dependency is missing?
I already read the tutorial about camel and karaf, but it did not explain the deployment stuff, so could anyone suggest me a good tutorial?
Thanks!
Chris
Short answer
Scroll down to the bit referring to "camel-cxf" and run the two commands features:addurl and features:install. I have a feeling this will resolve all your problems.
spring-aop
On Karaf console type:
exports | grep org.aopalliance.aop
I think you'll see lines like:
XX org.aopalliance.aop; version=3.1.0.RELEASE
So while the spring-aop bundle has the right packages they're the wrong version, the range being requested is >=1.0.0 and <2.0.0, so 3.1.0 doesn't satisfy that.
Deploying/Installing
You can drop bundles into ${karaf.home}/deploy or use the console.
You can install maven bundles from the Karaf console with:
install -s mvn:groupId/artifactId/version/packaging/classifier
Where -s starts the bundle and packaging/classifier are optional.
You can find a lot of OSGi ready maven dependencies here http://ebr.springsource.com/repository/app/ - I had a quick look but your spring aop dependency is very old, what version of CXF are you using?
Read up about Karaf features - they're basically XML files that list suites of bundles that can be installed. Very useful for deploying large numbers of bundles and they can be installed into a maven repository.
There are some standard features available in Karaf, try:
features:install war
This will give you a jetty webcontainer and may resolve your ClassNotFoundException: javax.servlet.http.HttpServlet as long as it's the right version
Camel also has a features file which probably sort all your issues, try this:
features:addurl mvn:org.apache.camel.karaf/apache-camel/2.9.0/xml/features
features:install camel-cxf
Tutorials
There's quite a bit available, some on http://karaf.apache.org and http://fusesource.com but also take a look at the PDF manual that comes in the Karaf distribution.
Always beware that info may be out-of-date
Please post your MANIFEST.MF file. I think you didn't not mention the tag in maven-bundle-plugin dependency.

Resources