Why does maven keep resources in a separate \"source folder\" from the Java sources?
From my experience, in Java the resource files are mostly treated like Java sou
1) What do you think?
I thinks, it's an excellent convention.
2) Is there a good reason why maven keeps resources separate from sources?
Yes. You follow the convention. Everyone, who has got your project code's access will know where to look for code and where for everything else. And certainly, where for test cases. And what will happen to which file when that plugin will be executed.
3) Is there any counter indication in not using src/main/resources and src/test/resources and keeping resources in src/main/java and src/test/java using maven?
There isn't a counter indication. It's matter of convention, nothing's wrong with the way you arrange your own code. In fact, if you ever created a Wicket project, you will see your HTML and your Java code stays side-by-side in Java package. But, it is just Wicket where you know the HTML is going to be by the side of Java files. But everything else goes in resources
folder.
for simplicity and easier access we keep some resources as well in the java source path. This makes it convenient for us when developing on the GUI level as velocity templates and such are close to the Controller Java Code. But you have to tell maven to include non java stuff which is in src/main/java by adding something like this to your pom file.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.1.1</version>
<configuration>
<webResources>
<resource>
<directory>src/main/java</directory>
<targetPath>WEB-INF/classes</targetPath>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
<include>**/*.htm</include>
<include>**/*.html</include>
<include>**/*.css</include>
<include>**/*.js</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<excludes>
<exclude>**/log4j.xml</exclude>
</excludes>
</resource>
</webResources>
</configuration>
</plugin>
What do you think? I think that the guys behind Maven should exercise a little "separation of concerns". The number one reason to use Maven is for dependency management, but why should a blender tell me how to peel my fruit? It makes no sense to me at all.
Is there a good reason why maven keeps resources separate from sources? No. In a java project, the duplication of package structure, not once, but three times, adds unnecessary work to the project, increasing the risk for errors and reducing the agility of the code.
I try to give an answer by myself.
What do you think?
It's a useless additional complexity. Thus is wrong: see below.
Is there a good reason why maven keeps resources separate from sources?
The only reason I might think of, is that for some platform this might be a good practice. For example in Mac OSX application, resources are packaged separately (in a different sub folder) than the binaries.
I think that "external" resources and configuration files, the ones that don't get packaged inside the final artifact (jar file) can have a good reason to be kept separate from the source files. So, when maven packages the jar, he knows that those files don't have to be included, because for example, we want them outside the jar in order to allow the user to edit those files as configuration.
But, for the things that are packaged together in the jar (like translation strings, and xml metadata, such as hibernate mappings and spring configuration) there is no good reason to have them in a separate location, unless we expect our users to change them manually after the deployment, as part of the configuration process.
Resources can be organized with the same package structure as for the classes, so if you have a class in the package x.y.z you may want to have the resources it depends on in the same package, as they represent the same "logical unit": in this case, having them in two separate folders leads to additional attention required during package refactoring and reorganization, since you want to keep the things in sync. The ClassLoader also provides the possibility to specify relative paths in the getResourceAsStream() method. So if you have the class x.y.z.MyClass, you can do getClass().getResourceAsStream("foo-bar.properties"), and the resources will be loaded from the same package "x.y.z". So it's very useful to keeps things together when they have a tight dependency.
For the external resources that needs to be kept separate also in the deployable artifact, it's a good thing to keep them separate, but in this case I don't see why maven treats the src/main/resources as a "java source folder" (maven-eclipse-plugin) since they actually must not be in the classpath but accessed through the filesystem as plain files, and especially you don't want those file to be included inside the jar during the maven build. This is the case of application icons, configuration files that you might want to place in /etc directory, and so on.
In conclusion, there's something wrong in how maven handles resources, in my opinion: if they are "external" resources, then there's no reason why maven packages them in the final artifact (jar). If they are not "external", then there is no reason to keep them in a separate "source folder".
Is there any counter indication in not using src/main/resources and src/test/resources and keeping resources in src/main/java and src/test/java using maven?
I don't know.
Most of the time I've used the default maven layout to play with resources, but in a couple of times I didn't; taking the precaution to declare the non-standard resources directory location in the pom (see resources and super-pom). It is possible to alter the maven project's directory structure specifying that in the pom:
<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>
And I didn't find particular problems with it.
I would like that maven guys think again about this convention, as having a simpler project structure helps the developer to concentrate more on the development and less on finding things around several folders in the project structure while browsing the application code.
One point that hasn't been brought up yet is that you are obviously used to seeing projects with only java sources in them. however, if you throw in some other source file types, i think the organization makes more sense, e.g.:
each sub-dir has a specific classification of files:
also (as i've noted in some comments already), i don't usually make the resources directory flat. files may be nested into a package-like structure or into other sub-directories as appropriate (to my sense of organization).
The way I distinguish between the two is that the java
folders default to allowing nothing to be built in the resulting jar, except the file types I list (e.g. *.class
, *.html
, *.properties
if you're using Wicket), whereas all the stuff in resources
will be copied in the build except the few exceptions I list.
Of course that's just my private convention, adhered to by myself.