Showing posts with label Maven. Show all posts
Showing posts with label Maven. Show all posts

Friday, 5 February 2016

Moving from Maven to Gradle in under 5 minutes


  • How to move a project from Maven to Gradle
For mainly historic reasons I've been a heavy Maven users for all my projects and not really dipped more than a toe into the 'holy grail' that is Gradle.

So I was pleased to be set the challenge by one of my clients, that as part of the delivery they wanted the code moved from Maven to Gradle.


After a bit of research (as well as some trial and error) I can take you through the steps that should be able to convert a Maven project to Gradle in about 5 minutes. (Note I've used IntelliJ but I would imagine this should be pretty much the same on any other IDE - or even if you're not using an IDE). 


  1. Install Gradle on your machine.  You can get the software from here.
  2. Check out (or copy) your code into a new directory.  This is not strictly necessary but it makes things cleaner.
  3. cd into the directory that contains your pom.xml
  4. Run the command: run gradle init.  This will create a new gradle project creating a build.gradle file based on your pom.xml.  (Note this is an incubator feature but it seems to work quite well).
  5. Create a new IntelliJ project as follows:  File -> New -> Project From Existing Sources. Select the build.gradle file you created in the previous step and choose the following defaults as in this dialog:


    That's really all there is to it. A brand new Gradle project.

    Here are some additional notes I found useful as a Gradle newbie:
    1. If you want to include files you already have in your existing Maven .m2 repo add mavenLocal() as a dependency.
    2. Your dependencies get downloaded here (the equivalent of .m2): 
      .gradle/caches/modules-2/files-2.1
    3. This is the correct way to define jdk compatibility:def javaVersion = JavaVersion.VERSION_1_8;sourceCompatibility = javaVersion;targetCompatibility = javaVersion;
    4. To see the results of your tests as they are running add this method to your build.gradletest { testLogging {     events "started", "passed", "skipped", "failed", "standardOut", "standardError" }}
    5. If you have repositories that need authentication see here.

    Monday, 2 February 2015

    Maven Tip: All about executable jars

    An executable jar is an extremely useful artefact when it comes to distributing your code.  It means that, as long as Java is installed on the client machine, on Windows and Mac at least, your users can just double click the jar and program will launch. Alternatively on the command line the program can easily be launched with the simple command line java -jar xxx.jar. No fussing with classpaths and dependent jars.

    Creating a executable jar from Maven is pretty straight forward and involves using the maven-assembly-plugin. This can be configured and added to your pom.xml as below:

                <plugin>
                    <artifactId>maven-assembly-plugin</artifactId>
                    <configuration>
                        <archive>
                            <manifest>
                                <mainClass>com.example.Main</mainClass>
                            </manifest>
                        </archive>
                        <descriptorRefs>
                            <descriptorRef>jar-with-dependencies</descriptorRef>
                        </descriptorRefs>
                    </configuration>
                    <executions>
                            <execution>
                                <phase>install</phase>
                                <goals>
                                    <goal>single</goal>
                                </goals>
                            </execution>
                    </executions>
                </plugin>
    

    Let's drill into the details:
    <goal>single<goal> tells the plugin that we want to execute the single goal. For more documentation see here.
    <phase>install<phase> tells the plugin that we want this task to be run as part of the install lifecycle event.
    <descriptorRef>jar-with-dependencies</descriptorRef> tells the plugin that we want the jar to include all dependencies.
    <mainClass>com.example.Main</mainClass> tells the plugin which class should be launched when the jar is executed.

    In this case I set up the plugin to produce an executable jar during the install life-cycle but of course you can change that setting if you want it to be part of a different part of the life-cycle.

    Another task you will want Maven to do for you is to create your executable jar as part of the release.

    In order to do this you will need to configure the maven-release-plugin to create the executable jar. This can be done as below:


    <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-release-plugin</artifactId>
          <version>2.5.1</version>
          <configuration>
               <goals>install</goals>
               <preparationGoals>install</preparationGoals>
          </configuration>
    </plugin>

    The key thing here is the configuration of the preparationGoals which is called by release:prepare. When configured as a preparationGoal install is executed before committing (default preparationGoals are clean verify). By adding install to the preparationGoals we ensure that our executable jar will be built before the commit.  It will be tagged with the same number as the release.  If we are moving from version 1.3 to 1.4 the executable jar will be named xxx-jar-with-dependencies-1.4.jar.

    Compare what happens when you configure install as a completionGoal as opposed to a preparationGoal. In the same example as above, moving from version 1.3 to 1.4, if install was configured as a completionGoal, install would be run after the commit and the resulting executable jar would be called xxx-jar-with-dependencies-1.5-SNAPSHOT.jar.

    Goal (as opposed to preparationGoal and completionGoal) is run by release:perform. By default it calls deploy. See here as to why I configured it to call install.

    In summary I hope you can see how easy it is to build an executable jar with Maven and to have it released with the correct release tag every time you release your project.

    Monday, 19 January 2015

    Maven tip: Release Without Deployment

    This is how you do a Maven release, as simple as this:

    mvn release:prepare
    mvn release:perform

    This will move you up a version in your code. Say, for example your last released version is 1.2 (meaning the pom.xml on HEAD is on 1.3-SNAPSHOT), by default your release version will be moved to 1.3 and the version on the pom.xml on HEAD will be moved to version 1.4-SNAPSHOT.

    A nice feature is that if you use the flag -dryRun=true on either of the above commands you can go through all the steps without any of the files being checked in. It gives you an opportunity to examine the changes to the pom.xml files before you go through with the commit.

    To facilitate the release procedure you need to have these lines configured in your highest level pom.xml file.

    <scm
      <connection>scm:git:git@github.com:YourRepository.git</connection
      <url>scm:git:git@github.com: com:YourRepository.git</url>
    </scm>

    By default the code will be built and deployed to a server.  Typically you will want to deploy to Maven Central or to a local Nexus server.  This is done using the releaseProfiles property in the maven-release-plugin.

    But this will not always be the case.  If you just want to do a release of the code, to Git for example, and not deploy the code anywhere you need to override the default maven-release-plugin goal property, which by default is set to deploy and set it to install as below:

    <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-release-plugin</artifactId>
             <version>2.5.1</version>
             <configuration>
                  <goals>install</goals>
              </configuration>
    </plugin>



    Saturday, 17 January 2015

    Maven Tip: Adding a Custom Jar to your Maven Project

    Sometimes you come across a jar which you want to include in your Maven project but is not in Maven Central.  This happened to me recently with a great web scraping library called jaunt which I wanted to include in my Maven java project.

    One way (maybe the best way) is to add the jar to you local Maven repository which you can do with this command.


    mvn install:install-file -Dfile=jaunt0.9.9.4.jar -DgroupId=com.jaunt.code -DartifactId=jaunt -Dversion=0.9.9.4 -Dpackaging=jar

    Then add to your dependencies in Maven as below:

     <dependency>
                <groupId>com.jaunt.code</groupId>
                <artifactId>jaunt</artifactId>
                <version>0.9.9.4</version>
      </dependency>

    The issue with this methodology is if you want to share your project with people who don't have access to you local Maven repository.  For example, if you want to put your project on Git for general release.

    Of course you could always check in the actual source but that's not always possible or necessarily desirable. If you have any good solutions please leave in the comments.