How to add a bundle manifest to an existing maven dependency? - maven-2

I am using the Adobe XMP Core dependency within a maven file
<dependency>
<groupId>com.adobe.xmp</groupId>
<artifactId>xmpcore</artifactId>
<version>5.1.2</version>
</dependency>
The MANIFEST.MF of that bundle is not suited for osgi deployment, as no bundle specific information was provided. So I would need to add the following lines to that Manifest.mf
Bundle-ClassPath: .
Bundle-Version: 5.1.2
Bundle-Name: xmpcore
Bundle-ManifestVersion: 2
Bundle-SymbolicName: com.adobe.xmp.xmpcore
Export-Package:
com.adobe.xmp;version="5.1.2",
com.adobe.xmp.impl;version="5.1.2",
com.adobe.xmp.impl.xpath;version="5.1.2",
Is there a way of unpacking this maven artefact and exchanging the provided manifest via the maven dependency plugin or any different way?

For runtime enhancement use the Pax URL Wrap Project. If you have this bundle in your environment add the wrap: url-schema to your bundle installation it will auto-wrap your bundle on the fly.

IIRC, Eclipse Virgo Bundlor can do that work for you.
http://www.eclipse.org/virgo/documentation/bundlor-documentation-1.1.1.RELEASE/docs/user-guide/htmlsingle/user-guide.html#usage.command.line
Virgo Bundlor will add all export-Package statements + all import statements which he can find via declared import-statements in your java-files. If the jar uses dynamic classloading, you need to add a template.mf file with the additional import.

Related

Bundle Manifest dependencies

Recently I have been assigned to improve the structure of inter-dependencies that an Eclipse plugin has. Let's call it "core" and assume that the following manifest describes this eclipse plug-in where all the other plug-ins point to in order for them to access services (RMI, OSGi services). These services are reachable by using either "rmiservices.jar" (Maven generated artifact) and another eclipse plug-in called "org.osgiservice". Other bundles reference "core" bundle and use the Export-Package declaration in order to use these services.
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: core
Bundle-SymbolicName: coreid;singleton:=true
Bundle-Version: 0.0.1
Bundle-Activator: org.sample.Activator
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Bundle-ActivationPolicy: lazy
Export-Package: org.sample.api,
org.rmiservice,
org.osgiservice
Bundle-Localization: plugin
Bundle-ClassPath: lib/rmiservices.jar
Require-Bundle: org.osgiservice;bundle-version="1.0.0";visibility:=reexport
Questions that arise in order to improve the dependency structure are:
The "core" plug-in includes within its generated jar the rmiservices.jar. Would it be better having rmiservices.jar as a separate bundle instead?
rmiservices.jar is a maven generated artifact. Would there be a benefit moving it to a P2 repository and expose it inside a target definition?
You should put the jar into its own bundle. If your application grows, you might need to access that library from different bundles. With local jars you risk different versions being loaded by different bundles (due to those local jar copies), leading to very strange errors at runtime.
If the jar is available in P2, then you can easily build your complete application using Tycho. The automation and reproducability of the build process is well worth the shortly longer build time.

Running unit tests in Tycho fails: resolves google-collections instead of Guava

I am having an issue running tests using tycho due to an incorrect dependency resolution that, somehow, is placing the the old Google Collections .jar on the classpath and not the Guava one, despite the fact that at no point in any of my poms do I specify a dependency on collections (only guava).
My unit tests fail due to things like NoSuchMethodError (ImmutableList.copyOf), NoClassDefFoundError (Joiner), which I pretty much narrowed down to 'finding the wrong jar'. These same tests pass when ran manually in Eclipse.
Here is the relevant part of the pom:
<dependencies>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>14.0.1</version>
</dependency>
...
</dependencies>
The phrase 'google collections' appears no where. The only other repository I specify is:
<repositories>
<repository>
<id>helios</id>
<layout>p2</layout>
<url>http://download.eclipse.org/releases/helios</url>
</repository>
</repositories>
My plugin imports 'com.google.common.base' and 'com.google.common.collect' as imported packages. I have my own bundled version of Guava 14 in my workspace for debugging, but in the POM I elect to not use my local module.
I followed Sean Patrick Floyd's answer on this question (JUnit throws java.lang.NoSuchMethodError For com.google.common.collect.Iterables.tryFind), and had my test throw an exception with the location of the .jar that the Iterables class was loaded from. It spat back out:
java.lang.IllegalArgumentException: file:/C:/Documents and Settings/Erika Redmark/.m2/repository/p2/osgi/bundle/com.google.collect/0.8.0.v201102150722/com.google.collect-0.8.0.v201102150722.jar
This is where I am now stuck. This google-collections jar is coming seemingly out of no where, and I don't know how to stop it. As long as it is being resolved, my unit tests will fail. How can I stop Tycho from trying to get the old Google Collections?
Just to clarify, this has not stopped building and deployment; the plugin update site is on an CI platform and we have been able to install the plugin on different Eclipse IDEs, so this issue is only affecting the tests.
Please let me know if additional information is needed.
The plug-in com.google.collect 0.8.0.v201102150722 is part of the Helios p2 repository that you have configured in your POM. This means that this plug-in is part of the target platform and so may be used to resolve dependencies.
If you want to ensure that the bundle is not used, make sure that it is not part of the target platform. In your case, the easiest way to do this is to explicitly remove the plug-in from the target platform:
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>target-platform-configuration</artifactId>
<version>${tycho-version}</version>
<configuration>
<filters>
<filter>
<type>eclipse-plugin</type>
<id>com.google.collect</id>
<removeAll />
</filter>
</filters>
</configuration>
</plugin>
Next, you need to make sure that the guava plug-in is part of the target platform. You can add an artifact from a Maven repository to the target platform in the following way:
Declare a Maven dependency to the artifact in the dependencies section of the POM. You already have done this correctly.
Set the configuration parameter <pomDependencies> to consider on Tycho's target-platform-configuration plug-in.
Note that this will generally only work if the referenced artifact is already an OSGi bundle. This is the case here: com.google.guava:guava:14.0.1 seems to have all manifest headers needed by OSGi.
This should give you the result you wanted: In the test runtime, guava should now be used to match your com.google.common.* package imports.
And another general remark on declaring dependencies in Tycho: In Tycho, you can only declare dependencies in the PDE source files META-INF/MANIFEST.MF, feature.xml, etc.
The normal Maven-style dependencies declared in the POM do not add dependencies to the project. As explained above, the POM dependencies may only add artifacts to the target platform, i.e. the set of artifacts that may be used by Tycho to resolve the dependencies declared in the PDE source files. So in the end, the POM dependency may become part of the resolved dependencies, but only if the dependency resolver picks it for matching one of the declared dependencies.
by default, tycho will add any p2 artifacts you installed in your local maven repo to the target platform. If bundle com.google.collect exports the package which you import, it may be wired.
To stop tycho from including any locally installed artifacts, you can use -Dtycho.localArtifacts=ignore (or, remove the unwanted bundle from your local maven repo)
See http://wiki.eclipse.org/Tycho/Release_Notes/0.16#Improvements_and_Fixes

How do I install JQuery into my web app using Maven?

I am looking at using Maven 3 for some web development. I know how to use maven to resolve java based jar files. How do I use maven to resolve JavaScript dependencies for example I want to have maven automatically put jquery in my webapp/js folder?
Is it possible to do transative JavaScript dependencies with Maven 3?
You could create your own "war" that has jquery in it on the path you specified.
Afterwards add that war to your real web application. Maven should merge it. I think it was called somehting like "processing overlay".
I'm using the same for some GWT application where the javascript is generated by a maven plugin and it works well.
Perhaps WebJars can help you:
WebJars are client-side web libraries (e.g. jQuery & Bootstrap) packaged into JAR (Java Archive) files.
Explicitly and easily manage the client-side dependencies in JVM-based web applications
Use JVM-based build tools (e.g. Maven, Gradle, & SBT) to download your client-side dependencies
Know which client-side dependencies you are using
Transitive dependencies magically appear
Caveat: WebJars does not put the jquery files in the webapp/js folder. Please read documentation to see how it is used with some popular frameworks.
Try adding this to your pom.xml file. It worked for me :
<dependency>
<groupId>com.efsavage.jquery</groupId>
<artifactId>jquery-maven</artifactId>
<version>1.7.2</version>
</dependency>
This library gives you a way to drop jQuery into your project as a Maven dependency, which means you don't have to include these third party files in your own source control.
Source : here
May be you should use one of CDN to include external javascript libs to your webapps?
E.g. for jQuery you can simple include it from any of URLs from http://docs.jquery.com/Downloading_jQuery#CDN_Hosted_jQuery
Also libs from CDN will reduce your server bandwidth usage.
You can create a new zip artifact in your repo with your version of jquery inside.
Then use the maven war plugin to deploy it to your war.
Take a close look at <targetPath> and <includes> to be sure to deploy what you need where you need it :)
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<overlays>
<overlay>
<groupId>yourgroupid</groupId>
<artifactId>yourJqueryArtifactId</artifactId>
<type>zip</type>
<targetPath/>
<includes>
<include>js/jquery.js</include>
</includes>
</overlay>
</overlays>
</configuration>
</plugin>
the previous config supposes that you have a directory called 'js' in your zip with jquery.js inside. It will be unzipped in your war at js/jquery.js
More info here

jar-with-dependencies Maven Assembly

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

Java-Maven: How to add manually a library to the maven repository?

I'm trying to generate a jasperReport, but I receive this:
net.sf.jasperreports.engine.util.JRFontNotFoundException: Font 'Times New Roman' is not available to the JVM. See the Javadoc for more details.
After searching on the net, I found that I need to add a jar to the classpath with the font. So, I create a jar file with the ttf files and now I want to add this as a dependency to my pom file.
So: I installed the file :
mvn install:install-file -Dfile=tf.jar -DgroupId=tf -DartifactId=tf -Dversion=1.0.0 -Dpackaging=jar
and in my pom, I added these lines:
<dependency>
<groupId>tf</groupId>
<artifactId>tf</artifactId>
<version>1.0.0</version>
</dependency>
but I receive this: Dependency 'tf:tf:1.0.0' not found less
I checked the repository folder and the jar file is there, in ... tf\tf\1.0.0\
What I'm doing wrong?
The syntax of the command used to install your 3rd party jar looks identical to the reference (I would just also generate a pom by adding -DgeneratePom=true), the snippet to declare the dependency in your pom looks fine. What you're doing seems ok.
Could you provide the exact trace?