Is this the right approach for structuring codebase? - maven-2

We have a Java codebase that is currently one Web-based Netbeans project. As our organization and codebase grows it seems obvious that we should partition the various independent pieces of our system into individual jars. So one Jar library for the data access layer, one for a general lib, one for a specialized knowledge access, etc. Then we'd have a separate project for the web application, and could have one for a command line tools app, another web app eventually, etc.
What is the recommended practice for doing and managing this? Is it Maven? Can it all be effectively done with just Netbeans alone by simply creating individual projects and setting the dependecies of one project on the jar files of the others?

I'd agree with SteveG above on using Maven2 to help you modularise your code base, but I'd use Nexus as the local repository for Maven instead of Archiva. The guys at Sonatype also have an excellent (free html/pdf) book on how to use Maven, Nexus, and integrate it into IDEs.
Be careful on how you decide to partition up your projects, though. There's no sense in over-complicating your dependencies just for the sake of it.

I would definitely say check Maven(2) out. It is very good for doing this sort of thing. You can define individual models and version then very easily. Netbeans also does a decent job of integrating with.
Also I suggest you set up Archiva which will let you be dependent upon binaries of other artifacts that your company generates internally. This also acts as a proxy and will keep a local copy of any external dependencies your projects might have so its very quick to get the new versions internally.

I would create ant scripts to build the pieces and for deployment. Then you are not depending on your IDE for build/deployment.

It sounds like your code is getting to the point where you're graduating from the WAR approach and have entered into the EAR level.
An EAR is just another archive that contains all the other JARs and WARs that get combined to create an application. There are four types of modules that can reside inside it, Web, EJB, Connectors and Utilities. Most people only use Web and Utilities so they go with using the WEB-INF/lib approach.
But if you're starting to get a lot of interdependencies what you do create an EAR project and make your web project a child of it. Each Utility JAR which is just straight Java code used by other modules also becomes a child of the EAR. Finally in each of your projects there should be a META-INF/manifest.mf file that just has the name of the JARs that JAR/WAR depends on.
I'm an eclipse guy and most of this gets taken care of for you in eclipse, but I'm sure netbeans has very similar functionality.
Now the only problem is that you have to use a full Java EE server to deploy an EAR so I don't think you can use Tomcat if that's what you're currently using.

Related

Central store for build artifacts in .Net

I know Maven has a central repository that you can upload build artifacts (assemblies) and reference them in your build script so that you get the latest versions.
Is there any similar tool (other than Maven for .Net) that provides a way to centrally store artifacts and reference them in MSBuild scripts?
I'm trying to figure out how to incorporate a library solution we have that is used across all our other solutions (contains common data access, schemas, etc.)
We don't always automatically want it included in our projects as sometimes we need to stay on a particular version for one project until that project is ready to upgrade to the latest.
If I were you, I'd create a build system that allows publishing packaged 'modules' from one end, and importing from the other end.
You create a shared directory at a global place within your organization and this becomes your "central Repository" you're talking of.
Alas, I'm not aware of any public implementation of such an msbuild system.

Delivering a single jar with a Maven project

I want to deliver a single .jar file to my clients, but my project is currently built with Maven, and I have several modules that generate a single .jar each.
I know nesting different .jar files is not a great idea, so I am not sure how can I achieve this.
Any ideas?
If you really want to go this direction, there are several ways to do that:
with the Maven Assembly Plugin and maybe the jar-with-dependencies predefined assembly descriptor (that will unpack dependencies)
with the Maven Shade Plugin (similar to the above one but gives more flexibility)
with the Maven One-Jar Plugin (that uses One-JAR and its custom classloader to allow nesting of JARs)
Depending on your exact requirements and constraints, you might prefer one or the other.
First of all, ask yourself if you have a really good reason for packaging your application and all of its dependencies in to a single jar. I haven't found a very many good reason for this at all (with most reasons being related to organizational policy foolishness or just plain ignorance). The way to go is to keep libraries in their own jars and supplying a .zip/.tar.gz containing all of your libraries and your application with either
An executable .jar with the
classpath setup appropriately in
your MANFIEST.MF file
a .bat/.sh
script that invokes java and builds
an appropriate classpath based on
your deps
Conversely, use JNLP (better known as Java Web Start).
If you really want to have maven bundle all of your dependencies and your application under a single jar, what you want to use is the "jar-with-dependencies" predefined assembly. The maven assembly plugin usage page also shows how you might this up as well.
You can try Maven Shade plugin too.
http://maven.apache.org/plugins/maven-shade-plugin/
General instructions on how to use the Shade Plugin can be found on the usage page. Some more specific use cases are described in the examples given below. Last but not least, users occasionally contribute additional examples, tips or errata to the plugin's wiki page.
In case you still have questions regarding the plugin's usage, please feel free to contact the user mailing list. The posts to the mailing list are archived and could already contain the answer to your question as part of an older thread. Hence, it is also worth browsing/searching the mail archive.
If you feel like the plugin is missing a feature or has a defect, you can fill a feature request or bug report in our issue tracker. When creating a new issue, please provide a comprehensive description of your concern. Especially for fixing bugs it is crucial that the developers can reproduce your problem. For this reason, entire debug logs, POMs or most preferably little demo projects attached to the issue are very much appreciated. Of course, patches are welcome, too. Contributors can check out the project from our source repository and will find supplementary information in the guide to helping with Maven.
Actually, nesting .jar files is not possible. A jar can't have other jars in it.
.war and .ear files can contain jars, and that's a good solution if you're delivering a J2EE application.
If your app is just J2SE, however, I recommend looking at the Maven Assembly plugin. As the name implies, it allows you to create a single binary distribution of your build.

Questions to Determine Maven Knowledge

I requested Maven training at work, and the bosses want to hire someone who knows Maven to come work with us as a consultant so that we'll learn Maven from a real-world perspective instead of a training perspective.
I've been tasked with coming up with questions of various difficulty to ask potential hires in order to ascertain their Maven ability. The problem is that I don't fully understand Maven yet (hence the training request).
What questions would you ask someone to determine their Maven ability, and what level of knowledge would someone have to have of Maven to answer them?
In my opinion, a "Maven consultant" should:
Have a good understanding of how Maven differs from other build tools like Ant (Maven provides a "lingua franca" for project management).
Have a good understanding of Maven principles: Conventions over Configuration, the default layout, the naming conventions, the philosophy of the tool (one primary output per project).
Have a good understanding of how Maven works: from where the conventions are coming from (the super POM), the lifecycles (main, clean, site), the phases, how plugins are bound to phases, the influence of packaging, etc
Know what profiles are and how they can be used to deal with different environments, how to trigger them.
Know how to use plugins, how to configure them, how to plug them in a maven build.
Know how repositories work, the difference between local and remote repositories, what SNAPSHOT dependencies are.
Know how dependencies are resolved, what transitive dependencies are, how to control them, what dependencies scope are, how to use dependencyManagement.
Know how to implement code health checks, the essential plugins (Checkstyle, PMD and Findbugs plugins), how to implement various kind of tests (unit, integration, functional), how to measure coverage, when to fail the build, when to report.
Know how to setup maven in a corporate environment (using a shared repository, setting up CI, a company POM).
Know how to handle advanced packaging scenarii (with the assembly plugin)
Know how to handle deployment, the various protocols, the deploy plugin, the release plugin, the SNAPSHOT resolution.
Know how to setup a Maven build for a Java EE project, how to setup a multi-modules build, what modules are required, how to test in the development environment, how to handle the production environment.
Someone with these skills should put you on the right path (and has very likely a decent experience of Maven).
A lot of good questions here, especially the ones proposed by Pascal Thivent. However, I would ask another question:
Q: What is the difference between the aggregation and inheritence in Maven?
A: You can have a short explanation here.
I would suggest that you think about what you wanna do with Maven, or why you wanna introduce it into your projects. Maybe ask your boss for his reasons/goals in introducing Maven.
After you have named your main goals why to introduce Maven. Ask potential consultants how they would use Maven to achieve those goals.
Examples 1
Goal: Improve overall code quality in project.
Question: How may we use Maven to improve our overall code quality in projects.
Possible answer: Maven has several plug-ins to force/meassure code quality in projects, we could integrate those into our buildscripts in almost no time. (e.g. checkstlye, pmd, cobertura, xradar...)
Examples 2
Goal: Creating automated deployment scripts for several destination environments.
Question: How may we use Maven to automatically deploy artifacts to several destination environments.
Possible answer: We could use Maven plug-ins for deployment (e.g. Cargo) and use maven's profiles to handle several configurations.
a.s.o.
I would ask:
Describe what is the practice of SCM?
Describe your ideal Maven infrastructure (server, repositories, CI, plug-ins, conventions, etc.)?
Both are very open questions, but they should give your a feeling of his skills and what you can learn from him and what he could bring to your company.
EDIT
Maven is just one piece in the overall software configuration management (SCM) strategy. A good consultant should know the details of maven in and out but also know how it fit in the big picture. Just like you expect a Java EE consultant to be expert in a Java but to know what it means to deliver enterprise application to a customer.
In the company I worked, we had a guy responsible of the SCM who had been a Maven contributor. And his view was way broader than "just" maven. He was in charge to have a productive build, configuration and release process. Two examples:
We were hard-coding the release number in java code to be able to display it into the "about" dialog of our desktop applications. Most of the time we forgot to change it after the release resulting in a mismatch between the actual release number and the about dialog -- big problem for integrators on-site. This was a bad practice. He then set up something so that the release number in Maven would be correct in the manifest file and educated us to read the manifest file from Java to ensure both match.
When you would release a module, he wrote a script to not only build the application, but also close the corresponding version in the ticket system (JIRA) and push the release notes in the wiki.
All that to say that knowing how to "mavenize" a project is important, but more important, the guy must understand how you currently work, what is in place and help you set up something reasonable to improve your productivity.
Here are the questions I would ask:
How would you enforce the use of JDK6
for a group of projects?
How would you enforce the use of a
particular version of a plugins?
What are some of the reasons why you
would use an assembly to build a jar
rather than the jar plugin?
Describe the process of releasing a
Java EE project made up of an EJB, a WAR
file and two utility jars.
How many repositories should an
internal company repository server have and why?
How would you structure a POM project made up of N child projects so they it can easily be used in Eclipse?
All of these questions have at least two answers. I would be looking for someone who can provide at least two answers and point out the pros and cons of each approach. Ideally, this person should be tweaking the set up to be less disruptive to the way your environment already works.
If you have the luxury, I suggest having the consultant come onsite for a day, give him/her an existing java project that you're working on and have him/her "mavenize" it for you. The next day, sit with him/her and have them explain how to compile, and build a jar (or war).
Or maybe have them come to the interview with a maven project to demonstrate. The should be able to compile, and build a jar/war at the very least, imo. If they can run unit tests, deploy to tomcat, integrate with any of the various frameworks like gwt, hibernate, spring, etc, then even better.

Should I migrate from Ant to Maven?

I am working on a fairly large project (with a number of modules, a bunch of external libraries etc.) and we are now considering switching from Ant to Maven. I understand the differences between the two, but I am not convinced that it is really worth spending time converting the project layout, setting up all the dependencies, teaching developers and configuration managers doing things "the new way" etc.
There are a lot of resources on the web describing how to migrate from Ant to Maven, but I haven't found that many that say why :-)
Before changing your build system, ask yourself (and the group) why you're changing? If you're changing just because Maven is the "new thing", don't. If you actually see a technical reason to migrate, do it.
In general, unless there's a major compelling reason to do so (new capabilities or much simpler management), I'd say stay with what you have for the current project, but consider Maven for future projects.
Have you read chapter 1 of "Maven, the definitive guide"? In particular, 1.7 Comparing Maven with Ant has an interesting discussion.
I agree with the other answers that advise caution. Maven has strong points, but nothing that can't be done by an Ant build process:
dependency management: Ant has the Ivy subproject, which can interact with Maven repositories.
convention over configuration: you can also do that with Ant, it's just a matter of establishing the rules and enforcing them.
build lifecycle: same as above, you can enforce a convention over the tasks exposed by each build.
build logic reuse (Maven plugins): you can also achieve that in Ant with macrodefs and task libraries.
The thing is, with Maven you get these features out-of-the-box, while with Ant you need a rock-solid build, a very strict set of rules and a way to enforce them (for instance, make sure that everyone follows the conventions when they create a new subproject, that they reuse the existing blocks instead of doing everything from scratch, etc.).
Personally, I would see how well the existing process addresses the issues above: how are dependencies managed, is there a central repository? Are the project structures uniform (when I checkout a project I don't know, how long does it take to figure out how to build it)? Is there some form of build logic reuse, or does each project reinvent the wheel? Which of these features are needed?
Then I would try to balance the cost of adding the missing features to the existing Ant script, against the cost of migrating to Maven (if you don't know Maven, that also includes the cost of learning it).
In any case, I suggest you build a small Maven prototype (5 to 10 projects) illustrating the common cases in your build. You can test a lot of Maven's features with dummy projects containing little java logic (use the archetype plugin to generate them).
Before Maven we were checking dependency libraries (typically third-party, open source variety) into source control - so that we could insure our components compiled and got packaged with the precise versions intended.
Now with Maven in place, we're relying on artifact repositories to hold those versions and we let our pom.xml dependency declarations be the official means of defining version dependencies. This has proven to be a simplifying approach that makes project organization in version control repositories (and their Hudson build projects) much easier to devise. Our local artifact repository is under backup policy along with our source control repositories. It's nice to use the Maven tools to go and search and specify a needed library version. We also use parent pom files to specify dependencies that other project poms inherit by default. So if you want all projects to use the same log4j version, then that is specified in one place in the parent pom file. (But any project can at anytime override and specify a specific version instead of just accepting the default from the parent pom.)
Here is the secret to a successful adoption of Maven:
Use Maven project build approach for
your new greenfield projects
Modify existing legacy projects that
use ant build.xml files to incorporate Maven task
for managing depenedencies (a hybrid
approach)
The benefit is that you can then get all of your projects under Maven dependency management, which is of course it's greatest benefit.
The nice thing about the Maven task for ant, where you specify all dependencies in a pom.xml file, is that it involves just modest modification of the existing ant build.xml file to incorporate Maven for this. From the ant file's perspective, Maven is just a means for defining classpath definitions, which are subsequently used by the various ant build task.
The Maven scope classifier of dependencies can be utilized when defining classpaths such that a suitable classpath can be set for compiling, running unit test, packaging, et al. Other definitions in the pom can also be accessed as ant property definitions.
A lot of existing ant build files are rather complex. It can be a formidable undertaking to convert such projects to a full Maven build process. This hybrid approach of having Maven manage all the dependencies and leave the bulk of the ant build.xml file as is, is most pragmatic.
First, like I'm sure a lot of people will mention, Ant and Maven are not exactly intended to solve the same goals. Since you said you understand what each provides, I won't get into the details of that, so suffice it to say that Ant lets you define the details of how to build individual components, while Maven manages the dependencies between components plus Maven lets you define a complete project build cycle from compile through test and deploy in a programmatic way.
I've used Maven on a couple projects in the past, and I just started using it on another one recently. There are plenty of articles on the net that compare Ant and Maven, so you can look at those, but from my experience, its always worthwhile to consider how you can improve a project. Dependency management and build lifecycle are two important aspects of any large project, and Maven helps in both those areas. If you already have a good build system in place using ant, and your dependencies are kept in a easy to access central location, and you don't plan on extending your build process to include any more advanced build management, then maybe you should stay with what you have.
On the other hand, if you want to use a continuous integration server like hudson or an artifact repository like nexus, then moving your project to maven can really help with build efficiency and automation. You probably would like maven in those situations because the full cycle from dependency to build to artifact can be achieved using those types of tools and you'll be able to better control your builds and releases. On my current project we have many modules and dependencies, like you mention. Migrating to maven so we could use hudson and nexus really helped because we could drop all those 3rd party jars into a nexus repository and stop having to check them into version control or email them around. Also, builds were out of hand because the CM people had a build plan as a document that they would sometimes follow, but making that part of your project (i.e., the pom.xml) defines how you are supposed to build and lets you enforce it. Maven is the glue that holds all of those things together.
In the end, its a matter of how long you expect the project to last, how good your process is now, whether you want to clean up your dependencies, whether you want to enforce your build plan, and whether you want to have the option to use continuous integration and artifact management. If you any of those things, Maven is a strong candidate.

Maven or Ivy for Managing Dependencies from Ant?

I was wondering about the best way to manage projects dependencies from ant. What are the pros and cons of the Maven Ant task and of Ivy?
Since what you're wanting to do is add dependency management to an existing Ant project, that's precisely what Ivy's designed to do. Dependency management is a big part of Maven, but far from all of it. Maven is more of a project-oriented tool that does several other things in addition to dependencies. It would be worth considering if you were planning to migrate to Maven and use additional Maven features as well, but it's a bit much if all you'd use it for is to spin off Ant.
Your type of dependencies and your expectations for how they behave will also make a difference. Pulling third-party dependencies is almost trivial in Maven, while Ivy excels in rebuilding your own dependent components. In either case, the tools won't provide decent build, versioning, and repository policies, those are still up to you and needed to get the configuration right.
Ant + Ivy == A campground, where people use the facilities as needed.
Maven == A resort, where you rely on someone else to provide services.
Maven is easier for a team lacking build/integration experience, but when the team needs to diverge from Maven standards they will find themselves reaching for groovy, gradle, and the lack of solid documentation will become frustrating.
Ant + Ivy will take longer to startup a project, but if the team has build/integration experience they can tailor the build system around they way they develop and release code.
In engineering... technology companies I always push for the campsite solution versus the resort.
It is amazing though that both Ant and Maven choose XML as their langauge to express build recipes with. The Java community is stuck on that XML...
I think this blog post covers exactly what the OP is looking for:
Why you should use the Maven Ant Tasks instead of Maven or Ivy
Ivy+Ant is far, far more flexible. Ivy does dependency management, period, and it does that extremely well, better than Maven. And with Ant you can pretty much put together any build system that you want.
Maven tries to control everything - the "lifecycle" (compile, test, package, etc.), where files should live, and so on. Have fun customizing plugins and the like if you don't like the "Maven way".
Maven is the answer to a question no one asked. Writing an Ant script is not hard, and Ivy gives you better dependency management than Maven. I am confused by some of the previous comments stating they couldn't get Ivy working. Ivy is quite a bit simpler than Maven to get up and running.
The Spring Framework uses Ivy in its build process. I think that can be seen as quite a vote of confidence for Ivy.
If your long term goal is to migrate to using Maven to manage the entire build process (which one might intend to do for new greenfield projects), then I heartily recommend using Maven pom.xml files to manage dependencies on behalf of Ant build.xml files. The end result is that both your greenfield projects and your legacy projects are then all using the same mechanism to manage dependencies. And it turns out Maven really does a better job of managing dependencies for Ant build.xml files than does Ivy.
Prior to adopting Maven as our flagship build tool, I had a developer attempt to use Ivy in combination to existing Ant build.xml files. This was most frustrating experience that very soon lead us to reject Ivy. We went ahead with an adoption of Maven. Our greenfield projects began to be built with the stock Maven approach, etc.
However, I went back to the Ant legacy projects and started using the Maven Ant task to define classpath definitions (and occasionally other Ant property definitions pulled in from the pom.xml). This turned out to be a most superlative experience. The existing Ant build.xml files need only be modified slightly to use Maven ant integration to define any classpath that were in use in the build.xml file. All dependencies required by the project became defined in an accompanying pom.xml file that gets processed by Maven via the Ant task incorporated into the build.xml files.
Maven scopes can be used to fine tune classpath definitions such that one suitable for compiling, or running unit test, or for packaging, et al, can be established. Also, pretty much any element of something defined in the pom.xml file can be referenced as an Ant property within the build.xml file.
Really with the Ant task for Maven there is no viable reason for Ivy to even exist.
Comparing Maven with ivy/ant is to compare a smartphone to telegraphy.
If you want to leverage a real enduring effect in your build infrastructure, it's better to use Maven because it anticipates and abstracts all processes and tasks every software project or other software-like project is faced with. I took part in many projects and if your projects get more complex and more diverse and more heterogeneous, you will praise even more the simplicity of a Maven project configuration. Indeed, it will become complex but not complicated compared to ivy/ant-driven projects.
The main advantage of Maven is "convention over configuration" (http://en.wikipedia.org/wiki/Convention_over_configuration) a very important paradigm. In short, this means that you don't need to know/configure things that are obvious/trivial/commonplace. Although Maven and all its plugins ship with many default-settings, you always have the option to configure your projects for your special needs. With Maven, on the one hand you can setup a project very easy and quickly; on the other hand, you can customize a growing project up to your needs with minimum effort. If you have understood the key concepts behind Maven you will leverage every project and also projects that are not typical software development projects as well.
In the past, I wrote many ant scripts and with upcoming Maven I began to hate ant. One disadvantage is that you always copy scripts and repeat yourself, develop ant tasks that don't repeat tasks that don't repeat tasks that don't repeat... And the main disadvantage is that growing ant scripts tend to get unmaintainable, especially if a dozen ant geeks want to pimp up each others ant scripts.
Many ant-enthusiasts suffer from getting overall control over trivial things like copying of artifacts and printing buildmessages. But because Maven's key concept is to hide these trivial things the legend will forever keep alive that Maven restricts customization needs. But don't worry, that’s a legend! And so you finally understand my initial statement: don't bother with trivial things that are already solved.
Maybe ivy/ant is an option for simple projects but for complex growing projects you need simplicity and conventions. Otherwise you will be overwhelmed with more and more maintaining problems. Especially if you have many dependent projects, technologies and heterogeneous product parts in a global project you don't have time and money for developing and testing ant scripts or solving dependency problems.
Another advice should be mentioned: Ant offers the integration of Maven. This integration is often used to test and play with maven in projects that are grown up with ant. Avoid this stupid approach because it generates more problems. Instead stay with ant and its pain or migrate fully to maven.
If you are in doubt about the migration costs I suggest you to use the contrary way of integrating that different worlds by the Maven-Ant-Plugin. With this standard plugin you can run every ant-script without any effort. Sure it’s a legacy solution for a while, but it gives you as much time you need to understand mega-lines of monstrous distorted uncommented ant scripts of your predecessor.
And now you will praise the next advantage of maven: You need very less documentation of your configuration, because documentation is part of every maven-plugin you want to use.
So I confess I was a Maven-Antagonist.
I know that one advantage of Ivy is that it can use different kinds of repositories. Maven is typically very rigid in the format of the repository it will use. That's all I know.
I've just spent 2 days reading through the Ivy documentation and I have to say, USE MAVEN if you have any kind of choice. Ivy is complete and utter garbage as far as I can tell. I just wasted 2 days trying to incorporate it into my build and am cutting my losses now. Why?
Ivy is a half-assed attempt at dependency management
Ivy documentation is a total joke
Ivy examples and tutorial are useless
As soon as I introduced 'configurations' (read as maven profiles), Ivy started going bezerk downloading all sorts of junk I don't need then failing. The documentation for Ivy is an utter joke. Maven documentation in comparison reads like a dream. If you want an example of how impenetrable and badly written the Ivy documentation is, take a look at the reference page for configurations. These are an essential part of any build, but in Ivy they seem to be a badly designed after thought.