Get started with maven - java

I have experience in Ant, how to get started with maven. Any advantage with maven over ant?

There's a quite large difference, where ant forces you to create your own targets you will get a default set of targets for maven, e.g., clean, install, package etc without scripting them.
Maven promotes that you use a common directory structure for java classes, resources etc. If you do, maven is just on xml file where you specify some project metadata such as name, package and most importantly depenencies. It provides similar dependency lookup to what ivy does for ant.
Based on the standard maven promotes, it becomes very easy for developers to approach and build your projects. With an IDE such as Netbeans it's enough to select open project, and then hit the install button to compile and install the project in your local repository.
I recommend working with maven the maven way. Doing things differently will often cause more pain than it's worth. Maven offers a plugin structure where you can perform various tasks, such as invoke the ant-library should you need to. If you're actively working with multiple projects (and want project switching to be as easy as possible) maven is a huge leap forward, especially if combined with repository server such as Nexus or Archiva.
To get started
Either you can generate your project structure using the archetype goal of maven, or you could do it the way I do by copy-pasing an empty template project every time. Then you need the maven binary and the project definition file pom.xml which I typically also copy paste between projects.
A sample is included below. With this sample you'll get the external library log4j, and you automatically get all nececcities to build and package your own project (in this case to a jar file).
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.company</groupId>
<artifactId>projectname</artifactId>
<packaging>jar</packaging>
<version>0.1.0-SNAPSHOT</version>
<name>${project.artifactId}</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
</dependency>
<!-- add more dependencies here ... -->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

Around two weeks ago, I was in the same situation. In my opinion, Maven is a lot more powerful as compared to Ant.
It has a generate command which makes it very easy to start new projects of various kinds (artifacts) and will also build a standard directory structure along with the pom.xml file,
thereby taking care of a lot of things that are needed to be written in the build.xml file of Ant.
Managing dependencies is also a lot better. Maven will download dependencies from repos and will store them in a central repo on your system. If a dependency is already present in the local repository, it will take it from there instead of downloading it again.
I use eclipse and maven has a command (mvn eclipse:eclipse) which creates the .classpath file in the project directory. So no need to add the libraries again in eclipse.
The Getting started guide on the maven website is a good resource and covers quite a lot of stuff -

In comparison to Ant what Maven does well is dependency management and standardisation of the build lifecycle.
As for learning a bit more about it, the Maven documentation is pretty readable and thorough.
I'd start by looking at the introductory piece that explains some of the core principles about the difference between Maven and other build tools.
http://maven.apache.org/what-is-maven.html
Then downlod and install maven, open your terminal and type...
mvn archetype:generate
Select all defaults and you'll end up with a simple build-able project with one runnable class and a matching test file. Use that as a test project to familiarise yourself with the build lifecycle and dependency resolution process.

Related

How to set up Maven project to optionally generate signature files

I maintain a small Java component published in Maven Central. In order to successfully publish the artifact, pgp/gpg signature files are required for all the artifacts. Following the directions here: https://central.sonatype.org/pages/apache-maven.html#gpg-signed-components, I can add this plugin to my pom.xml like this no problem.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
...
and I attach it to the verify or install phase. Now, when I run: "mvn install" or "mvn deploy" the .asc files are generated automatically as desired. Note: you also have to have your pgp/gpg machinery installed and configured properly for this to work.
This works OK for me as the artifact maintainer, but if someone else wants to clone my source code, modify it, and then run mvn install so they can make a locally modified version of the component available to other projects of theirs, they have to have all this pgp/gpg machinery setup properly too, which can be a pain. And they likely don't care about having signature files.
My question is, is there a recommended pom setup so the component maintainer can generate the .asc signature files when needed for a deployment (e.g., to Maven Central), but normal usage of Maven commands don't require signature generation?
I imagine I could use a profile in my pom to handle this. I did figure out a solution, which is pretty simple. Rather than adding the maven-gpg-plugin to my pom, I figured out I can actually just do this:
mvn clean install org.apache.maven.plugins:maven-gpg-plugin:sign deploy
This cleans everything, creates and installs all the artifacts locally, signs all the generated artifacts, and then deploys all the generated artifacts, including the signature files to the deployment target.
This does exactly what I want in 1 line without a pom modification, which is pretty cool. But are there other 'better' ways? Either way, I figured posting this way to do this might be helpful to others.
maven profile
One way using maven-gpg-plugin conditional it is put configuration of maven-gpg-plugin in profile.
You can simplify your profile by only add one property for skip / don't skip maven-gpg-plugin
Your project can look like:
<project ...>
<properties>
<gpg.skip>true</gpg.skip><!-- by default skip gpg -->
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.6</version>
<configuration>
<!-- ... -->
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>release</id>
<properties>
<gpg.skip>false</gpg.skip>
</properties>
</profile>
</profiles>
</project>
another plugin
You can also consider use another plugin for making signatures, eg: https://www.simplify4u.org/sign-maven-plugin/ sign-maven-plugin by default skips execution if private key not exist on running system.
Another feature of sign-maven-plugin is that don't need external software like gpg to make signature.
gpp.skip property
In my poms I set the gpp.skip property to true:
<properties>
<gpg.skip>true</gpg.skip>
</properties>
Its evaluated by the maven gpg plugin in the way, that signing is skipped by default, e.g.:
mvn install
To enable signing, you can set gpp.skip to false within pom.xml. But better you do it on the command line, so you don't have to modify your pom all the time:
mvn install -Dgpg.skip=false
You can also skip setting the property within the pom and skip signing like this:
mvn install -Dgpg.skip=true
But this way you (and other people working with your project) have to add this all the time to avoid signing. I find it more convenient when signing is turned off by default, as in the first solution. And I guess that's what you want.

Easily add libraries to Eclipse Java Oxygen

I know there are post about JAVA libraries in Eclipse and I used a way to add some .jar files (like apache.poi and jsoup) to my project. My question is:
Where do we have to put those libraries and what settings do we have to change, so to make the libraries available for every future project we start ?
Thank you!
The most common tools for bringing dependencies into a Java project are Maven, Gradle, and Ant. I'll focus on Maven, as I estimate it to be the most popular of the three (though I have come to prefer Gradle).
I'm going to assume you have the following prerequisites installed on your machine and each of the developers on your team:
JDK 1.7 or above (in other words, Java)
A Java-focused IDE like IntelliJ or Eclipse
Here's what you need to do:
You and your team members will install Maven
You will create a pom.xml for each new project.
You will specify the dependencies for the project (like jsoup) in your pom.xml
Here's what Maven will do for you:
It will download all the dependencies you specify from an online repository like https://mvnrepository.com/
It will cache the dependencies in a directory in your user home folder called .m2 so that it doesn't need to download dependencies more than once per project
It will resolve the dependencies within each of your dependencies and avoid putting the same dependency on the classpath twice
The minimum pom.xml file you need is as follows:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.yourcompany</groupId>
<artifactId>your-project</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.8.3</version>
</dependency>
</dependencies>
</project>
Copy that into a file called pom.xml in your root project directory. You can add any additional dependencies in the <dependencies> section of the XML file. By convention, all of your classes and code should go into the directory structure src/main/java/.
Any Java IDE you use will know how to open a project from a pom.xml file. In IntelliJ, you select File->New->Project from existing sources, navigate to your project's root directory, select your pom.xml, and click Open. IntelliJ will then open your project as a Maven project, read your pom.xml, and make all of your dependencies indexed and available for code completion and compilation.
Hope this helps

How to use multiple GitHub projects in one Eclipse project?

So I have a GitHub repo and I want to supplement it with other projects in other repos. I am using Eclipse and Java as my dev tools. Is there a video I can watch or a tutorial? I've looked on YouTube and Googled the problem -- I'm probably not building a proper query so find what I need.
I don't want to merge two repos into one repo. I want to incorporate the code in another repo into an Eclipse project on my dev machine that uses one of my repos. I think.
If I'm understanding you correctly, you wish to use other projects/libraries in your project. You should look into Java build tools (ev. Maven, Gradle and others). Among other things, they let you specify a list of dependencies for your project.
Maven example
First of all, you should set up your project to use Maven.
For instance, if you wish to use joda-time (a popular date and time library for Java), you could go to http://mvnrepository.com/ and look for joda-time. From there select your desired version and copy-paste the Maven dependency to your pom.xml file.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.myproject</groupId>
<artifactId>myproject</artifactId>
<version>0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.9.1</version>
</dependency>
</dependencies>
</project>
Now when you call mvn clean install from your commandline or use the Maven Eclipse plugin, your project is built and the dependencies you specified are downloaded and added to your class path.
Keep in mind, the source code for the dependencies is never added to your project, only the jar files are added to your class path.

How do I build my Maven pom in Eclipse?

I have a project that uses UI4J, and instead of using external jar I decided to go for maven, I am going to distribute it via git, so I guessed that this is a much better approach.
This is my pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>Kalamaria</groupId>
<artifactId>KalamariaHarverst</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>MavenFirst</name>
<dependencies>
<dependency>
<groupId>com.ui4j</groupId>
<artifactId>ui4j</artifactId>
<version>2.0.0</version>
<type>pom</type>
</dependency>
</dependencies>
</project>
The problem is that I can't find a way to get this to work. What ever I try I am still getting errors on the import of the library, meaning that the jar of the ui4j is not imported.
I have (among others) tried to do a "Maven bumvn eclipse:eclipseild" with "clean install" as goal
Downloading source and Updating Project from the Maven menu
even tried to do a mvn eclipse:eclipse from the console, but i got this error
The program 'mvn' can be found in the following packages: * maven *
maven2 Try: sudo apt-get install
How does this work, what should I do to import the declared jars?
Removing <type></type> was the correct first step that you need to do.
Now, there's probably still a pom.lastUpdated file in your repository that is wrong, you need to forcibly override it. The easiest thing to do is just delete the entire directory in your .m2 directory, which is located in your OS dependent home directory. On windows, this would be:
C:\Users\<username>\.m2\repository\com\ui4j
On Linux, this is usually in:
/home/<username>/.m2/repository/com/ui4j
Delete that directory, and then do Maven -> Update project, this should fix your problem.
By the way, mvn eclipse:eclipse is almost never the right thing to do, it's much better to use m2eclipse for your eclipse integrations as it works much more seamlessly.
I am not able to reproduce the behavior of the pom type being added automatically when you add the ui4j dependency. However, most of the time the correct dependency <type> is jar, as that is the default. pom dependencies are most often used when a project is simply a pom and nothing else, which is common as the parent pom of an entire application.
In this case (as in most cases), the type you want is jar, so don't specify a type parameter.
To add a bit more background to #durron597 's correct answer:
tag defines what Maven looks for in the repository when it downloads your artifact. Various types exist. Most common and default is "jar" - Maven will look for something packaged as "jar" - a regular *.jar file. Other types include "test-jar", "war" and "pom". Type "pom" means that Maven will look for something packaged as "pom" - basically your dependency's pom.xml file. Most of the artifacts you refer to are packaged as "jar" and do not supply "pom" packaging. See http://maven.apache.org/pom.html#Dependencies, search for "Type".

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.

Categories

Resources