I've been asked to apply Maven to a project. After browsing a dozen sites it appears that it's quite vast and I'm not familiar as I'd like with similar tools like Ant. Why is it used/preferred and what does it offer over a standard Eclipse project? Also, how could it be added to an existing project?
Why is it used/preferred and what does
it offer over a standard Eclipse
project?
It is a build tool which can build your project without the need for an IDE like Eclipse. It can create a jar or war or other artifacts from the source, performing a bunch of steps like compilation, running unit tests, etc.
Where maven scores over ant is in managing third-party dependencies and in convention over configuration (which mean less lines of build script if you follow convention).
Also, how could it be added to an
existing project?
You start by creating a new maven project, following the step here.
Place it in the root folder of your project
If your source and resource files do not follow maven folder convention, update maven properties suitably referring to this documentation.
Run mvn package
It will fail if it needs any third party dependencies, which you can add as specified in the doc
With some trial and error, you should have your project running with maven, possibly, much quicker than if you were to set up the same with ant.
Others are already provided sufficient resources to read more about maven.
I suggest to start reading here:
http://www.sonatype.com/books/mvnref-book/reference/public-book.html
Maven is a great tool when you know how to use it. Maven (at core) is a dependency manager.
You include in your pom.xml (similar in function to the build.xml from Ant) all the librairies your project depends on (example : apache commons) along with their version and Maven get them directly from a repository (by default, the central maven repository)
Then you do not have to manually install any jar to make your project work. All is downloaded and cached on your local machine. You can even create an enterprise repository where you put all the jars needed by your company
Maven uses the concept of artifacts which are pre-built library projects with their own dependencies
To mavenize a project, you'll have to write a pom.xml describing your project (examples are numerous), get rid of your libs directory (or whatever classpath you described under Eclipse) and add all your dependencies to your pom.xml
You could also check Mavenizer for a first-start
But Maven is a lot more what i've just said. Read the docs, read poms from librairies and you'll get used to it quickly ;-)
If you use the M2Eclipse plugin from Sonatype, it's just a matter of right clicking the project in the package explorer and choosing Enable Dependency Management in the Maven menu. You are also advised to adjust the directories that contain the sources to the Maven standard directory layout but if you absolutely can't, you can configure that later.
Apart from that: Well, look for tutorials and documentation (for example there is the free book Better builds with Maven. Maven is very complex (yes, I don't think it is simple) and very powerful.
Related
Se lets say you are starting with a multi-module project. A library and two modules which will depend on that library.
I am planning on using ANT plus Ivy for dependency management. So I am looking for a way to integrate Eclipse + ant + ivy.
So the standard way of working with these tools would be to create a different project in eclipse for each module? or create a Single project and multiple src folders for each module?.
Although my question might seem like a very subjective one, I am looking for a standard way to handle multi-module projects under Eclipse when using an external tool for building and dependency management. And by a standard I mean, in a way that eclipse will find the dependencies for my project, auto complete works and src and javadoc will be available when needed inside the IDE, also that when debuging within Eclipse, the source will be attached to navigate through the breakpoints.
Please don't tell me to use Maven, I have used it already and hate it with passion.
You have IvyDE which works well with dependency management (can be Jar from repository or Ivy module in the workspace).
Each Eclipse project is an Ivy module whose dependency may be resolved from workspace (build path entry from eclipse project) or an Ivy resolver (build path entry from the Ivy cache).
For the developer workflow, I think you doesn't need Ant since Eclipse will build the projects for you, and for the CI build, the Ant script will use the same Ivy modules definition. The only difference is that at each module build, a publication will be done and you'll need something else (Jenkins?) to make dependency build trigger (which in turn will resolve their dependencies from Ivy and publish their artifacts).
There is also Ivy trigger after a publish task to trigger other project?
The Ivy buildlist task may work as well but never used myself.
I have multiple java projects in a folder. Also there is a second folder with libraries, that might be used as build dependencies from the projects. The projects may also have dependencies to other Projects. What's the best approach to build all projects ?
In other words I want to build the projects without explicit telling their dependencies.I think the biggest problem is the dependecy between the projects.
There are multiple build systems that are available that you may use. Maven has a complete dependency system built into it. Almost all third party open source jars are directly accessible via the World Wide Maven repository system. Basically, you describe the jar you need (groupId, artifactId, and version) and Maven will automatically fetch it for you. Not only that, but Maven also will build your project without having to create a build file. Instead, you have to describe your project in a project object model (a pom.xml file) and Maven will download everything you need, including all compilers, etc.
Almost all new projects use Maven, but Maven has a few downsides:
Since you don't control a build process, it can sometimes feel like poking a prodding a black box to get the build to work the way you want.
Documentation can be scant -- especially if you're moving beyond basic Java compiles.
You usually have to arrange your project in a specific layout. For example, source files should go under src/main/java while JUnit tests are under src/test/java. You don't have to follow the recommended layout, but then you'd have to modify the pom.xml file this way and that to get your build to work. That defeats the whole purpose of the pom.xml in the first place.
If you already have another build system setup (like Ant), you lose everything. There's no easy way to move from Ant to Maven.
The other is called Ant with Ivy. Ivy uses Ant for building, but can access Maven's world wide repository system for third party dependencies. It's a great compromise if you already are heavily invested in Ant. I also find Ant with Ivy to be better documented than Maven (although that's not too difficult). There's an excellent chapter going over the basics of Ivy in Manning Publication's Ant in Action.
With either process, I would recommend that you build a company wide Maven repository using either Nexus or Artifactory. This way, any proprietary third party jars (like Oracle jars) can also be stored in your company wide Maven repository since they won't be in the standard World Wide Maven repository.
By the way, if this is a company wide effort, and you are moving multiple Ant projects into Ivy, I have an Ivy project I use in Github that makes things easier.
Oh, there's a third possibility called Gradle which I know nothing about. I also believe it can use the World Wide Maven repository. It's based on Groovy which is based on Java syntax, and that's about all I can say. Maybe others can fill you in on the details. The Gradle group contends it solves a lot of problems of both Ant/Ivy and Maven.
Whatever tool you use, if you have various projects interdependent, you need to be clear on the independent ones which will be built first before building the dependent projects. You need to have a clear dependency structure for your projects.
You can do this with Apache Ivy. You can lay out the locations for you common libraries, define published artifacts and inter-dependencies in an ivy.xml document in each project, and let a top-level Ant build with the Ivy tasks figure out what the build order should be based on those dependencies.
I downloaded Java source code of some project that works with Maven. After checking out
the code to Eclipse, and then building it from the command line, I followed the instructions
and imported it from Eclipse as: File > Import > Maven Projects. Now I have the core source code and many additional sub projects that seem to have the same thing like the core, just separated.
Could anyone please explain me what are these sub projects? why I need them? and on which code I need to work now if I want to make changes, the core or the new imported Maven ones?
I don't know nothing about Maven besides the fact that it's a tool for building code and managing releases.
Thanks!
In Maven land, these are called modules. There a nice way to further divide a project into very distinct pieces.
People handle Maven differently. I've seen projects where there was the actual project module, then 10 or so implementation modules. Most people use them for the above mentioned separation.
Most likely, your going to need all of the modules in order to work correctly.
To modify the project, your going to need Maven. I don't know if Eclipse has an embedded maven, but at least NetBeans does. With this you can modify anything that you want, then build it with Maven, which should be just a simple click.
In addition to what #Quackstar said:
Eclipse has embedded Maven support provided by the m2eclipse plugin. When you import a Maven project consisting of multiple modules, the default behavior is to map each Maven module as a separate Eclipse project. This allows the Eclipse build paths to be constructed in a way that matches the declared Maven module dependencies.
There is also a way to map a multi-module Maven project into a single Eclipse project that entails enabling m2eclipse's "Nested Module" support. This results in an Eclipse project with a build path that is an amalgam of all of the Maven module dependencies ... and not exactly correct. This approach is not recommended by the m2eclipse developers, and I've heard they are intending to remove the nested module feature entirely in a future release.
Perhaps the reason I stalled learning Java until now is because I HATE how Java handles external libraries. I'm stuck keeping them in one place, adding them individually, fixing problems with versioning and every time I move/rename them, and copying and writing the classpath over and over each time I release a Java application.
There has to be an elegant solution to all of this. I keep all of my libraries (regardless of task, platform, or other) in their own little folder inside a "lib" folder in my development folder, kind of like this:
Dev
-lib
+JS-jQuery
+Flex-Degrafa
-Java-Xerces
+Xerces-1.2.3
+More libraries
I can use either Netbeans or Eclipse for Java dev, but none of them provide a very streamlined (and not to mention idiot-proof) way of managing all of these.
A nudge in the right direction or an online article/tutorial on this would be greatly appreciated.
You can either use Ant + Ivy or Maven to manage your library dependencies.
If it is only dependency management you're after and you're happy with the rest of your build process, I would use Ivy, as it can unobtrusively manage your dependencies, leaving your existing build process intact. There is a plugin for Eclipse called IvyIDE that contributes your dependencies via a classpath container.
Maven 2 has a steeper learning curve but provides a much richer set of functionality for building your projects and Eclipse integration through m2eclipse or IAM.
Personally I use Maven as I have a large number of projects to work with and Maven is particularly suited to efficient development across lots of projects.
Have a look at the introductory documentation to see what works for you.
Ivy Tutorial
Maven Getting Started Guide
Netbeans 6.7.1's Maven support is quite good and comes out of the box with the IDE.
The Eclipse addon was frustrating enough that I gave Netbeans another try.
A third choice besides ChssPly76's options is to use Ant with the Maven Ant Tasks. I don't know if I'd call any of these solutions particularly "elegant," but they do spare you the need to manage your own lib/ directory and classpath variables.
If you're working on Linux you can install Java libraries with APT or RPM.
Otherwise, I normally check precompiled JARs into a lib directory in my project's version control repository and make sure the names of the JAR files include full version information. E.g. lib/foo-1.5.6.jar, not lib/foo.jar.
To avoid having to manually set the classpath before running your app, you can set the classpath in the Manifests of the JARs themselves to define the dependencies of each JAR file. The JVM will follow all the dependencies when loading classes.
Maven is often more trouble than it's worth, but the ability to open a maven project directly into IDEs such as IntelliJ is excellent. For example, IntelliJ will download all dependencies and have them available without having to run a build first, or an mvn command and then a project refresh. It also isn't necessary to re-generate the project every time a dependency is added. I work with a number of Eclipse developers who switched to IntelliJ for this alone.
However, one shortfall of Maven is that many libraries (or versions of libraries) are not available on public repositories. Therefore it is often necessary to set up a local repository such as archiva. In ant, it would just be a matter of adding it to the lib directory in the repository.
Maven can also attack when you need to do something that maven doesn't directly support via a plugin. What would normally be a few lines of ant can often turn into a morning's worth of work.
Finally, buildr is an excellent way of using Maven's dependency management and plugins, while also supporting ad-hoc tasks.
Our software is written in Java and comprise many (7) projects.
These projects are Netbeans ant projects.
I'm considering to converting them to maven2.
Where can I find some hints for doing such thing?
Don't read that book. It will only make you confused. Read this book instead: "Maven - The definitive guide" http://www.sonatype.com/books/maven-book/reference/ .
Also, the maven site has a lot of information, but the structure is terrible so you'll need to use google to navigate in it.
Here is my suggestion:
Do this by hand, not with "automagic" "help" from the IDE. Maven integration doesn't work that good yet, not in any IDE.
Make sure you program project is divided into modules under a common umbrella module, so that each module produces a single binary artifact (jar, war,...) possibly accompanied by the javadoc of the source code behind that artifact, a zip with the source code etc. The basic principle is that each module produces a single artifact, containing all the non-test-code under that module. You can do this while the project is still built by ant.
Each module should conform to the standard maven directory layout. The build destination is under [module]/target/[output-type, e.g. "classes"]. The source code is under [module]/src/main/[src-type e.g. "java"] and [module]/test/[src-type]. The artifact consists of all the code under src/main, and none of the code under src/test, as it built to the target directories. You can do this while the is still built by ant.
Start by transforming the sub-module that has no dependencies on other modules in the project.
Now you can create the parent maven module pom.xml with artifact type "pom", consisting of one of the modules below. Make a child module for the first submodule (the one with only external dependencies), using the umbrella module as "parent". Remember that you need to specify version for the parent. Remember to add the child module as a "module" in the parent too. Always use ${project.version} as version in the child modules when you create multi-module projects like this. All modules under a parent must be released simultaneously in a single operation, and if you use this setting maven will make sure the version fields stay the same across all modules and gets updated everywhere during the release. This may make it difficult to re-use the existing numbering scheme, but that doesn't matter. You are never going to run out of version numbers anyway.
Add the necessary dependencies, and make sure you can build the parent and the child module together using the command "mvn clean install" from the parent module.
Proceed with the rest of the modules the same way. Dependencies to other modules under the same parent project should also use ${project.version} as the "version" they are depending on, meaning "the same version as this". NOTE THAT in order to build, the module you are depending on must be built using "mvn install", so that it gets deployed to you local (computer) repository. Otherwise the depending module will not be able to find the classes. There are NO source-code dependencies between modules in maven, only dependencies to built and packed versions installed in local and remote repositories. This can be very confusing if you come from ant-projects. Build from the root module until you get comfortable with this. It takes two days.
Don't use maven integration in IDEs. It is a bad idea. Use "mvn idea:idea" or "mvn eclipse:eclipse" to set up your workspace as a non-maven ordinary IDE project. The inter-module dependencies mechanisms in maven and the IDE aren't identical and will never be. Also, if you have several mavenized projects with dependencies in between, you want to have several of these in your workspace with dependencies set up between. You can do this with mvn idea:idea / eclipse:eclipse if you create a separate maven project file called "workspace.xml" (or whatever) in the same directory as parent module, set up as a multi-module project containing modules "." and "../otherproject" (only one-way reference here, no parent ref back). If you run "mvn idea:idea / eclipse:eclipse -f workspace.xml" you get a workspace with all these modules linked together. No IDE integration lets you do that. This sound like a lot of extra work, but the workspace.xml-file is really small. It doesn't have to contain all that dependency stuff and all that, only the reference to the modules you want to bind together in your IDE.
I did a succeful migration of NetBeans Ant project to Maven project using the instruccions by Joseph Mocker here: http://forums.netbeans.org/ptopic55953.html
I cite the important part:
close the project
rename the build.xml, nbproject files/folders to something so NB won't recognize them.
close and restart NB (so any memory cache knowledge of the project is gone)
copy in an empty pom from some other project.
open the project back up in NB (NB should now identify it as a maven project)
rearrange the files to follow the maven way (™)
This won't be an easy task since Maven2 expects the files to be organized in a specific way. Anyway Better Builds with Maven is a free book that should get you started. It will help you understand Maven and it also has a chapter on migration.
I discovered that the migration is not necessary. The real requirements that I need was automatic download of dependencies (libraries).
This is also achieved by Ivy which nonetheless uses maven repositories.
I solved converting project from ant to ant+ivy with IvyBeans.
I have built a script to migrate Ant builds to Maven. You can find more information here:
https://github.com/ewhauser/ant2maven
It won't help you with fixing your directory structure and or any additional Ant tasks, but it removes a lot of the tedious steps to get started.