Using maven to connect to a local project - java

I have two projects in eclipse:
framework: A general library used in several projects.
client: A project that uses framework.
client is quite large, possibly larger than framework at this point. I am using client as sort of a test fixture for framework. I want to make a few changes in framework and test them in client. Currently, I have to do a full build of framework, install it into a maven repo, and then rebuild client.
Is there a way to just have client point to framework directly on my local disk? Any other hints for developing in such a situation (ie is the a better way)?

Running mvn install on Framework will build it and install it in your local Maven repository (that is, the Maven repository on your local disk). When you run your tests in Client, Maven will automatically use the version of Framework in your local repository.

You can specify dependencies from the local disk using <systemPath> like so:
<dependency>
<groupId>example.logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.0.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/commons-logging.jar</systemPath>
</dependency>
I'm not sure if you can point to a directory that has a pom in it, but at least you don't have to deploy it into maven.

The m2eclipse plugin is fairly intelligent about Maven dependencies. If you have the framework dependency open as a separate project in Eclipse, I think it should use its code for client rather than the version in your repository. You might need to tweak your project settings if you're already using m2eclipse and it doesn't do this.

Related

Centralized local Maven repository for Team

Our team of developers uses Maven for building software. We have Maven local repository on our computers. The problem is that sometimes builds made from two different developer differ, because the built packages include different version of included dependencies.
This happens when version tag is not mentioned in POM.xml file for dependencies. For example:
<dependency>
<groupId>mylib-group</groupId>
<artifactId>mylib-artifact</artifactId>
</dependency>
In this case Maven gets the newest library installed locally.
To avoid this problem We installed Maven on one computer (we call Build server) and all members of our team make build on that computer.
Is there any better solution for this case?
How can I have centralized Maven local ?
First of all: if you have a dependency like
<dependency>
<groupId>mylib-group</groupId>
<artifactId>mylib-artifact</artifactId>
</dependency>
Maven will not take the latest version, but the one defined in the <dependencyManagement> section. So you get the same results on every computer (unless you have SNAPSHOT versions which might differ).
Having said that: Having a build server is generally a good idea for having a stable environment for builds.
Addendum: You can not share a Maven local repository. This repository is not thread safe and running two builds at the same time on the same local repository can have strange effects (I speak from experience).

How to properly use any Java API

I have been trying to use the vget library/api to make my own youtube video downloader. The vget library can be found here: https://github.com/axet/vget
I have downloaded the zip on github and I imported the project into eclipse. However, I am confused to how I am supposed to properly use this API. Should I make a completely new project, and import the classes that I need or do I put my own source files in the project of the api?
I have read other threads concerning this problem. However, they all mention how a api is typically packaged in a JAR file, but in my case it is just files and classes. So I am confused to how I should properly use this api.
The vget project is a maven project. You can see that because it has a pom.xml file in the root folder of the project.
To use it, you don't even need to download the source, because the compiled jar files are already stored in the central maven repository. You can find more information about this here:
http://mvnrepository.com/artifact/com.github.axet/vget/1.1.23
(in general, you can use the http://mvnrepository.com/ site to search whether your library is available on the maven central repository. If it's even a mildly popular library, then chances are that it is)
What you need to do is to make your own project a maven project.
Here's a "5 minutes" starter guide that describes how to do that.
When you've done that, you just add the dependency on vget to your pom.xml file in the <dependencies> section:
<dependency>
<groupId>com.github.axet</groupId>
<artifactId>vget</artifactId>
<version>1.1.23</version>
</dependency>
Since you are making use of a 3rd party software, and not extending it with your own logic, the way to go is to create a new project, which references the 3rd party software.
You then construct your application and make it do whatever you need it to do. When it comes to using logic which is available within the 3rd party logic, you would then simply delegate that call to the 3rd party library.
I have seen on the link you have provided, that this is a maven project. You have to execute a maven package command, or maven install, so that the jar file will be generated.
With this jar follow the Bill's instructions, and add it as external library to your claspath.
When you do this, you will be able to invoke methods of that api.
Let us know if you need some help doing this in eclipse.
If your project is a maven project, you can solve dependencies problems just adding the dependency written on Readme file to your pom file.
The easiest and most automatic way is to use something like maven, ant, or gradle, that will automatically download and put the jars in to your classpath if they are in the central repositories. For example, in the maven configuration file(pom.xml) you can add this to the dependency list:
VGet Maven Repository
These build tools also allow you to add external jars if needed.
If
I would suggest you get familiar with Maven. At the bottom there is a Maven dependency you just have to include into your pom.xml, and then you can use the extension immediately.
Maven is a build platform which organizes your project in a technical way (convention over configuration, e.g. code is in /src/main/java, tests are in /src/test/java). The proper way is it to create a Maven project in Eclipse (you have to install the plugin and download Maven as well) and put the dependency
<dependency>
<groupId>com.github.axet</groupId>
<artifactId>vget</artifactId>
<version>1.1.23</version>
</dependency>
into your <dependencies> inside your pom.xml. After adding it, you project recognizes the additional package automatically.
Nobody tinkers by adding libraries manually. It's actually not professional to work without a build platform like Maven or Gradle.

Travis CI not using extra Maven repository provided in pom.xml

I have a Java-based GitHub project, fitnessjiffy-spring (I'm currently focused on the "bootstrap" branch). It depends on a library built from another GitHib project, fitnessjiff-etl. I am trying to configure both of these to be built by Travis CI.
Unfortunately, Travis is not as sophisticated as Jenkins or Hudson in dealing with Maven-based Java projects. Jenkins can easily handle dependencies between projects, but the same concept doesn't seem to exist with Travis. If one project depends on another, then that other project must already be built previously... and its artifact uploaded to some Maven repo where the first project can download it later.
My "fitnessjiffy-etl" library is building and deploying just fine. I'm using Bintray for Maven repository hosting, and you can clearly see my artifacts over plain HTTP at:
http://dl.bintray.com/steve-perkins/maven/
In my "fitnessjiffy-spring" project, I am adding this Maven repo location directly in the pom.xml, so that Travis will be able to find that artifact dependency. Here is the state of my POM at the time of this writing. Note the <repositories> element at the bottom of the file.
When I build this project locally, it works just fine. I can see it downloading the Maven artifact from "http://dl.bintray.com/...". However, when I try to build on Travis CI it fails every time. I can see in the console log that Travis is still trying to download the artifact from Maven Central rather than my specified repo.
Does this make sense to anyone else? Why does Maven utilize a custom repository location in a POM file when building locally, but ignores this configuration when running on a Travis CI build?
From digging into this further, I discovered that Travis uses its own proxy for Maven Central, and has configured Maven to force ALL dependency requests through their proxy. In other words, it does not seem possible at this time to use additional Maven repos specified in the POM file of a project built on Travis.
In my case, I ended up refactoring such that project would not need the outside JAR dependency. I also switched to Drone.io, so I could manage my settings on the build server rather than having to carry a YAML file in my repository (which always struck me as a bit daft).
However, even on Drone it's still a major hassle to manage dependencies between multiple projects (extremely common with Java development). For Java, I just don't think there's currently an adequate substitute for Jenkins or Hudson, maybe running on a cheap Digital Ocean droplet or some other VPS provider instance.
In your install phase add a $HOME/.m2/settings.xml define your custom repository.
cache:
directories:
- "$HOME/.m2"
install:
- curl -o $HOME/.m2/settings.xml
https://raw.githubusercontent.com/trajano/trajano/master/src/site/resources/settings.xml
- mvn dependency:go-offline
script:
- mvn clean install site

Maven: packaging & module dependencies

I have a maven project that consists of a couple of modules. The main structure and setup is this:
/project/pom.xml: packaging=pom, lists all sub-modules, version: TRUNK-SNAPSHOT
/project/core-module/pom.xml: packaging=jar
/project/war-module/pom.xml: packaging=war, depends on core-module with ${project.version}
I use IntelliJ for development if that somehow matters.
When I now develop/run/debug the war-module and meanwhile I change code in the core-module things get out of hand. The running war-module application (running via jetty:run-exploded) uses the core-module which is "installed" in my local ~/.m2/ repository instead of the current build. It doesen't matter if I do a "rebuild project" in IntelliJ or a mvn clean before running.
My question is: do I have to mvn install each time, can I circumvent the installed packages or do I have to change packaging options?
Making a long story short, the answer is: YES, in a multi-module project you have to run mvn install every time so the dependencies of your war-module get compiled and installed in your local repository.
However, for local testing I usually recommend to make use of the IDE features to test our local changes. With IntelliJ is really easy to configure and it supports a lot of different application servers.
The reason for this is: Imagine working on a large team, using an enterprise shared repository to hold your common dependencies without the need to publish them to Maven central. If any of your colleagues has made changes to core-module, committed them and make them available through your internal shared repo then Maven will download that dependency and then use to run the Jetty plugin.
The good side of this is that you'll be testing with last version of those dependencies, the bad side of it is that the code of those dependencies is not the same as the one in your working copy.

How to add javax.* dependencies in Maven?

I am getting tired of manually installing javax jar files in Maven and would like to know what is the best solution to include a dependency on javax.cache, javax.transaction, or other JSRs that are not easy to find in Maven repositories.
Have you seen https://people.apache.org/~ltheussl/maven-stage-site/guides/mini/guide-coping-with-sun-jars.html ?
This link suggests groupID and artifactID's to use, as well as a java.net repository.
It looks to me like almost all of these exist in the central Maven repository under this naming scheme.
I'm not aware of one, but adding the java.net repository may help you with some of these dependencies:
<repositories>
<repository>
<id>java.net repository</id>
<url>http://download.java.net/maven/2</url>
</repository>
</repositories>
If building on more than one box and/or for team development, a local (intranet) maven repository manager can help with these "missing" jars. This centralizes the configuration and management of not only 3rd party jars that are not in a public repository, but also all external repositories in general. It could also help automate your builds, creating more 'reproducable' builds (e.g., if you have a pool of continuous integration servers).
install a mvn repo mgr (see list -- imo, nexus is really simple to start with);
use a custom settings.xml that includes a "mirrors" section pointing to your intranet mvn repo mgr. Either update your ~/.m2/settings.xml, or run maven with "mvn -s etc/settings.xml"-- useful for hudson builds, where you don't want a custom per-user settings.xml;
manually upload your 'problem' jars to your internal repo (again, super-simple w/ Nexus via a web-interface);
set up the internal mvn repo mgr as a "mirror" of repo1.maven.org/maven2, codehaus, java.net, ... (etc).
Now, you can centrally define all 3rd party repositories & 3rd party jars -- rather than requiring each person, each box and/or each project define them individually in their pom or settings.xml. Each project / person / box would ONLY define your central, internal maven repo as the single repo for all maven projects.
This also really speeds up your artifact re-download time for fresh builds, or for those times when you need to (or would like to) delete your local ~/.m2/repository cache.
Repo managers: nexus, archiva, artifactory... e.g.,: maven.apache.org/repository-management.html
- http://docs.codehaus.org/display/MAVENUSER/Maven+Repository+Manager+Feature+Matrix
javax.cache are in jcache:jcache:1.0-XXX artifact (in Maven's central repo)
<dependency>
<groupId>jcache</groupId>
<artifactId>jcache</artifactId>
<version>1.0-dev-2</version>
</dependency>
javax.transaction.* classes are in javax.transaction:jta:1.1 artifact, JTA jar can’t be inserted in the Maven repository because the Sun’s Binary License (I know, this sucks). To use it you need to download manually the JAR (it's free) and put it into a local repo or use 1.0.1B version which is contained in java.net.
NOTE: I've read in some place JTA will be integrated in future versions of the JDK
I know is really a pain to find these artifacts in Maven's repositories but you can make a search of a class in www.mvnrepository.com and it will show you the correct groupId and artifactId for mostly all the packages.
In the particular case of JTA, I hit this post:
http://www.jugpadova.it/articles/2005/11/26/maven-2-spring-and-jta-depencies
.. which makes sense, if I didn't have to spend a lot of time in Oracle's horrible site to get the forementioned JAR file. (I was an Oracle's enthusiast myself but that site could use a lot of UX rework here and there).
I decided to replace the dependency with what Hibernate provides, via Geronimo, as per this post (worked perfectly):
https://forum.hibernate.org/viewtopic.php?p=2420836
The deal with Java licensing and Maven is currently being worked on by the Hibernate team, or so it seems here:
https://hibernate.onjira.com/browse/HHH-4548
Thanks to everyone for sharing!

Categories

Resources