ChatGPT解决这个技术问题 Extra ChatGPT

Maven compile with multiple src directories

Is there a way to compile multiple java source directories in a single maven project?


O
Ondra Žižka

You can add a new source directory with build-helper:

<build>
    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>build-helper-maven-plugin</artifactId>
            <version>3.2.0</version>
            <executions>
                <execution>
                    <phase>generate-sources</phase>
                    <goals>
                        <goal>add-source</goal>
                    </goals>
                    <configuration>
                        <sources>
                            <source>src/main/generated</source>
                        </sources>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

The only issue with this approach is that the final artifact includes the java source files as well(.java files). Is there a way to exclude the source files and include only have the .class files?
just a note for others (like me), plugin element is in /project/build/plugins and NOT in /project/build/pluginManagement/plugins
If you are using eclipse, you might want to install m2e connector for build-helper-maven-plugin from eclipse marketplace to remove the error in pom.xml
If you receive a warning like 'build.plugins.plugin.version' for org.codehaus.mojo:build-helper-maven-plugin is missing you need to add within <plugin> the tag <version>1.12</version>
So the best way to do this, in 2017, was to create an XML pasta. Does nobody see a problem with that?
c
comeGetSome

I naively do it this way :

<build>
  <finalName>osmwse</finalName>
  <sourceDirectory>src/main/java, src/interfaces, src/services</sourceDirectory>
</build>

Worked for me to :) Eclipse doesn't seem to like it though. It seems to think "src/main/java, src/interfaces" is a single src, and therefore flags it as (missing).
For me, that caused Maven 3.2.2 not to find any sources.
I got similar experience as @Joel, Code compiled but had problems with things like recognizing a "main" method.
For maven 3.8.1 does not work. Also, in the documentation for this version of the maven, nowhere is it written that such a content is possible in the tag . --- maven-compiler-plugin:3.8.1:compile (default-compile) @ xxx-xxx --- No sources to compile
Worked in netbeans and did not break intelliJ, or Eclipse for me.
B
Betlista

This worked for me

<build>
    <sourceDirectory>.</sourceDirectory>
    <plugins>
        <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
        <includes>
            <include>src/main/java/**/*.java</include>
            <include>src/main2/java/**/*.java</include>
        </includes>
        </configuration>
        </plugin>
    </plugins>
</build>

Not such a good idea IMHO, since several plugins assume the sourceDirectory - and possibly additional sources - as the roots of source files. In your solution, the maven-compiler-plugin is the only plugin aware of these actual roots.
@Laurent You're right about that. This was a good idea a couple years ago but there are much better options now. build-helper listed above is my preferred options.
This doesn't add it to the project model, so it won't work correctly in IDEs.
+1 @sal it worked like a charm with a WAR project dependency.
This cannot work if i want to include an external source directory (containing Java class that i'm using in my maven project). What if my external source is located outside my Eclipse's workspace? What can i do?
c
cb4

To make it work in intelliJ, you can also add generatedSourcesDirectory to the compiler plugin this way:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.8.1</version>
    <configuration>
        <generatedSourcesDirectory>src/main/generated</generatedSourcesDirectory>
    </configuration>
</plugin>

Would like to add that this worked in Eclipse as well to add the generated sources as a source location in the project configuration.
This path seems to be for sources generated by annotation processors though. Even if it works, it is possible that this path is handled differently by some plugins. For example I would expect this directory could be deleted when 'clean' is run.
where did you put it ?
IntelliJ 2021.2.3 This still works and it was the only solution I found that did. I agree with @kapex that it is intended for annotations, but I spent a day trying to find the "right way" to do it and failed.
To make the build less brittle and more in line with maven standards:<generatedSourcesDirectory>${project.build.directory}/generated-sources/main/java</generatedSourcesDirectory>
G
Gavin S. Yancey

This also works with maven by defining the resources tag. You can name your src folder names whatever you like.

    <resources>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.java</include>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
        </resource>

        <resource>
            <directory>src/main/resources</directory>
            <includes>
                <include>**/*.java</include>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
        </resource>

        <resource>
            <directory>src/main/generated</directory>
            <includes>
                <include>**/*.java</include>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
        </resource>
    </resources>

maven.apache.org/pom.html#Resources --> Resources are not (usually) code. They are not compiled
S
SwissCodeMen

This worked for with maven 3.5.4 and now Intellij Idea see this code as source:

<plugin>
     <groupId>org.apache.maven.plugins</groupId>
     <artifactId>maven-compiler-plugin</artifactId>
     <version>3.3</version>
     <configuration>
         <generatedSourcesDirectory>src/main/generated</generatedSourcesDirectory>                    
     </configuration>
</plugin>

S
SwissCodeMen

While the answer from evokk is basically correct, it is missing test classes. You must add test classes with goal add-test-source:

<execution>
    <phase>generate-sources</phase>
    <goals>
        <goal>add-test-source</goal>
    </goals>
    <configuration>
       <sources>
            <source>target/generated/some-test-classes</source>
        </sources>
    </configuration>
</execution>

a
arntg

Used the build-helper-maven-plugin from the post - and update src/main/generated. And mvn clean compile works on my ../common/src/main/java, or on ../common, so kept the latter. Then yes, confirming that IntelliJ IDEA (ver 10.5.2) level of the compilation failed as David Phillips mentioned. The issue was that IDEA did not add another source root to the project. Adding it manually solved the issue. It's not nice as editing anything in the project should come from maven and not from direct editing of IDEA's project options. Yet I will be able to live with it until they support build-helper-maven-plugin directly such that it will auto add the sources.

Then needed another workaround to make this work though. Since each time IDEA re-imported maven settings after a pom change me newly added source was kept on module, yet it lost it's Source Folders selections and was useless. So for IDEA - need to set these once:

Select - Project Settings / Maven / Importing / keep source and test folders on reimport.

Add - Project Structure / Project Settings / Modules / {Module} / Sources / Add Content Root.

Now keeping those folders on import is not the best practice in the world either, ..., but giving it a try.


Neither option works with IntelliJ Idea 9.0.4 which is what I use. Haven't tried the build-helper options with the recent Eclipse, but it didn't work with 3.4 and the m2 plugin when I tried it. Maven doesn't like multiple source trees or multiple artifacts built from the same project any any attempt to get around this limitation is usually an awful hack.
Have been on IntelliJ for many years now. And never switched to eclipse, so can't talk for it, then hearing it's generally very good too. For IntelliJ Upgrading a personal license every other year is at $100/year. The new major versions are usually out every year at January. Then at the last 2-3 month of previous year they are allowing you to buy the previous version and get the upgrade to the upcoming one free. This is on right now so it's the "safe" time to buy 10 and get 11. Also, if you don't need JSP and other enterprise features, use the free community edition.
G
Gerold Broser

This can be done in two steps:

For each source directory you should create own module.

In all modules you should specify the same build directory: ${build.directory}

If you work with started Jetty (jetty:run), then recompilation of any class in any module (with Maven, IDEA or Eclipse) will lead to Jetty's restart. The same behavior you'll get for modified resources.


P
Prabhu

In the configuration, you can use <compileSourceRoots>.

oal:          org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-cli)
[DEBUG] Style:         Regular
[DEBUG] Configuration: <?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <basedir default-value="${basedir}"/>
  <buildDirectory default-value="${project.build.directory}"/>
  <compilePath default-value="${project.compileClasspathElements}"/>
  <compileSourceRoots default-value="${project.compileSourceRoots}"/>
  <compilerId default-value="javac">${maven.compiler.compilerId}</compilerId>
  <compilerReuseStrategy default-value="${reuseCreated}">${maven.compiler.compilerReuseStrategy}</compilerReuseStrategy>
  <compilerVersion>${maven.compiler.compilerVersion}</compilerVersion>
  <debug default-value="true">${maven.compiler.debug}</debug>
  <debuglevel>${maven.compiler.debuglevel}</debuglevel>
  <encoding default-value="${project.build.sourceEncoding}">${encoding}</encoding>
  <executable>${maven.compiler.executable}</executable>
  <failOnError default-value="true">${maven.compiler.failOnError}</failOnError>
  <failOnWarning default-value="false">${maven.compiler.failOnWarning}</failOnWarning>
  <forceJavacCompilerUse default-value="false">${maven.compiler.forceJavacCompilerUse}</forceJavacCompilerUse>
  <fork default-value="false">${maven.compiler.fork}</fork>
  <generatedSourcesDirectory default-value="${project.build.directory}/generated-sources/annotations"/>
  <maxmem>${maven.compiler.maxmem}</maxmem>
  <meminitial>${maven.compiler.meminitial}</meminitial>
  <mojoExecution default-value="${mojoExecution}"/>
  <optimize default-value="false">${maven.compiler.optimize}</optimize>
  <outputDirectory default-value="${project.build.outputDirectory}"/>
  <parameters default-value="false">${maven.compiler.parameters}</parameters>
  <project default-value="${project}"/>
  <projectArtifact default-value="${project.artifact}"/>
  <release>${maven.compiler.release}</release>
  <session default-value="${session}"/>
  <showDeprecation default-value="false">${maven.compiler.showDeprecation}</showDeprecation>
  <showWarnings default-value="false">${maven.compiler.showWarnings}</showWarnings>
  <skipMain>${maven.main.skip}</skipMain>
  <skipMultiThreadWarning default-value="false">${maven.compiler.skipMultiThreadWarning}</skipMultiThreadWarning>
  <source default-value="1.6">${maven.compiler.source}</source>
  <staleMillis default-value="0">${lastModGranularityMs}</staleMillis>
  <target default-value="1.6">${maven.compiler.target}</target>
  <useIncrementalCompilation default-value="true">${maven.compiler.useIncrementalCompilation}</useIncrementalCompilation>
  <verbose default-value="false">${maven.compiler.verbose}</verbose>
</configuration>

these are all the configurations available for 3.8.1 version of compiler plugin. Different versions have different configurations which you can find by running your code with -X after the general mvn command. Like

mvn clean install -X
mvn compiler:compile -X

and search with id or goal or plugin name This may help with other plugins too. Eclipse, intelliJ may not show all configurations as suggestions.