Results for tag "maven"

Java Tip of the Week #7 – Maven Slow?

posted by Roberto Cortez on

Maven SlowThis week Java Tip of the Week is a follow up of last session about Maven. The first video covered aspects related to Maven Dependencies. This video will cover some techniques to speed up your Maven build.

Maven Slow?

Since Maven 3, you are able to run your builds in parallel. Depending on the build machine and the project structure, you might get a 60% speedup increase!

Also, there are some ways to selectively pick just the things you want to build, using the -amd and -am flags. These are available since Maven 2, but for some reason they don’t seem to be used that much.

Check the video:

For reference, here are the commands:

CommandDescription
mvn clean install -T 1CBuilds the project with one Thread per Core
mvn clean install -T 2CBuilds the project with two Threads per Core
mvn clean install -T 4Builds the project with fours Threads
mvn clean install -pl [project-name] -amdBuilds just the project specified in -pl and all the dependent projects.
mvn clean install -pl [project-name] -amBuilds just the project specified in -pl and all the required projects to build it.

Check the Maven wiki page about Parallel Builds.

Also, check this other post I wrote: Maven Common Problems and Pitfalls.

Remember to follow my Youtube channel for faster updates!

Leave a comment if you enjoyed it, if not leave one as well!

Java Tip of the Week #6 – Maven Dependencies

posted by Roberto Cortez on

This week Java Tip of the Week is about Maven. I’ve recently had session at Jfokus, called Maven Taming the Beast with the following abstract:

Maven Taming the Beast

Love it or hate it (and a lot of people seem to hate it), Maven is a widely used tool. We can consider that Maven has been the de-facto standard build tool for Java over the last 10 years. Most experienced developers already got their share of Maven headaches. Unfortunately, new developers are going through the same hard learning process, because they don’t know how to deal with Maven particularities. “Why is this jar in my build?”, “I can’t see my changes!”, “The jar is not included in the distribution!”, “The artifact was not found!” are common problems. Learn to tame the Maven Beast and be in complete control of your build to save you countless hours of pain and frustration.

And here are the slides:

Maven Dependencies

Since the presentation was only 15 minutes long (video should be available later), I made this week Java Tip of the Week a small demo of some of the issues discussed and the commands you can use to fix them:

For reference, here are the commands:

CommandDescription
mvn dependency:listDisplays the list of dependencies for the project.
mvn dependency:treeDisplays the dependency tree for the project, including transitive dependencies.
mvn dependency:analyzeAnalyzes the dependencies of the project and determines which are: used and declared; used and undeclared; unused and declared.
mvn dependency:tree -DverboseDisplays the dependency tree for the project, including transitive dependencies and omitted dependencies due to Dependency Mediation.
mvn install -Dmaven.repo.local=/tmp/.m2Points Maven local repository to a new directory, forcing Maven to download everything again.

Also, check this other post I wrote: Maven Common Problems and Pitfalls.

Remember to follow my Youtube channel for faster updates!

Leave a comment if you enjoyed it, if not leave one as well!

Tenth Coimbra JUG Meeting – Maven Introduction

posted by Roberto Cortez on

Last Wednesday, 4 November 2015, the tenth meeting of Coimbra JUG was held at the Department of Informatics Engineering of the University of Coimbra, in Portugal. The attendance was great. We had around 40 persons and a lot of them were on a Coimbra JUG meeting for the first time. We had the pleasure to listen Sérgio Ferreira talk about Maven. Sérgio is an old time member of Coimbra JUG and he volunteered to present the session for us for the first time. A big thanks to Sérgio! It’s not easy to do it.

Love it or hate it (and a lot of people seem to hate it), Maven is a widely used tool by 64% of Java developers (source – Java Tools and Technologies Landscape for 2014). Most experienced developers already got their share of Maven headaches. Usually in the hard way, banging with their head into a brick wall. Unfortunately, I feel that new developers are going through the same hard learning process. In a young JUG as ours, it makes perfect sense to have a dedicated session to Maven, since sooner or later everyone will have to use Maven.

Coimbra JUG Meeting 10

As always, we had surprises for the attendees. IntelliJ sponsored our event, by offering a free license to raffle among the attendees. Congratulations to A. Ventura and Ana Filipa for winning the license. Develop with pleasure! We also handed a few Tomitribe and ZeroTurnaround t-shirts.

Here are the materials for the session:

Also, we already have our 11th and 12th Meetings scheduled for 2 and 9 of December of 2015. These are going to celebrate our 2nd Anniversary and we are happy to have two international well know speakers: Heather VanCura and Christoph Engelbert. Please, check our Meetup website for more information.

Enjoy!

Configure JBoss / Wildfly Datasource with Maven

posted by Roberto Cortez on

Most Java EE applications use database access in their business logic, so developers are often faced with the need to configure drivers and database connection properties in the application server. In this post, we are going to automate that task for JBoss / Wildfly and a Postgre database using Maven. The work is based on my World of Warcraft Auctions Batch application from the previous post.

Maven Configuration

Let’s start by adding the following to our pom.xml:

We are going to use the Wildfly Maven Plugin to execute scripts with commands in the application server. Note that we also added a dependency to the Postgre driver. This is for Maven to download the dependency, because we are going to need it later to add it to the server. There is also a ${cli.file} property that is going to be assigned to a profile. This is to indicate which script we want to execute.

Let’s also add the following to the pom.xml:

With the Resources Maven Plugin we are going to filter the script files contained in the src/main/resources/scripts and replace them with the properties contained in ${basedir}/src/main/resources/configuration.properties file.

Finally lets add a few Maven profiles to the pom.xml, with the scripts that we want to run:

Wildfly Script Files

Add Driver

The scripts with the commands to add a Driver:

wildfly-install-postgre-driver.cli

Database drivers are added to Wildfly as a module. In this was, the driver is widely available to all the applications deployed in the server. With ${settings.localRepository} we are pointing into the database driver jar downloaded to your local Maven repository. Remember the dependency that we added into the Wildfly Maven Plugin? It’s to download the driver when you run the plugin and add it to the server. Now, to run the script we execute (you need to have the application server running):

mvn process-resources wildfly:execute-commands -P "install-driver"

The process-resources lifecycle is needed to replace the properties in the script file. In my case ${settings.localRepository} is replaced by /Users/radcortez/.m3/repository/. Check the target/scripts folder. After running the command, you should see the following output in the Maven log:

And on the server:

wildfly-remove-postgre-driver.cli

This script is to remove the driver from the application server. Execute mvn wildfly:execute-commands -P "remove-driver". You don’t need process-resources if you already executed the command before, unless you change the scripts.

Add Datasource

wow-auctions-install.cli
The scripts with the commands to add a Datasource:

We also need a a file to define the properties:

configuration.properties

Default Java EE 7 Datasource

Java EE 7, specifies that the container should provide a default Datasource. Instead of defining a Datasource with the JNDI name java:/datasources/WowAuctionsDS in the application, we are going to point our newly created datasource to the default one with /subsystem=ee/service=default-bindings:write-attribute(name="datasource", value="${datasource.jndi}"). In this way, we don’t need to change anything in the application. Execute the script with mvn wildfly:execute-commands -P "install-wow-auctions". You should get the following Maven output:

And on the server:

wow-auctions-remove.cli

This is the script to remove the Datasource and revert the Java EE 7 default Datasource. Run it by executing mvn wildfly:execute-commands -P "remove-wow-auctions"

Conclusion

This post demonstrated how to automate add / remove Drivers to Wildfly instances and also add / remove Datasources. This is useful if you want to switch between databases or if you’re configuring a server from the ground up. Think about CI environments. These scripts are also easily adjustable to other drivers.

You can get the code from the WoW Auctions Github repo, which uses this setup. Enjoy!

Maven Common Problems and Pitfalls

posted by Roberto Cortez on
tags:

Love it or hate it (and a lot of people seem to hate it), Maven is a widely used tool by 64% of Java developers (source – Java Tools and Technologies Landscape for 2014).

Most experienced developers already got their share of Maven headaches. Usually in the hard way, banging with their head into a brick wall. Unfortunately, I feel that new developers are going through the same hard learning process.

Looking into the main Java conferences around the world, you cannot find any Maven related sessions that guide you through the fundamentals. Maybe the community assumes that you should already know them, like the Java language itself. Still, recycling this knowledge could be a win-win situation for everyone. How much time do you or your teammates waste with not knowing how to deal with Maven particularities?

If you are reading this, I’m also going to assume that you grasp Maven basics. If not, have a look into the following articles:

There a lot of other articles. I see no value in adding my own, repeating the same stuff, but if I feel the need I may write one. Let me know if you support it!

Anyway, I think I can add some value by pointing out the main issues that teams came across when using Maven, explain them and how to fix them.

Why is this jar in my build?

Due to Maven transitive dependencies mechanism, the graph of included libraries can quickly grow quite large.

If you see something in your classpath, and you didn’t put it there, most likely is because of a transitive dependency. You might need it or maybe not. Maybe the part of the code of the library you’re using doest not required all those extra jars. It feels like a gamble here, but you can have a rough idea if you use mvn dependency:analyze. This command will tell you which dependencies are actually in use by your project.

I mostly do trial and error here, exclude what I think that I don’t need and run the code to see if everything is OK. Unfortunately, this command doesn’t go so far to tell you if the transitive dependencies are really needed for the dependencies that you are using. Hey, if someone knows a better way, let me know!

I can’t see my changes!

This can happen because of multiple reasons. Let’s look into the most common:

Dependencies are not built in the local repository

You may have Module A and Module B. Module B has a dependency to Module A. The changes you made to Module B are not visible in Module A.

This happens, because Maven look into it’s own local jar repository to include in the classpath. If you make any changes, you need to place a copy of new jar into the local repository. You do that by running mvn install in the changed project.

Dependency version is not correct

This can be so simply as to change the version of the dependency that you are using, or a real pain to figure it out. When Maven performs the dependency lookup, it uses the rule Nearest Definition First. This means that the version used will be the closest one to your project in the tree of dependencies. Confused? So do I. Let’s try an example.

You want to use dependency Dv1 in your project A, but you’re getting Dv2, and you have the following dependency tree:

A -> B -> C -> Dv1

A -> E -> Dv2

Which dependency of D is included? Dv1 or Dv2? In the case Dv2 because of the Nearest Definition First rule. If two dependency versions are at the same depth in the dependency tree, it’s the order in the declaration that counts.

To fix this problem you could explicitly add a dependency to Dv1 in A to force the use of Dv1 or just exclude Dv2.

If you use the command mvn dependency:tree it will output a tree will all the dependencies and versions for the project. This is very helpful to debug these kind of problems.

Remote repository has overwritten your changes

It’s usual for companies to have an internal Maven repository, to cache artifacts, store releases or serve the latest changes of the project you are working on. This works great most of the time, but when you’re working with SNAPSHOT versions, Maven is always trying to pick up the latest changes to that dependency.

Now, you are happily working on your Project B changes which has a dependency to Project A. You build everything locally and proceed to integrate the changes in Project A. Someone or something, upload a new SNAPSHOT version of Project B. Remember, your changes are not visible yet, since you have everything locally and did not commit to VCS yet. The next build you make of Project A it’s going to pick the Project B from the company repository and not the one in your local repository.

The jar is not included in the distribution!

To add a little more confusion, let’s talk about scopes. Maven has four scopes: compile, provided, runtime and test. Each dependency has a scope and the scope defines a different classpath for your application.

If you are missing something, and assuming that you have the dependency defined correctly, most likely the problem is in the scope. Use the compile scope to be on the safe side (which is the default). The commands mvn dependency:analyze and mvn dependency:tree can also help you here.

The artifact was not found!

Ahh, the dreaded “Could not resolve dependencies … Could not find artifact”. This is like the Java NPE! There are many reasons for why this happens. A few more evident that others, but a pain to debug anyway. I usually follow this checklist to try to fix the problem:

  • Check that the dependency is defined correctly
  • Check if you are pointing to the correct remote repositories that store the dependency
  • Check if the remote repository actually holds the dependency!
  • Check if you have the most recent pom.xml files
  • Check if the jar is corrupted
  • Check if the company repository is caching the internet repositories and didn’t not issue a request to get the new libraries
  • Check if the dependency definition is being overridden by something. Use mvn help:effective-pom for the actual maven setting building the project
  • Don’t use -o

Conclusion

Maven is not a perfect tool, but if you learn a few of tricks it will help you and save time debugging build problems. There are other that fix a few of these problems, but I don’t have enough knowledge to be able to voice my opinion about them.

Anyway, a big chuck of projects use Maven as a build tool and I believe that developers should know about their build tool to be able to perform better in their everyday work. Hopefully this post can be useful to you.

Feel free to post any other problem not covered here. Unfortunately, Maven sometimes seems a box full of surprises.

One last advice: Never trust the IDE! If it works on the command-line then it’s an IDE problem!