lunes, 6 de diciembre de 2010

Tunning your Maven project

Content:

Maven abstract.
Tunning your Maven proyect
Maven standard folders
Managing dependencies with Maven
Adding a nature in Eclipse
Maven profiles inheritance

Now let's suppose you want to build a new Maven project in SpringSource,

New Project -> Other -> Maven project.

You already know about the benefits of a Maven project and you want to roll your own like a library, without Spring dependencies.

As soon as you have created your project, you notice that your project doesn't have any resource folder as source folder. They doesn't exist in the folder hierarchy either. But you need those folder for Unit Testing (that is something that will be explained afterwards).


Round one, fight!

As a Eclipse user, the first you think is you may create those folders manually- Create a "resources" folder inside "main", and another "resources" inside "test", then register them as "source folders" in Properties -> Java Build Path -> Source -> Add Folder. By selecting the new folders you may access resource files throw classpath.

It's important to sort the order of folders in Order and Export tab, put your main/resources above your test/resources entry.

Now create three files, "a.xml" in "main/resources", a different copy of "a.xml" in "test/resources" and finally one "b.xml" in "test/resources".

Try it please. Then Run As -> Maven Install and you will get a jar file in your target project directory. Unzip your jar, you should find an "a.xml" with the content of "main/resources" and "b.xml".

What did it happened?

Maven will export every file in "source folders", compiled or not, that's the reason of the undesired existence of "b.xml". We shouldn't export our testing data!
If Maven finds two or more files with the same name, it is chosen by classpath priority, so it is important to tune it well in "Order and Export" tab.

Nevertheless, we don't find the result appropriate, because we don't want to export our testing data.

Take a look to your "Order and Export" tab, you can't uncheck your "Source folders" for exporting (the box at the right of the entry), so, this isn't a good solution.


Round two, fight!

Please delete both entries from "Source folders" in Properties -> Java Build Path.

Now go to "Libraries" tab in the same dialog. "Add class folder" and check your main and test "resource" folders.

Is it the same than before? no. Because now you can drift to your "Order and Export" tab and check your "main/resources" folder for exporting, and not the same for "test/resources" one.

Run As -> Maven Install. Unzip your Jar and see how magically you haven't exported your testing resources. :) Terrific.

DELETE your project, without deleting sources or resources. Only the project from your workspace. Reimport it like a "Existing Maven Project" and... Ops, you have lost all your classpath configuration. Yes, you can reimport like a Simple Project as well, but have now experienced what will happen when any of your workmates download your project from any cvs/svn/other repository.

Take a look to your ".classpath" file, there you have all your configuration. But this file won't be uploaded to the repository, and therefore, no mate will be able to export this library correctly.

You have draft this round too ;)


Round 3, fight!

By losing your second round, you must have noticed that you can't win this battle by using local classpath files. Indeed, you won't never export it to the repository, so the solution must be as exportable as functional.

Take a look to your "Java Build Path" again, 

Let's take a look to your pom.xml file. It's quite clean, isn't it? Let's take a look to the "Super POM.xml" from Maven.

See the build entry:

<build>
    <directory>target</directory>
    <outputDirectory>target/classes</outputDirectory>
    <finalName>${artifactId}-${version}</finalName>
    <testOutputDirectory>target/test-classes</testOutputDirectory>
    <sourceDirectory>src/main/java</sourceDirectory>
    <scriptSourceDirectory>src/main/scripts</scriptSourceDirectory>
    <testSourceDirectory>src/test/java</testSourceDirectory>
    <resources>
      <resource>
        <directory>src/main/resources</directory>
      </resource>
    </resources>
    <testResources>
      <testResource>
        <directory>src/test/resources</directory>
      </testResource>
    </testResources>
  </build>


Quite appealing, I will take it as is and drop it in my "pom.xml". Delete and reimport as Maven project.

That is what you will find:
.classpath independent, the information is in your "pom.xml" file.
Files under "testResource" member of "pom.xml" file won't be exported
Appropiate for sharing throw control version repositories, every mate will build the project correctly.


Epilogue

Now clean every fingerprint from this project, create a new one, create the same folders, the same files inside:

src/main/resources
a.xml

src/test/resources
a.xml (different)
b.xml

Delete the project, reimport it like a Maven one again... yes, Maven did it for you.

Those are the standard folders for a Maven project, and, by being standard, as far as you name your folder so, you won't have to configure they as testResource folders, and their content won't be ever exported.

You are 20% smarter than your mates, you woooon! :)


I will check my horrible English tomorrow. Enjoy this article as much as I enjoyed writing it.

No hay comentarios:

Publicar un comentario

Nota: solo los miembros de este blog pueden publicar comentarios.