Maven: Using a project folder as a repository for lib - java

I have a project with the following layout:
My goal was to have mvn looking in the project lib dir as an additional location for potential libs that would not be found in maven repository like j-text-utils.jar for example. So I added this in the pom.xml
<repositories>
<repository>
<id>lib</id>
<url>file://${project.basedir}/lib</url>
</repository>
</repositories>
I took the idea from here: http://randomizedsort.blogspot.co.il/2011/10/configuring-maven-to-use-local-library.html
When running mvn compile, it fails to find the relevant libs in the project folder.
Is there anything wrong with the above?
Thx

There is nothing wrong to setup a file based repository. But first and foremost, your directory structure needs to conform to the groupid/artifactid. You should use
set localrepopath=C:\path_to_repo_rootdir
call mvn install:install-file -Dfile=xyz-1.2.jar -DgroupId=com.foo -DartifactId=xyz -Dversion=1.2 -Dpackaging=jar -DlocalRepositoryPath=%localrepopath% -DcreateChecksum=true
It will create directory com\foo\1.2 with all the pom.xml, jar files, checksum files under it.
Then you need to define the dependency for these newly installed artifacts in your own project pom.xml.
If you do not want to setup local repository and only want to add them to the compile classpath, you can consider using "system" scope dependency, but it will make your build not portable and is discouraged in general.

You can do that (just configure the maven-dependency-plugin properly), but I wouldn't suggest that.
There might be a few drawbacks with that direction (e.g., having the Jars there could get into the repository you're using, for many projects it's better to have only one Jar in a dedicated place of your HDD rather than having one of them in each and every project, etc.).

Related

Maven dependency issue - artifact not found in central repo

I'm trying to build the project from this site http://www.joptimizer.com/usage.html. I downloaded the sources jar file, unpacked it and ran maven package in the root folder. Maven fails at the last minute saying it couldn't resolve the dependency..
could not find artifact seventytwomiles:architecture-rules:jar:3.0.0-M1 in central repo - repo.maven.apache.org/maven2 ..
I have a feeling I might need to change something in the pom.xml file for this to work, but have no idea what. Googling for this missing dependency lead me no where. In general, how would one know what to do to handle such errors (and also please help with this specific case).
Specifically
According to the Building notes on http://www.joptimizer.com/usage.html:
JOptimizer is build on maven 3.0. Before building it, you must resolve
(in pom.xml) the external dependency on Colt and other dependencies
that aren't in public repositories. Please refer to the "Dependencies"
report for a complete treatment. For ease of use a boundle with
these external libraries is provided (visit "Download"): extract the
boundle in a folder and run the "maven-install.cmd" (translate it in
your own shell language), and you will get the artifacts in your local
repository.
To get the bundle for this, go to http://sourceforge.net/projects/cvxopt/files/, and download the appropriate version of joptimizer-3.X.X-dependencies.zip. Unzip in your own folder, and run mvn install:install-file -DgroupId=seventytwomiles -DartifactId=architecture-rules -Dversion=3.0.0-M1 -Dpackaging=jar -Dfile=architecture-rules-3.0.0-M1.jar -DpomFile=architecture-rules-3.0.0-M1.pom
Generally
Use a tool like http://mavenrepository.com to search for another version of the missing dependency and update your POM with the proper version. If MVNRepository doesn't know about it, you can install the dependency yourself. If you are working with a group of developers, as Eric Jablow mentions, an artifact repository like Nexus or Artifactory is great for sharing non-public dependencies. If it's just you, you can install the artifact in your local repo as described here: How to manually install an artifact in Maven 2?
You should add your own repository manager like Nexus or Artifactory. Then, find out where this dependency is kept; there are repositories other than central. If it's kept on another repository, have your repository mirror that too.
Otherwise, Nexus or Artifactory have commands to enter the dependency manually. Create a local repository called "Third-party" and add it there.
Finally, change your settings.xml file to refer everything to your repository manager.
The most common case for this is when a company refuses to license their products to be held at the central repository. For example, Microsoft won't let its sqljdbc.jar file be distributed through Central. So, you need to add it by hand.
Change the dependency as follows
<dependency>
<groupId>org.architecturerules</groupId>
<artifactId>architecture-rules</artifactId>
<version>3.0.0-rc1</version>
<scope>test</scope>
</dependency>
Add the repository in pom
<repositories>
<repository>
<id>architecturerules.googlecode.com</id>
<url>http://architecturerules.googlecode.com/svn/maven2/</url>
</repository>
</repositories>

Embed local jar files in maven project

I have some local jar files from a non-maven project which I wish to include in my maven-based eclipse project.
These jar files are undergoing a lot of change as me and my project buddy attempt to 'fix' them, so I'd prefer not to upload them to a repository to avoid making a maven version of this non-maven project if this is possible.
Of course, the jar files need to be embedded in the resulting deployment jar. We did this before using Ant which let us specify that those jar files should be included.
How do you do the same thing in maven? Take into consideration that we do have maven dependencies too which all work fine and aren't required in the deployment. Some answers I've seen don't allow for this requirement.
Here's one of my attempts - the problem is that the jar does not get embedded:
<dependency>
<groupId>se.krka.kahlua</groupId>
<artifactId>kahlua-core</artifactId>
<version>5.1_2.1.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/kahlua-5.1_2.1.0-core.jar</systemPath>
</dependency>
System paths are a very bad idea. When anybody else checks out your projects, he cannot build it anymore. (I always see such crap in many companies). The right solution would be to install the jar into the local repository:
$ mvn install:install-file -Dfile=[JAR NAME] -DgroupId=[GROUPID OF
JAR] -DartifactId=[ARTIFACT OF JAR] -Dversion=[VERSION OF JAR]
-Dpackaging=jar
In your project, you just add the dependency as usual after you installed the jar into the local repository.
<dependency>
<groupId>[GROUPID OF JAR]</groupId>
<artifactId>[ARTIFACT OF JAR]</artifactId>
<version>[VERSION OF JAR]</version>
</dependency>
You can use maven-install-plugin to install kahlua-5.1_2.1.0-core.jar into the local repository then this dependency will behave as any other, see http://maven.apache.org/plugins/maven-install-plugin/usage.html. Or make a remote repository in a location shared with your buddy and let him upload his jar there with maven-deploy-plugin:deploy-file (http://maven.apache.org/guides/mini/guide-3rd-party-jars-remote.html) each time he changes it and add this repository to your pom. You can use SNAPSHOT version if this jar changes often

Maven: Add local dependencies to jar

I have a dependency
<dependency>
<groupId>de.matthiasmann</groupId>
<artifactId>twl</artifactId>
<version>1.0.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/TWL.jar</systemPath>
</dependency>
Then I execute mvn assembly:assembly. All natives files and remote maven libs are added, but there is no this jar.
UPDATE
When I am trying to run app by java -jar myjar.jar. It returns an error that there is no class from the above dependency (NoClassDefFoundError : de.matthiasmann.twl.ForExample).
I want to add classes from this jar to myjar.jar (the same what maven does with remote dependencies). How I can configure maven to do that?
See Maven 2 assembly with dependencies: jar under scope "system" not included for why system dependencies are not included and how you can work around it, specifically the mvn install:install-file code is what you want.
You cannot use systemPath, unless your Java EE server/container has that jar configured.
Remember that maven is development and compile time only. Once the war file is built, maven has no effect except for having placed all the desired jars into the WEB-INF/lib folder.
When you specify system scope, it means that it is your responsibility to ensure that the jar is present when the war is deployed. You already have a framework to do that and you do not wish to encumber your build dependency with that jar, but you have to make it available thro Maven only during development.
The other similar scope is "provided". e.g., JBoss or your corporate common deployment Tomcat framework already provides many of the jars like Spring and Hibernate that are loaded by the server startup and common to all apps in the server. Therefore, you would not want maven build to include those into the war file.
The right way, Maven gurus would tell you. is to have your own maven server and build whatever artefacts you need into that server. However, occasionally that is not possible.
Therefore, on such occasions, I create project level repository that is distributed with the project and checked into version control. I run the command mvn install to create a project level directory called, say, "project-repo".
http://maven.apache.org/plugins/maven-install-plugin/examples/specific-local-repo.html (Due to familiarity, most of the time, I build the repo by hand rather than run mvn install).
Then in the POM, I specify file://${project.basedir}/project-repo as one of the repositories. The caveat with this is that in Windows, the slashes other than the pair after "file://" has to be back-slashes when referring to Windows file system paths.
<repositories>
<repository>
<id>my-repo1</id>
<name>my custom repo</name>
<url>http://ho.ho.ho</url>
</repository>
<repository>
<id>project-repo</id>
<name>my project repo</name>
<url>file://${project.basedir}\project-repo</url>
</repository>
</repositories>
YOu can implement this in many ways refer the blog below
http://blog.valdaris.com/post/custom-jar/
If you have such an dependency the best solution is first to use a repository manager and simply put that dependency into the repository manager and afterwards use it as simple dependency.

Include a Maven dependency only if it exists

I have a problem, I have a project which is based in a system that includes modules. This modules are other maven projects and are referenced from system POM. My problem is I'm sharing the system project with a workmate and we've got different modules.
So, is there a way to tell Maven that I want to include a module referenced in my POM only if this module exists? I mean, without compilation failure.
Thanks!
I would suggest to use profiles and activate them on file/exists option.
Use dependencyManagementis to pull all the dependency information into a common POM file, simplifying the references in the child POM file.
There are several solutions, depending on what you can do/want to achieve.
One approach is to install a Maven repository server at your company (in your local LAN or in a LAN that you and your colleague share). Build the system and then deploy the modules to the server.
In your build, you can add this new server like this (documentation):
<project>
...
<repositories>
<repository>
<id>my-internal-site</id>
<url>http://myserver/repo</url>
</repository>
</repositories>
...
</project>
Or you can both copy the base system and build it locally with mvn install. That will copy all artifacts into your local cache.
From there, you can reference them as usual. You don't need to include all the modules; just the ones you really need. That way, you and your friend don't have to use the same dependencies.

How to add missing maven libraries to Jetty

I am trying to launch a maven project, that I always launched manually in Tomcat, in Jetty. For this I am using the maven-jetty-plugin.
When executing jetty:run It seems like everything goes fine, except for the fact that Jetty does not find the dependencies defined in the POM.
If I run jetty:war, the war is built properly, using the dependencies, so that works. Why is jetty:run not including my libraries in WEB-INF/lib (or anywhere else)?
If you need a dependency for Jetty which resides somewhere other than the main Maven repo, add the following:
<pluginRepositories>
<pluginRepository>
<id>repo-id</id>
<url>http://my_other_repo.edu</url>
</pluginRepository>
</pluginRepositories>
I don't believe Jetty will use the existing repositories in your POM.
It really depends on the dependencies you have defined. For example, if you have defined a JNDI resource in your jetty.xml file, you will need the jetty-plus dependency. However, you will need this dependency for the execution of the plugin only. Plugins can have <dependencies/> and that is where you need to define it.
If you have a list of Jetty-specific classes that the plugin can't find, the best way to look up the dependencies is to use a site like www.jarvana.com.
By 'dependencies', do you mean other projects?
If so, you will need to install (mvn:install) these into the local repository before jetty:run will see them.
It's possible that jetty:war is packaging them and placing them into the lib folder without installing into the local repo.
For me I had one .jar file in my repo that was not getting picked up by Eclipse. I didn't figure out how to fix it in Eclipse, so my work around was to ...
Add a duplicate of the .jar file to the repo under a different groupId (different path under ~/.m2) using this command:
mvn install:install-file -Dfile=dhcp4java-1.0.0.jar -DgroupId=a_abc.hack -DartifactId=dhcp4java -Dversion=1.0.0 -Dpackaging=jar
Reference the new groupId , which requires only to update this entry for the dependency in pom.xml :
<groupId>a_abc.hack </groupId>

Categories