I'm using org.slf4j:slf4j-api:1.7.30 and ch.qos.logback:logback-classic:1.2.3 in one of my bundles (Maven <packaging>eclipse-plugin) via the project's Target Platform definition (i.e. another Maven project with <packaging>eclipse-target-definition).
The slf4j-api JAR's MANIFEST.MF contains:
...
Import-Package: org.slf4j.impl;version=1.6.0
The logback-classic JAR also contains the package org.slf4j.impl and its MANIFEST.MF contains:
...
Export-Package: ...
....................., org.slf4j.impl;versi
on="1.7.25";uses:="org.slf4j,org.slf4j.spi"
...
If I add:
Import-Package: ...
...
org.slf4j,
ch.qos.logback.classic,
org.slf4j.impl
to my bundle's MANIFEST.MF` only the first two are resolved. For the latter Eclipse shows the error:
Bundle 'ch.qos.logback.slf4j' exporting package 'org.slf4j.impl' is unresolved
and the ch.qos.logback.classic_1.2.3.v20200428-2012.jar in my bundle's Plugin-Dependencies folder shows only ch.qos.logback.classic package and sub-packages thereof.
Major question:
Why is org.slf4j.impl not considered exported and hence cannot be resolved?
Minor questions:
Where does the Bundle-SymbolicName in the error message come from?
Where does the qualifier v20200428-2012 of logback-classic's JAR in the Target Platform definition come from? It's MANIFEST.MF doesn't contain this, but just Bundle-Version: 1.2.3.
Why does slf4j-api import org.slf4j.impl? Shouldn't rely an implementation on an API and not vice versa?
UPDATE
I found answers to 2. and 3. (not the first that this happens while writing an SO question :): It's from Eclipse itself: https://ftp.fau.de/eclipse/releases/2021-03/202103171000/plugins/
And this also leads to an answer for 1.: I'm actually not using the orignal slf4j and logback JARs but those from Eclipse and ch.qos.logback.slf4j's MANIFEST.MF contains:
...
Export-Package: org.slf4j.impl;x-internal:=true;version="1.7.30";uses:
="org.slf4j,org.slf4j.spi"
...
So 5. How to get the package org.slf4j.impl exported/imported nevertheless?
Related
I am using plugins org.seleniumhq.selenium.api_3.4.0 and org.seleniumhq.selenium.remote-driver_3.4.0 which were created from respective jars in my OSGi project. While executing the tests I am getting the below exception.
[NoClassDefFoundError: org/openqa/selenium/logging/LoggingHandler, ClassNotFoundException: org.openqa.selenium.logging.LoggingHandler cannot be found by org.seleniumhq.selenium.remote-driver_3.4.0
Stack Trace:
java.lang.ClassNotFoundException: org.openqa.selenium.logging.LoggingHandler cannot be found by org.seleniumhq.selenium.remote-driver_3.4.0
at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:464)
at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:171)
at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
As per my analysis, the issue is coming because the package org.openqa.selenium.logging is present in both org.seleniumhq.selenium.api_3.4.0 and org.seleniumhq.selenium.remote-driver_3.4.0 jars and the LoggingHandler class is present in org.seleniumhq.selenium.remote-driver_3.4.0 jar only. While installing the bundles during startup, the org.seleniumhq.selenium.api_3.4.0 is installed first. So while searching for the class at runtime, the class loader could not find the LoggingHandler class in the plugin org.seleniumhq.selenium.api_3.4.0.
Upgrading the version might resolve the issue because the class LoggingHandler is present in higher versions of org.seleniumhq.selenium.api_3.4.0 jar but I cannot upgrade the version because of other dependency issues.
Is there any other way in OSGi/RCP world to specify which plugin to refer while trying to find the class at runtime. One way which is suggested usually is to specify the version of the import package in Manifest.MF file but here the version of both the jars is same.
We use tycho-buildtimestamp-jgit as explained in the tycho wiki to create reproducible version qualifiers for bundles.
The bundle jars created in the target/ directory are still named bundle.name-1.2.3-SNAPSHOT.jar even though the MANIFEST.MF already contains the generated version qualifier.
Why isn't SNAPSHOT replaced with the generated qualifier? How can the pom.xml be adjusted to include the generated version in the bundle file name?
Every bundle built by Tycho has a Maven version and an OSGi/p2 version. Which one of the two versions you see depends on the context. E.g. in the target/ folder, being a Maven concept, you will see the bundle jar with the Maven version.
If you aggregate the bundle into a p2 repository (with the packaging type eclipse-repository), you'll see the bundle jar with a file name that includes the OSGi version.
Note that the tycho-buildtimestamp-jgit plugin only affects the OSGi version, i.e. the replacement of the qualifier literal. Maven's SNAPSHOT literal is never replaced by Tycho.
In my RAD, when I open up the MANIFEST.MF file for an ejb project, because I need to add dependencies, in the UI, I see (under dependencies):
Select other JARs or modules contained by the EAR that are required by this JAR or module. Only valid or existing dependencies are shown.
What does it mean by Only valid or existing dependencies. I say this because not all projects in the workspace are listed under Dependencies. And the project that I need to add as dependency is not listed here. What is the reason for this?
I found the solution although do not understand the reason. I need to add the project jar under JAVA EE Module Dependencies
I created a simple Maven project (Packaging type - Jar) that has dependencies on Spring and My Sql library (mysql-connector). When I package this project with $mvn package I do get a jar file after successful execution of this command.
I was also trying to include all the dependencies in the output jar file, so I added a 'jar-with-dependencies' assembly descriptor, but as the documentation says:
The `jar-with-dependencies` descriptor builds a JAR archive with the contents of the main project jar along with the unpacked contents of all the project’s runtime dependencies.
I want to include the dependencies in JAR form, not the unpacked way. How can I do this?
Java cannot load classes from jars in your jar out of the box. You must configure it with project like one-jar and maven plugin.
Maybe this can help Maven Shade Plugin:Maven Excecutable Jar
Olivier
Vicky is trying to aggregate the jars and this is known as "building-an-aggregate-jar" in Maven's terms. You can find more in Robert's[1] and Artifact Technical Notes'[2] blog.
One discussion[3] that can help as well.
Regards
[1] http://rombertw.wordpress.com/2010/05/14/maven-recipe-building-an-aggregate-jar/
[2] http://blog.artifact-software.com/tech/?p=121
[3] http://maven.40175.n5.nabble.com/Aggregate-POM-for-thirdparty-package-dependencies-not-downloaded-td113927.html
I’m trying to embed some JARs into single OSGi bundle using the feature of maven-bundle-plugin
The thing that worries me is that all packages of embedded JARs are put into the Import-Package header of the generated MANIFEST.MF.
If I specify explicitly to use only the packages I need, like in the following snippet:
Import-Package: org.osgi.framework
The build fails with BND error (unresolved references).
So, the question here is how can I build the bundle with embedded JARs with "Import-Package" header I need?
All the packages that are imported in your classes will be imported by bnd. Perhaps you do not want those packages imported because you know that at runtime you won't be needing them. If you cannot stop bnd from importing them, you can make them optional so that your bundle will still resolve even if they are not supplied by another bundle (at wire time). Try to add this:
<Import-Package>*;resolution:=optional<Import-Package>
To your maven bnd configuration in maven.
One possible reason why you are seeing "unexpected" packages in Import-Package header is the following:
A general good practice that supports collaboration model in OSGi is to import all packages that you export -- see this blog post by Peter Kriens for detailed explanation why. Bnd (and hence also maven-bundle-plugin) follows this practice by default and automatically imports all exported packages. Therefore you should first check your Export-Package header and make sure that you export only the packages you want.
Also if you want to export packages from the embedded dependencies then you should be careful to avoid duplication inside your bundle -- see section Embed-Dependency and Export-Package of the maven-bundle-plugin documentation.
You should use Bundle-ClassPath if you want to make classes available inside a bundle that contains JARs e.g.
Bundle-ClassPath: foo.jar,other.jar
Import-Package: org.osgi.framework,org.other.imported
You'll need to list the classes that foo.jar and other.jar import/use, but you won't need to list any of the packages in foo.jar or other.jar unless you're actually exporting them.
You can remove some packages from import-package scope when you embed a JAR into your bundle:
<Import-Package>![package_name9]<Import-Package>
inside pom.xml or if you use external *.bnd files:
Import-Package: ![package_name]