49

Besides src/main/java folder, we have one folder that contains some generated java sources that are required for the main sources. Code generation is invoked manually, when needed. Generated source is checked into the source repo. Everything will be built and packed together.

What would be the best location for generated java sources that are going to be compiled together with main sources? Should it be:

  • /src/generated/java (following the same naming logic for src/testInt/java for integration tests)
  • /generated-src/main/java (in collision with "The src directory contains all of the source material for building the project")
  • /src/main/generated-java (well... generated-java is not a type)
  • ...?

The first option seems like the most appropriate one for this case. What do you think? Is there anything in Maven docs that describes this situation (that I have overlooked)? Do you know any repo with similar structure?

Thank you.

Answer

As suggested by @Absurd-Mind, direction we are thinking about is to split the source into the submodules (which works nice in gradle). So, the generated source and some other related source will go into its own submodule (they will produce the separate artifact) and the rest will go in other submodule, that uses this one. Thank you.

igr
  • 10,199
  • 13
  • 65
  • 111
  • 1
    I normally use `target` folder to store the generated java sources. For your case, it will be something like `/target/main/java` – Balwinder Singh Apr 07 '14 at 12:51
  • When I use the target folder, my source files don't see the generated classes. I suppose I could put them in a sub-project and add a dependency, but I don't know of a way to put it all in the same module this way. – MiguelMunoz Dec 19 '19 at 22:50

5 Answers5

52

I think the location depends on how the source is generated and handled.

  1. The source code is generated automatically during the build process: Then i would use target/main/java/, target/test/java/ and so on. This code is not checked in into CVS since you can rebuild it fairly easy. In case you clean your project the target directory will be removed and the source will be rebuild.

  2. The source code is generated manually by an external tool or similar: I would use generated/src/main/java/, generated/src/test/java/, generated/src/main/resources/ and so on. This code should be checked in. A benefit is, as soon you see that the top-level directory name is generated you know that all files/directories below are also generated. Also you have the standard maven directory structure under the top-level directory. Another point is that clean-up is easy, just delete generated and recreate it, without looking through many other directories (like in your example: src/main/generated-java and src/test/generated-java).

EDIT: Another nice solution would be to create a maven project which only contains the generated source like myproject-generated-1.0.3.jar. This project would be a dependency in your real application. Then you would just put your generated source int src/main/java.

Absurd-Mind
  • 7,884
  • 5
  • 35
  • 47
  • 1
    @игор I'm a bit curious, which path/solution do you prefer? – Absurd-Mind Apr 08 '14 at 10:17
  • 4
    Then what are the folders target/generated-sources and target/generated-test-sources for. Those folders are empty though. I am using maven 3.2.5. These are created when you build. – RuntimeException Apr 09 '15 at 16:08
  • 1
    Source code generated by annotation processors are usually (See fx Mapstruct or https://maven.apache.org/plugins/maven-compiler-plugin/compile-mojo.html#generatedSourcesDirectory) placed in *target/generated-sources/annotations* – Hervian May 18 '17 at 19:26
  • 1
    @Hervian I would suggest not to commit anything from the target directory to your source control – Absurd-Mind May 26 '17 at 17:38
  • @Absurd-Mind Ah, yes you're right, I was too hasty, did not notice that the question was about where to put generated source that will be checked in. Good question - I like your "EDIT"-answer. – Hervian May 26 '17 at 22:27
  • I think the official documentation tells everything about default behaviour and extension/customisation possibilities: https://maven.apache.org/plugins/maven-clean-plugin/ – Michael Sebastian Oct 24 '19 at 08:56
  • You left out the case where the generated code is built by your standard build tool, but isn't built with the rest of the project. For example, I have a maven project that requires me to type "mvn jooq-codegen:generate" to generate the source, then "mvn clean install" to build the project with it. (I put the generated code in src/gen/java." Putting it in the target folder doesn't work, because my source java files can't see it there. – MiguelMunoz Dec 19 '19 at 22:56
  • When putting the generated sources in the `target` folder, are they one the classpath of the project in IntelliJ IEAD? In my project it doesn't seem to be the case. – Harold L. Brown Apr 29 '21 at 07:56
6

As much as i know there is no standard folder structure for generated sources. In my projects, i prefer src/gen/java kind of notation.

bhdrkn
  • 6,244
  • 5
  • 35
  • 42
2

I totally agree with the accepted answer. I just want to offer a slightly different suggestion for naming the directory that contains code generated by third-party tools:

src-gen/main/java

Background: In the Eclipse/Maven Tycho world (where code/resource generation often plays a large role) there is the src-gen directory for generated code, which has been established as some kind of standard convention. (the default project layout is a bit different compared to Maven, as all source files are directly in src and src-gen).

In a Maven project that could be translated for example to src-gen/main/java, src-gen/main/resources, src-gen/test/java, src-gen/test/resources. I like that more than moving everything into a "generated" directory, because

  • Sources in src/main/javaand src-gen/main/java are on the same depth in the directory tree
  • It's more clear that src-gen contains generated sources/resources that contribute to the build. On the other hand a folder just named "generated" dosn't tell you much about its content. It could contain anything, like generated documentation or generated test data or it could be just a temporary folder.
  • All the mentioned advantages of generated/src/main/java still apply (e.g. easy cleanup)
  • After a quick google search it looks like there are already projects on Github that use this pattern

Some thoughts/opinions about the other suggestions from the question:

  • Instead of /src/main/generated-java I would probably rather go with something like /src/main/java-gen which, when sorting directories alphabetically, keeps generated and regular code next to each other (<lang>-gen is also another pattern already used in Eclipse projects)
  • In my opinion gen fits in with the brief official names like src, it etc. more than generated. I've already seen src/gen/java a few times in the wild and have the feeling it is a more common than /src/generated/java. On the other hand some Maven plugins use the quite verbose target/generated-sources/<lang> directory, so generated-sources/main/java could also be an option if your not into short names...

Ultimately I think the naming doesn't matter that much and it is up to your preference since none of this is "official" convention.

kapex
  • 28,903
  • 6
  • 107
  • 121
1

NetBeans adopted <project>/target/generated-sources/<tool> as the location for generated code. As a result you would see an extra leaf appear in your project tree named as Generated Sources (<tool>), and source code will be navigable and not show up with compiler errors in the markup.

So if you commit your code, it will not be under the /target directory, and you will have to setup your maven project for the additional Source Code locations. Otherwise, I will suggest to keep with that adopted standard and put things under <project>/target/generated-sources/<tool>.

YoYo
  • 9,157
  • 8
  • 57
  • 74
-5

In Maven project source file store inside src/main/java , src/main/resources and test class store inside src/test/java.
In Maven generated code (Compile code) stored into target/ folder.
When you build your Maven project, all generated code to be updated in target folder.

Ondra Žižka
  • 43,948
  • 41
  • 217
  • 277
sus007
  • 297
  • 3
  • 9