63

I've noticed that a lot of projects have the following structure:

  • Project-A
    • bin
    • lib
    • src
      • main
        • java
          • RootLevelPackageClass.java

I currently use the following convention (as my projects are 100% java):

  • Project-A
    • bin
    • lib
    • src
      • RootLevelPackageClass.java

I'm not currently using Maven but am wondering if this is a Maven convention or not or if there is another reason. Can someone explain why the first version is so popular these days and if I should adopt this new convention or not?

Vertexwahn
  • 7,709
  • 6
  • 64
  • 90
Chris
  • 4,450
  • 3
  • 38
  • 49
  • related question - http://stackoverflow.com/questions/22914927/creating-a-src-main-java-folder-structur-in-eclipse-witout-maven – Erran Morad Oct 05 '14 at 00:31

5 Answers5

66

Main benefit is in having the test directory as subdirectory of src with the same directory structure as the one in main:

  • Project-A
    • bin
    • lib
    • src
      • main
        • java
          • RootLevelPackageClass.java
        • resources
      • test
        • java
          • TestRootLevelPackageClass.java
        • resources

All package private methods of RootLevelPackageClass will be visible, i.e. testable from TestRootLevelPackageClass. Since the testing code is also source its place should be under src directory.

Gerold Broser
  • 14,080
  • 5
  • 48
  • 107
Boris Pavlović
  • 63,078
  • 28
  • 122
  • 148
  • 3
    Usually the resources directory is also split into `src/main/resources` and `src/test/resources`. – Joachim Sauer Jun 09 '10 at 12:04
  • I use a convention like the OP's, and I'm able to put test code in the same package as source code just fine (project/src/com... and project/test/com...). I can see why it would be nice to split up resources, but I have to say I've never needed test-specific resources. – orbfish Dec 23 '13 at 21:31
  • 2
    Also, if your project uses more than one language, they sit well within the src/main/ and src/test structure. You could have src/main/groovy, src/main/kotlin, src/main/jython etc. The JVM now has a whole host of alternative languages aside from Java. – Matt Moran Sep 30 '18 at 10:32
28

Yes, this is the Maven convention.

Even if your project is 100% Java (as is typical with Maven btw), you often have resource files (which go to src/main/resources according to the Maven convention), or web app stuff, or ... all these fit into the Maven system easily.

If you are happy with your current build system (whatever it is), there is no reason to switch to Maven. Otherwise, or if starting a new project, you could evaluate your options, including Maven.

Péter Török
  • 114,404
  • 31
  • 268
  • 329
16

Others have already told you it's a Maven convention, I'm going to answer your question instead:

Absolutely none. Certainly it's beneficial to separate pieces of code to separate root folders, but usually you could achieve the same with

  • [root]
    • src
      • com.org.net
        • Your.class
    • test
      • com.org.net
        • YourTest.class
    • lib
    • bin
    • resources

instead. In fact here's a big thing Maven does that's actually hugely wrong: It wants to add binary content to source code repository which is meant for textual content only! All binary content should be managed outside the source code repository, that includes images in web applications and whatnot.

But OK, lets assume that you've decided to live in the somewhat smelly Maven ecosystem; then you should of course follow the Maven conventions as strictly as possible.

Esko
  • 29,022
  • 11
  • 55
  • 82
  • Hi, Thanks for your comments. The structure you show in your answer is similar to the structure I use in my existing projects and the normal convention up until Maven it seems. I'd be interested in your further views of Maven and what you would recommend for multi-project builds as an alternative and why (gradle/ant/ivy ...)? – Chris Jun 09 '10 at 13:55
  • 10
    Source code repos, despite the name, are meant for binary as well as textual content. Maybe your projects have no dependencies on binary assets, but all my recent (web) projects have a visual (or aural), and they won't function without them. They are integral to the project. It's very beneficial to have them versioned along with the "code". Not including them would just make everyone's job harder. – ndp Jun 09 '10 at 14:14
  • @ndp: Most versioning systems are made for textual content and very few support *proper* versioning of binary content. I do acknowledge they're integral to the project but that doesn't mean they necessarily belong to the same place as the actual source code. – Esko Jun 09 '10 at 18:22
  • 4
    .. What do you mean "proper" versioning of binary content? Every system I've used in the last 20 years has allowed me to check in binary files. Sure, CVS was a little finicky, but these days git is perfect-- in fact, git treats all content as binary blobs (at least at the storage layer). What am I/we missing? – ndp Jun 10 '10 at 04:01
  • 1
    I agree with @ndp - Just because binary files are not easy to diff/version on a line-by-line basis does not mean they should be excluded from version control. It seems silly to 'throw the baby out with the bathwater'. – JW. Sep 02 '14 at 17:02
  • 2
    Hm, yet another of my years old things which I don't agree with even myself at this point :) Answers grow old, I suppose. – Esko Sep 03 '14 at 12:29
  • @Borat Well that would require me a whole lot more effort to actually state my full opinion on the matter at this point which would steer the answer away from what was originally asked. I understand the dilemma though, should we have an outdated answer - which isn't even that highly upvoted - to an old question or an updated answer to an old question that will never get much of an audience since it's last on the answers and people have learned to by extremely impatient and won't scroll all the way down anymore. I do admit being a bit lazy on updating this too, no question about that. – Esko Oct 05 '14 at 08:03
11

Its a Maven convention.

Maven is based on Convention over configuration paradigm. Thats means: if you dont follow this convention you must configure where the sources are located. Thats the main benefit IMHO.

sourcerebels
  • 5,140
  • 1
  • 32
  • 52
  • 4
    They *say* Maven is based on convention over configuration, but why are the `pom.xml`:s a billion lines long and what is all this complex XML in general...? :) – Esko Jun 09 '10 at 13:19
  • 6
    You are right. But for sure if you dont use /src/main/java as your source folder, your pom.xml will have a billion and one lines :-) – sourcerebels Jun 09 '10 at 14:39
  • 1
    That's true if you're using maven - but Eclipse etc. can read and create a project with the user's convention just fine. – orbfish Dec 23 '13 at 21:29
  • 2
    @Esko I think you got that wrong...then. It's _convention over configuration_. It's not _**no** configuration over configuration_. I consider the declarative, instead of imperative, nature of POMs a pure genious concept. XML is verbose, agreed. But with that the content is easily understandable and comprehensible. We started to refrain from using identifiers like `a`, `a1`, `a2`, `x`, `y`, `z` a long time ago, didn't we? – Gerold Broser May 04 '16 at 00:03
5

Yes, this is a maven convention, but even if you're not using maven, there are benefits to using it:

  1. people new to the project will have an easier time coming up to speed, since it's a "standard"
  2. this convention is flexible and has a place for non-Java code and other things you don't have at this point. This is one reason it's popular and you may find it evolves better than a scheme you come up with on your own
  3. if you want to move to maven at some point it will be easy

Although I wouldn't argue you should switch just to switch, when starting a new project there's really no reason to not use it-- unless you disagree philosophically with how it breaks the code up.

ndp
  • 21,546
  • 5
  • 36
  • 52