How does the maven file structure work? - maven-2

We are planning on restructuring a complex project with many modules/pieces, what ever you wanna call it. In order to move toward a standard directory structure, we would like to adopt the maven file structure.
So the big question is: Can anybody provide a description of the maven file structure, where we don't have to dig through all the maven speak?

Please see
http://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html
src/main/java Application/Library sources
src/main/resources Application/Library resources
src/main/filters Resource filter files
src/main/assembly Assembly descriptors
src/main/config Configuration files
src/main/webapp Web application sources
src/test/java Test sources
src/test/resources Test resources
src/test/filters Test resource filter files
src/site Site
LICENSE.txt Project's license
README.txt Project's readme
BTW, we did that migration on existing projects.
It was a really long and hard task to make everything work as intended, but we are finally done and happy with it.
UPDATED
When you have many projects, you have the same structure for each project.
Now the real problem starts when you want to group them. We had a hard time reading Maven documentation and best-practices, and deciding what was the appropriate structure for us.
The basic idea would be to group related projects in a common directory (that we call a module), allowing to process the module as a whole without listing them. But if you open the module in an IDE (Eclipse in our case), the projects themselves belong to it, but are not opened as subprojects (that notion doesn't exist in Eclipse).
We ended up with a strict hierarchy, that freed us from many maven problems:
The actual coding projects (java projects) are always leaf in our directory tree. They are the only ones we open in the IDE. They are of type JAR, or WAR.
Their parents/modules are always of type POM. They have no java code.

I've been using the same approach as Jens on a number of projects both with Maven 2.2.1 and now with Maven 3.0-alpha-6: POM modules define the module structure of your project tree, JAR/WAR modules are the leaves of the tree. All modules have the same version.
Advantages:
You can
place properties or dependencies on
specific levels in the module
hierarchy and they will be inherited
to all sub-modules.
You can build
related modules simply by going to
the appropriate level in the tree and
running "mvn install" - Maven will
work out the correct build order
according.
Various Maven plugins such
as the release plugin rely on this
tree structure.
The latest Maven
Eclipse plugin can handle this
structure very well and will
represent the tree as a flat list.
There is an experimental feature in
the plugin which ensures that
so-called "shadowed" artifacts appear
only once which helps when searching
for resources in Eclipse.
Disadvantages:
Extension takes some time. For instance, if you decide that a JAR module requires sub-modules, you will need to convert the existing JAR module into a POM module and then distribute its contents to the newly created JAR sub-modules as POM modules cannot contain any code themselves.
All the POM modules will appear in Eclipse and can slow down the build somewhat. Hoever, you can close them and Eclipse will source them from the repository instead.

Related

Maven2: Possible to deploy depends on artifact classifier?

In fact I have 2 different problems, but I think they are kind of related:
I have an artifact, with an assembly descriptor set which will build an extra JAR (with extra classifier). By default, Maven2/3 will deploy the assembly generated together with the main artifact to remove Maven repository. Is there any way that I can deploy only the main artifact but not the assembly?
I have an artifact, in which I have jar plugin generate another artifact with different classifier (more specific, an EJB artifact, and I generate an client JAR). I want to deploy only the client JAR to Maven repo coz I think the main EJB artifact is not really going to be shared by other project. Is it possible to do so?
Thanks a lot
editied to provide more info:
The reason for avoiding deploy the EJB, is because the EJB main artifact is not going to be depended by other project except the containing project. The containing project will build a EAR (which contains the EJB), and normally we only need that build locally (by mvn package). However, the EJB client is something that we will deploy to our repo to let other project share when they need to communicate with our application.
Honestly it doesn't harm to deploy the EJB too, but I just want to see if I can save unnecessary waste of disk space on our repository.
Similarly, for deploying assembly, it is because the project is something we want to deploy to let other project to depends on. However, when building that project, we also have a separate assembly created on the same time (for example, an all-in-one executable jar) which we only need that built locally, and it is not something that other projects will depends on.
Turn off the 'attach' option to the assembly plugin. Then it won't be officially an artifact and it won't deploy; it will just lurk in the target directory, sulking that you don't love it as much as it's elder sibling and plot revenge.
Based on your first question i would like to know why do you create the supplemental assembly which is usually deployed as well as the main artifact. If you wan't to prevent you can put the creation of the assembly into a profile but this means you will not generate the supplemental artifact in your usual build only by activating the profile.

need maven plugin configuration for building aggregate source jar

I've been fighting with this for a while and reading a lot of docs pages and other questions but still can't get it to work.
In my ORMLite project, I have a ormlite-core project which has core functionality and then a -jdbc and -android projects (with more planned). Each of these sub-projects include the core functionality but add per-architecture implementations. I want to release a single set of jars for both the -jdbc and -android versions -- i.e. I want to copy the -core javadocs and sources into the resulting jars.
For the javadocs, it was cake with the includeDependencySources config entry set to true. However, I've been fighting for a while now on how to get the source jars released by the -android package to include the -core sources. I've tried the maven-dependency-plugin to copy and unpack the dependency sources to target/sources but I see no easy way to get them to be included in the source jar -- with the appropriate paths. I've gone over the maven-source-plugin and maven-assembly-plugin docs but I'm still in the dark.
If someone has figured out the magic maven fu to get this done, can they please share the appropriate working pom.xml examples? Thanks much.
I've reviewed the following similar questions among others. I've also looked at the Sonatype Maven manual and read a bunch web pages posing similar questions.
Delivering a single jar with a Maven project
Maven - 'all' or 'parent' project for aggregation?
While not an answer to the question, a possible reason why a parameter like <includeDependencySources> is not present for maven source plugin is because, while javadocs can be generated from a jar containing classes, the sources cannot be. The plugin cannot assume that the sources of the dependencies are available to it since they do not get installed by default.
I guess the best answer to this question at this time is "you can't get there from here". This requires extensions to the maven-source-plugin.
I ended up determining that combining these sub-projects into the same jar was not a good idea and now I release 3 separate jars.

maven multi-module assembly

I have a multi-module maven project, and I'm trying to create an assembly for the project. The assembly should be a zip file, including all of the jars from the dependent projects as well as all of the resources from those projects (this is for legacy support reasons - I know this isn't a good practice, but in this case, we really can't do much about it).
I have an assembly that builds a zip and includes the contents of the build output directory (which will get the resources). If I run that from the parent pom, it doesn't actually build a zip (presumably because the parent project is of type pom, not a jar). If I run an assembly from one of the individual projects, it does include the jars and all the dependencies (I specified including the dependencies). It includes the output directory for that project, but not the child projects.
Do I need to do something like run an assembly from the parent that iterates over the child projects and runs their assemblies (the assemblies for each of the child projects would be the same though - it would include the jar, the dependencies and the output directory)? I'm not even sure this is possible ... any guidance would be appreciated.
I suggest to check the whole Section 8. Maven Assemblies of the Maven: The Complete Reference book and in particular the following subsection 8.2.4. Assembling Assemblies via Assembly Dependencies. It describes a very similar requirement and a setup.

How to create master install folder with maven

Im trying to setup maven to assemble all my build artifacts into a central distribution folder. to help with explainations, ive uploaded a sample project here
This is a simple multi-module project with 2 j2ee components, each of those has a war, and ear sub-project. If you comment out the assembly plugin in the top level pom, everything will build fine.
There is also an outputFolder which is how i want things to look when the assembling is all done. Also in the outputFolder are misc jar files that will come from other sub-projects that just build a single jar (currently we have about 20 of these application jars). Now since all the j2ee projects have the same directory structure and resulting distribution formats, I wanted to create a common assembly descriptor to be re-used across all of our j2ee components (currently theres about 15).
What I have so far does not work - in that it wont find the binary artifacts from any of the subprojects. Ive tried using moduleSet and dependencySet sections in the assembly descriptor, but those dont seem to work either, i alwasy get something like: The following patterns were never triggered in this artifact inclusion filter: 'myCompany:j2ee_A_ear:ear'
Or if I try to put an assembly descriptor in the top level project, it causes wierd dependency errors when packaging my ear files.
Ive tried to use the dependency-copy plugin, but that seems to cause more problems than it solves. Also others have said, the dependency plugin is the way to go for this. Ive tried creating packaging only projects -- a sibling of the j2ee_A and j2ee_B projects in my example, but it cant seem to find any of the modules or dependencies
So im looking for an assembly descriptor (or descriptor s) that will be:
a) reusable across any number of j2ee sub-projects
b) also support single jar files
c) copy everything to a single folder
Ideas, suggestions and examples are welcome.

Setting up a standard directory layout using Maven

I'm new to Maven and have skimmed over the documentation as I am following the Hibernate tutorial at http://docs.jboss.org/hibernate/stable/core/reference/en/html_single/#tutorial-firstapp-mvn.
I have installed Maven and successfully setup a web-app but this does not contain all of the standard directories mentioned in the tutorial. Am I going mad?
When building my Maven project I am using the maven-archetype-webapp. This gives me the arh-webapp\src\main\resources and arh-webapp\src\main\webapp directories but I'm missing quite a few directories mentioned on the link http://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html.
Surely I don't have to manually add these? If not then the Hibernate documentation does not mention what archetype to use in order to achieve the directory structure used in their tutorial. Please can someone enlighten me.
What archetype do I need to use in order to have the above directory plus the src/main/java directory? If there is no such archetype then can easily append these using Maven? and how?
Surely you'll have to manually add these.
Just create those directories that according to the Maven convention are missing. Remember, a Maven Archetype is just a starting point to save you time configuring your workspace. After encountering many problems in some Archetypes myself I've been accustomed to just use a basic-web-app-archetype and then customize it myself, as a beginner with Maven you'll be better off doing that, and will learn a lot.
Regards.
Not all the directories mentioned are required for your standard web application. In fact, the reason behind the presence of the src/main/java, src/main/resources and the src/main/webapp directories is due to the archetype that you've used.
IMHO, the book titled "Better Builds with Maven" will serve you better; the Sonatype books on Maven might also help. The complete Maven documentation is also available as a PDF file, for future reference.
But just in case, you need some clarity on the terms used, here's some:
Archetype: A pattern for projects. Simple web applications (with no dependencies on other frameworks/libraries) have their own archetypes, so do applications using Spring, Hibernate, Seam, etc. Some archetypes will result in creation of different directories, as they are coded that way. You might be able to change the directory structures in most cases, although I cannot vouch for every archetype. For instance, it is quite possible to place your sources in 'src' instead of 'src/main/java', although this requires additional configuration in the POM.
Lifecycles, Phases and Goals: A Maven build lifecycle is a series of phases, with each phase executing a set of goals. Maven can be commanded to execute a build phase, which results in execution of all phases until and including the specified phase.
Maven plugins: Maven plugins contain one or more goals. Goals need not be bound to phases, but usually you would bind them to particular phases. Plugins are the basis for everything operational in Maven; you're using plugins even though you are just compiling the application (the Maven compiler plugin is a core plugin that is present in the Maven distribution).
I hope the above helps, but I would suggest that the reference books be followed.