maven can't add files in generated-sources for compilation phase - maven

I use Apache Thrift to generate code in target/generated-sources.
The Thrift compiler produces a directory named gen-java which contains all the Java code. When I execute mvn compile, the code is generated correctly in target/generated-source/gen-java, but in compilation phase, it complains can't find the classes which defined in gen-java.
In my understanding, Maven 2 automatically adds generated sources, is that right?
And what if my testing code also depends on the generated-sources, do I have to manually specified the compiler includes?

In my understanding, maven 2 automatically add generated sources, is that right?
Nothing automatic, plugins generating source code typically handle that by adding their output directory (something like target/generated-sources/<tool> by convention) as source directory to the POM so that it will be included later during the compile phase.
Some less well implemented plugins don't do that for you and you have to add the directory yourself, for example using the Build Helper Maven Plugin.
And since you didn't provide any POM snippet, any link, I can't say anything more.
And what if my testing code also depends on the generated-sources, do I have to manually specified the compiler includes?
As I said, generated sources are usually added as source directory and compiled and are thus available on the test classpath without you having to do anything.

Generated sources are not compiled or packaged automatically. Some IDEs (i.e. IntelliJ) will however show them as source folders.
To make generated sources visible to maven add a add-source-step to the build/plugins node of your pom.xml:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>${project.build.directory}/generated-sources/gen-java</source><!-- adjust folder name to your needs -->
</sources>
</configuration>
</execution>
</executions>
</plugin>

Related

Maven : exclude target/generated-sources from compilation

This question, just to be sure my interpretation is correct :
I'm using Mojohaus jaxb2-maven-plugin to generate java classes from .xsd files, and by default it puts them in target/generated-sources
Now, I want to get track of these classes in source control (target is of course excluded), and I may one day slightly customize one with an annotation or a line of code, and I may even change my class generation plugin, so what do is I copy these classes and packages in src/main/java
This upsets Maven when I try to compile because he considers "target/generated-sources" as a source directory and he finds all clases twice. For what I understand, I can exclude classes inside a source directory, but I can't remove a source directory from Maven build, am I right ?
So the only solution would be to configure my jaxb2 plugin to generate the classes elsewhere, right ?
UPDATE :
Ok, this doesn't work as I thought, if I change the outputDirectory of my jaxb plugin, it's still included as a source directory by Maven, and I have no clue why.
<configuration>
<outputDirectory>${project.build.directory}/tatata/jaxb</outputDirectory>
</configuration>
UPDATE 2 : The explanation is the plugin is adding the outputDirectory as a maven source directory during the generate-sources phase of the build, and it's not optionnal or customizable.
First things first, do not add generation code to source control. Do not modify it manually. You will get into trouble. Believe me, I've seen it too many times. A new version of the schema and you're lost.
Ok, now to your question.
With maven-jaxb2-plugin you could turn off adding generation directory as a compile source root with:
<configuration>
<addCompileSourceRoot>false</addCompileSourceRoot>
</configuration>
Disclaimer: I'm the author of maven-jaxb2-plugin.
The answer from Lexicore is an interesting lead but my question was about the plugin I'm currently using, not how to do it with an other plugin.
So here is the workaround for the Mojohaus plugin : you can just skip the generate-sources by default (no need to do this task at every build when your model changes once in a week, then once in a year), and trigger it only when needed using a dedicated maven profile : How to skip generate-sources in Maven
you can always specify the target directory(generateDirectory) in pom config file as below. Hope it helps
`
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.12.3</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<configuration>
<schemaLanguage>WSDL</schemaLanguage>
<generateDirectory>${basedir}/src/main/java</generateDirectory>
<generatePackage>com.myproj.proxy</generatePackage>
<schemas>
<schema>
<!-- <url>${project.basedir}/src/main/resources/wsdl/test.wsdl</url> -->
<fileset>
<!-- Defaults to schemaDirectory. -->
<directory>${basedir}/src/main/resources/wsdl</directory>
<!-- Defaults to schemaIncludes. -->
<includes>
<include>*.wsdl</include>
</includes>
</fileset>
</schema>
</schemas>
</configuration>
</plugin>
`

Maven Dependency Plugin: Copy only test dependencies

I have already assembled all runtime dependencies for my project in one output directory using the Maven Dependency plugin. Now I would like to assemble all additional test dependencies in a separate directory.
But when I include scope test and exclude either compile or runtime scope, it still always copies all compile dependencies as well.
Is there a way to copy only the additional test dependencies?
My current configuration:
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-test-libs</id>
<phase>generate-test-resources</phase>
<goals><goal>copy-dependencies</goal></goals>
<configuration>
<outputDirectory>${project.build.directory}/test-libs</outputDirectory>
<includeScope>test</includeScope>
<excludeScope>compile</excludeScope>
<excludeTransitive>true</excludeTransitive>
</configuration>
</execution>
</executions>
</plugin>
The includeScope parameter, by default, is empty which means it includes all scopes and the excludeScope is, by default, empty.
When you specify <includeScope>test</includeScope>, it means that you want to include all dependencies (of all scopes). This setting seems to be different that the default empty value and I guess the maven-dependency-plugin is confused when both <excludeScope> and <includeScope> are used: it includes everything and does not exclude the specified scopes.
You need to remove includeScope and let excludeScope do it's job.

How to generate a resource to be included in Jar file with maven?

During my build I need to some files to be generated by an external tool. For my minimal compilable example I reduced my "external tool" to the following script:
mkdir -p target/generated-resources
echo "hello world" > target/generated-resources/myResource.txt
Now I want to execute my external tool during build and the generated resource should be included in the war file. I could not find any documention on how that should be done, so it was just a guess that I need to write my generated resource to target/generated-resources. So maybe that is a problem?
I created a pom.xml file with the following build configuration:
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<phase>generate-resources</phase>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
<configuration>
<executable>./createResource.sh</executable>
</configuration>
</plugin>
</plugins>
</build>
If I run mvn package my createResource.sh script gets executed successfully and the myResource.txt file is created. However the myResource.txt file is not included in the resulting .jar file.
I noticed that it works if I add
<resources>
<resource>
<directory>target/generated-resources</directory>
</resource>
</resources>
to my build config, but I fear that this may cause problems if other plugins which may use this directory differently (Do they? I could not really find anything about the conventions of the target directory).
Additionally I'd prefer a solution that works with the usual maven conventions (if a convention for this case exists).
How do I correctly generate a resource to be included in the jar file during build using maven?
Convention (or main usage at least)for Maven is to generate resources inside (target/generated-resources/[plugin/process]).
But unlike generated sources and compiler plugin, generated resources are not handled specifically by the jar plugin, so you do have to add it as a resource (with a new resource like you did or the build-helper-plugin).
If you follow the convention to place everything you generate under a sub-directory of generated-resources, you should have no fear about how other plugins use it.

Eclipse Maven multi module project with xmlbeans

I have a multi module project, in which one of the module ( say MODULE-A) generates sources and classes using xmlbeans plugin. So everytime when I do a clean install of parent project, eclipse recognizes all of the generated sources as new classes, and I don't want to commit the same files again and again when there is no schema change. To overcome this problem, I wrapped xmlbeans build under a profile so that I can build it with profile whenever there is a schema change. But it didn't solve the problem completely.
Whenever I try to do clean build of parent, MODULE-A is not creating 'schemaorg_apache_xmlbeans' under build directory ( which is something only generated by xmlbean plugin when I run with profile ). I can tell maven to exclude 'schemaorg_apache_xmlbeans' from the clean task. But I want to know if this is the right way to handle.
Appreciate your responses.
Thanks in advance
One alternative to this approach is to add this plugin:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<id>add-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>${project.build.directory}/generated-sources/</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
This will allow the generated-sources to be added as a source folder so every time it generates you will have them built and available. You wouldn't commit these but when the actual jar gets built/released they will be in there and work all the same. This allows you to always be using code most up to date with your schema. This may not be the best solution for you but I found it to be a good idea when I ran into a similar situation.

define additional source directory in maven

I generate Java sources from a wsdl file. These sources are not under version control (but the wsdl is). We use the cxf-codegen-plugin in maven and the generated classes are generated in <sourceRoot>${project.build.directory}/generated/cxf</sourceRoot>.
This works all fine in maven.
I have to define this directory as addition source directory in Intelij Idea. (targetis normaly excluded).
But every time I re-import the maven project into InteliJ Idea (due to pom changes), I have to manually edit the project structure in Idea and redefine the addition source directory.
Is there any way I can either define this aditional source directory in maven, so Idea picks it up on reload, or tell Idea not to forget the manual source directoy definition?
This case is described in the IntelliJ IDEA Maven FAQ, Generated Sources section:
Specify the directory of your source root when you reimport a project.
You can select one of the following options:
Detect automatically This is a default option. When you select this option, IntelliJ IDEA automatically detects the location of the generated sources. IntelliJ IDEA also detects which directory to mark as a source root. However, IntelliJ IDEA searches for the generated sources only in target/generated-sources and target/generated-sources/* directories.
target/generated-sources This option enables you to mark the directory as source root manually.
subdirectories of "target/generated-sources" This option enables you to mark a subdirectory as a source root manually.
Don't detect This option lets you skip the detection process.
Take a look at the <add-source> build goal (see an example here)
Quote:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<id>add-wsdl-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>${basedir}/src-generated/src</source>
</sources>
</configuration>
<!-- [...] -->
</execution>
</executions>
</plugin>
You could define the (external) source directory as an dependency to your module. Project Structure -> Modules -> Depenencies. There you have to add a new JAR or Directory dependency.

Resources