Maven Dll Dependency Problem - java

I am developing a swing based desktop application and this application is using MediaInfo.dll library. I have first installed this dll to my local repository like described this answer. Then I have added a dependency in my pom.xml like this
<dependency>
<groupId>com.mediainfo</groupId>
<artifactId>mediainfo</artifactId>
<version>0.7.44</version>
<type>dll</type>
</dependency>
I am using Maven 3.0.3 version and when I executed mvn install assembly:assembly it says
PlexusIoResourceCollection not found, no archiever found for dll
I am new to maven, so I am searching for a help before pulling my hear out .

This will depend on your assembly descriptor, but it seems like you have a <dependencySet> under which <unpack>true</unpack> is specified, that does not exclude the DLL from the set. Try adding this into that dependencySet element:
<excludes>
<exclude>*:dll*</exclude>
</excludes>
If you intend to incorporate the DLL dependencies without unpacking them, then you might need an additional dependencySet element that includes them and doesn't specify the unpack flag. See http://maven.apache.org/plugins/maven-assembly-plugin/assembly.html#class_dependencySet for more information.

Related

Can't see how to tell Maven to install jars on lib folder

Sorry if this is too trivial, but I've recently jumped into Wep Applications from standard console java projects, and since in java projects I successfully used maven to download jars and include them into the classpath... in the web app I don't know how to accomplish the same stuff and downloading to the lib folder on WEB-INF instead of just adding the jars to my classpath.
I have searched stack overflow and the google for an answer, but since I haven't found any single answer, I'm afraid I should be completely wrong with my approach for this.
I have just created my webapp on eclipse, then converted it to maven project, and then added this dependencies in pom.xml, as I used to do in a normal java project:
<dependencies>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.9.1</version>
</dependency>
</dependencies>
Everything seems to be ok, and no error is shown, but the jars are not downloaded into the WEB-INF/lib folder.
Thanks in advance for any help you can provide.
If your project is correctly configured as "Maven project" there should be a folder called "Maven Dependencies" in your package view.
A good hint if your project is configured as Maven project is a little "M" on the top level folder.
Eclipse will download in a so called "Repository". This is mostly located in $HOME/.m2
Generally you don't have to care about jars directly. Maven will download them and create a classpath transparently for you.
The eclipse maven integration is called m2e.
The concept of Repositories is central to maven. They are the place where your dependencies and external dependencies are stored. Two repositories you can always assume to exist are the already mentioned local one and the other so called "Maven-Central" see here. Beside that you can setup , for example, company wide Repositories with tools like Nexus or Artifactory.
To upload a dependency in your local Repo use the mvn install command.
What maven within mvn install is executing the install lifecycle.
and then uploads the resulting artifact (generally a jar or war, but not necessarily) and some metadata (your pom mainly) to the repository.
You can then develop against these dependencies via the dependency mecahnism.
Dependencies in you installed in your local Repository are always of type "SNAPSHOT". There is more to know about the difference between SNAPSHOT and Release (only version number) and how to deploy/release them, but these questions are already awnsered several times.
Adding this plugin to pom.xml will help to get jars in lib folder.
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<phase>install</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>WebContent/WEB-INF/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>

Adding a JNI library to the local Maven Repository

I wish to add a JNI library, including its shared object (.so) file to my project using Maven. Unfortunately it is not yet on a public repository so I guess I have to install it myself on my local repository to have it working.
How do I go about including the native part in Maven to be bundled in my project (and eventually exported with the copy-dependencies plugin). This is a standard J2SE app (not a web-app), with packaging .jar?
The library I am trying to add is junixsocket, just in case it helps to know.
It has a .so (native library) component, and the Java .jar component.
I came across maven-nar-plugin which seems to target native builds, but seems to be more oriented towards building a JNI project from code, rather than bundling a 3rd party JNI library, and I can't get to piece the jigsaw puzzle together.
How do I go about:
Installing these in my local repository, having the .jar depending on the .so library.
Including the dependency (on the .jar and .so) in the POM file.
Thanks.
My approach:
Put .so files to repository with platform specific classifier, like this: sqlite3-3.7.9-linux-x86_64.so.
Add .so dependencies for all required platforms:
<dependency>
<groupId>de.ch-werner</groupId>
<artifactId>sqlite-jdbc</artifactId>
<version>3.7.9</version>
<type>so</type>
<classifier>linux-x86_64</classifier>
</dependency>
Use this maven assembly plugin config to put all native libs into lib/native directory of you dist:
<dependencySet>
<outputDirectory>lib/native</outputDirectory>
<outputFileNameMapping>${artifact.artifactId}${dashClassifier?}.${artifact.extension}</outputFileNameMapping>
<unpack>false</unpack>
<useProjectArtifact>false</useProjectArtifact>
<useStrictFiltering>false</useStrictFiltering>
<includes>
<include>*:*:dll:*</include>
<include>*:*:so:*</include>
<include>*:*:jnilib:*</include>
</includes>
</dependencySet>
Use this class to load libs on app startup (planning to change classifier naming to GNU triplets):
CtzJniUtils.loadJniLibsFromStandardPath(Launcher.class, "sqlite3")
I include the .so in the jar and extra the platform specific shared library before loading it. This way it is deployed just like any other jar.
An example of a project where this is done, with multiple .so for different platforms is
https://github.com/peter-lawrey/Java-Thread-Affinity
The main class to look at is https://github.com/peter-lawrey/Java-Thread-Affinity/blob/master/src/main/java/com/higherfrequencytrading/affinity/impl/NativeAffinity.java
As an alternative to unpacking your libraries at runtime, you could store them as jars in Maven but unpack them at build time: http://www.buildanddeploy.com/node/17.
The maven-nativedependencies-plugin plugin will do this for you automatically, as long as you follow their naming convention.

Dependency in Maven

I am really new to maven. I am bit confused about the dependency feature. I know that I can add dependency in the pom file like this
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.1</version>
</dependency>
What does this actually mean? Does it mean that I dont need to import the slf4j jar files into my project? If so how does my project get access to those libraries?
I have read about dependency from maven site but didnt help me much.
Can some one explain it in a simpler way.
Thanks
Nutshell: It means your project has a dependency on slf4j, version 1.6.1.
Furthermore:
If you build your project with Maven (or your IDE is Maven-aware), you don't have to do anything else in order to use slf4j. (Aside from normal source-code considerations, like a reasonable import statement, etc.)
slf4j v. 1.6.1 will be retrieved from a default Maven repository to your local repository, meaning...
... ~/.m2/repository is your repository. slf4j will be put in $M2_HOME/org/slf4j/$(artifactId}/1.6.1 and will include (in general) a jar file, a pom file, and a hash file.
Slf4j's dependencies will be downloaded into your local repository as well.
Dependencies of those dependencies will be downloaded ad infinitum/ad nauseum. (The source of "first use of a library downloads the internet" jokes if there are a lot of dependencies; not the case for slf4j.) This is "transitive dependency management"--one of Maven's original purposes.
If you were not using maven, you would manually download and use the dependencies that you needed for your project. You would probably place them in a lib folder and specify this location in your IDE as well as your build tool.
maven manages these dependencies for you. You specify the dependency your project needs in the prescribed format and maven downloads them for you from the internet and manages them. When building your project, maven knows where it has placed these dependencies and uses them. Most IDEs also know where these dependencies are, when they discover that it is a maven project.
Why is this a big deal? Typically most open source libraries release newer versions on a regular basis. If your project uses these, then each time a newer version is needed, you would need to manually download it and manage it. More importantly, each dependency, in turn may have other dependencies (called transitive dependency). If you do not use maven, you would need to identify, download and manage these transitive dependencies as well.
It becomes complex the more such dependencies that your project uses. It is possible that two dependencies end up using different versions of a dependency common to them.
When compiling your project, Maven will download the corresponding .jar file from a repository, usually the central repository (you can configure different repositories, either for mirroring or for your own libraries which aren't available on the central repositories).
If your IDE know about Maven, it will parse the pom and either download the dependencies itself or ask Maven to do so. Then it will open the dependencies' jars, and this is how you get autocompletion: the IDE "imports" the jars for you behind the scenes.
The repository contains not only the ".jar" file for the dependency, but also a ".pom" file, which describes its dependencies. So, maven will recursively download its dependencies, and you will get all the jars you need to compile your software.
Then, when you will try to run your software, you will have to tell the JVM where to find these dependencies (ie, you have to put them on the class path).
What I usually do is copy the dependencies to a target/lib/ directory, so it is easy to deploy the software and to launch it. To do so, you can use the maven-dependency-plugin, which you specify in the <build>:
<build>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</build>
There are a variety of servers on the internet that host artifacts (jars) that you can download as part of a maven build. You can add dependencies like you show above to describe what jars you need in order to build your code. When maven goes to build, it will contact one of these servers and download the jar to your computer and place it in a local repository usually
${user_home}/.m2/repository
The servers that maven contacts must be configured in your maven project pom file, under a section like
<repositories>
<repository>
</repository>
</repositories>
The prototypical server can be seen at repo1.maven.org
The nice thing about maven is that if a jar you list is needed, it will pull not only that jar, but any jars that that jar needs. Obviously, since you are pulling the jars to your machine, it only downloads them when it can't find them on your machine, thus not slowing down your build everytime (just the first time).

Using Hudson and Maven to release an application for multiple platforms

This question is not really about best practices or architecture, but about how to specifically configure Hudson and Maven to accomplish what I want. I'm a bit lost.
I have a Java application which uses SWT, and I need to build copies for different platforms. For now, all I need is Linux i386 and Linux amd64, but in the future, I need to add Windows x86/x64 as well, so I want to make sure I set it up "right" the first time around.
My application has all of the dependencies and other information listed in the Project pom.xml, including the different SWT jars to grab depending on OS, arch, and family.
My question is, how do I do builds for both linux i386 and linux amd64 with a minimal amount of configuration duplication? Right now I'm doing the following:
Project specifies all dependencies in pom.xml, and this project is set to build in Hudson and deploy the resulting .jar to Nexus
Builder-linux-i386 runs after Project and specifies any JNI files for i386 and uses the de.tarent maven-pkg-plugin to grab the project jar from Nexus and assemble it along with all dependencies into a single 'fat' jar file, and then into a .deb file for installation.
Builder-linux-amd64 does the same, but for amd64 files
I have been trying to specify which dependencies to use in the Builder projects by adding -P profilename to their Hudson projects, where profilename is a profile named in the Project pom. Maven doesn't seem to like this and prints that it is not activating that profile. It only uses the default profile from Project's pom.
What is the correct way to set this up? I want to have all of my dependencies specified in my Project pom, and have a Hudson project which compiles the jar for that project and deploy it to Nexus, and then independent projects which grab that jar and assemble it along with platform-specific files for release. I don't want to build the entire original project repeatedly, and I don't want to have a ton of duplicated configuration info or copy-pasted poms.
I have it working for unix-amd64 only because that's what the build machine is, so Maven targets that architecture. Also, I feel like the setup isn't as clean as it could be. Advice?
You have an syntax error. It needs to be -Pprofilename. It works for me this way.
Edit
Since the profile is read. There might be an syntax error in your profile configuration. I found a profile in one of projects, that I integrate into our CI environment. It defines some dependencies, it might help you.
<profile>
<id>junit</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skip>false</skip>
<testNGArtifactName>none:none</testNGArtifactName>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.4</version>
<scope>test</scope>
</dependency>
</dependencies>
</profile>
Profiles should work in the way you desciped it (you could post an other question about this).
But at (least for web applications) there is an other way: Try to use classifier instead of profiles to build for different environments. -- You can have a look at this blog: http://blog.jayway.com/2010/01/21/one-artifact-with-multiple-configurations-in-maven/
The purpuse of this solution is, that you are able to build (if you want (controlled by an profile)) for all environments at once.
The builder projects do not see the profiles from the main Project because it is not actually a parent. I cannot define it as a in the builder projects because my projects are not set up that way, and I'm building using variables like ${SVN_REVISION}, which maven does not like.
I have given up and instead copy-pasted the profiles into the 'builder' projects. This isn't the prettiest but for now it works.

How to share code between multiple GWT eclipse projects?

I would like to have multiple GWT projects that share common code. Is this possible? AFAICT my GWT projects need to each have their own directory, with source directly underneath, which seems to preclude code-sharing. I tried using linked folders, but GWT didn't seem to like that (described here).
If I want to do this, is my only choice to turn the code I want to share into a .jar file, and then inherit that in each of my projects' XML files? Is there a way to make eclipse automatically do this packaging, or would I need some sort of 'change-shared-code/compile-jar/use-in-other-project' loop?
Are there any other solutions?
I solve this problem with help of maven. The common code is packaged as separate maven project and then used as library. Here are snippets from pom.xml file:
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt-user</artifactId>
<version>2.0.4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt-dev</artifactId>
<version>2.0.4</version>
<scope>provided</scope>
</dependency>
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/client/**/*.java</include>
<include>**/client/**/*.properties</include>
<include>**/shared/**/*.java</include>
<include>**/shared/**/*.properties</include>
<include>**/*.gwt.xml</include>
</includes>
</resource>
</resource>
</build>
The above build configuration copies additional source files needed by GWT compiler into final jar.
In case of using eclipse as IDE, the m2eclipse plugin can be used for handling all the dependencies automatically. It is possible to have all the projects opened in single workspace and classpath of the common project will be shared. The only drawback is the requirement of invoking project > clean from time to time (will force embedded maven to copy all the resources specified in the snippet above).
I think all you need to do is make two separate GWT projects, e.g. project A for shared code and project B that uses code from project A.
Once you have these two projects, two steps are required:
Add project A to project B's build path in Eclipse.
Inherit project A's gwt.xml in project B.
You should now be able to use hosted mode / compile within Eclipse.

Categories

Resources