define additional source directory in maven - 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.

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>
`

how to create maven mojo plugin to overwrite files directories in target project

I am writing a maven plugin which generates java source code based on input text file and some additional configuration.
e.g. User creates maven project and adds my plugin in his project's pom.xml as below -
<plugin>
<groupId>abc.plugin</groupId>
<artifactId>abc-maven-plugin</artifactId>
<version>1.0.0</version>
<executions>
<execution>
<goals>
<goal>abc</goal>
</goals>
</execution>
</executions>
<configuration>
<schemaPath>${basedir}\input</schemaPath>
<package>com.svc.xyz</package>
<fileNametxt>${basedir}\input.txt</fileNametxt>
</configuration>
</plugin>
As part of executing the goal of my plugin, i would like the plugin delete all the pre existing java source files/directories in user's project as well as rewrite pom.xml of user project.Plugin should regenerate user project's pom.xml taking existing contents and also keep some other existing user project resources like schema Directory.
Also,I don't want user of plugin to do any editing after generation of source code and would prefer to directly 'compile package' the generated source code in user project by the plugin.
Since plugin will regenerate users' pom.xml itself, may be need to create a new maven project altogether with generated source code, compile, package and have jar created?

intellij not picking up maven project structure

I have a mavenized java project in Intellij 122.327. Unfortunately (due to legacy code) certain code in the src directory uses tests in the test directory. I'm trying to remove these dependencies but its a long shot. In the meanwhile, I'm able to compile and deploy by using the build-helper maven plugin and adding src/test/java as sources:
<execution>
<id>add-test-dir-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>src/test/java</source>
</sources>
</configuration>
</execution>
Problem is whenever I restart Intellij it keeps marking the src/test directory as a "test" directory (if I go to Project Structure -> Modules -> Sources, src/test is marked in green). So every time I have to manually mark test/java as "Sources". Is there a way to permanently mark this as sources? Even better, does Intellij have a way to read from the pom and infer the project structure?
Check the logs for any related exceptions. There can be many reasons for this problem like a proxy with the self signed certificate, invalid VM options, network issues, etc. See also this answer.
If the issue persists, contact support with the logs attached.

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

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>

Where should I put application configuration files for a Maven project?

I'm using the Maven Application Assembler plugin to generate stand-alone executables from my Java project. The application reads in configuration files, including Spring files. The Application Assembler plugin has an option (activated by default) to add a etc/ directory to the application's classpath, but what should I do to have the plugin copy my configuration files to this directory?
Or more generally, where is in Maven the kosher location for application configuration files that should NOT be packaged in the artifact?
You can also use resource filtering:
http://maven.apache.org/guides/getting-started/index.html#How_do_I_filter_resource_files
turn on filtering:
...
<build>
...
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
...
</build>
...
make a file under src/main/resources like: application.properties
application.properties
configprop.1=${param1}
configprop.2=${param2}
Then setup a profile and set some properties perhaps in a settings.xml
that sets different properties depending on if this is a dev or production build.
see: http://maven.apache.org/guides/introduction/introduction-to-profiles.html
I have different properties set depending on if this is the build server, dev or a production deployment
mvn -Denv=dev || mvn -Denv=dev-build || mvn -Denv=production
The maven link has a pretty good description.
For folks who have come to this more recently there is, since version 1.1 of the Application Assembler Plugin, the optional parameters configurationSourceDirectory and copyConfigurationDirectory. Please find them in an example POM.xml extract below:
<configuration>
<!-- Set the target configuration directory to be used in the bin scripts -->
<configurationDirectory>conf</configurationDirectory>
<!-- Copy the contents from "/src/main/config" to the target
configuration directory in the assembled application -->
<copyConfigurationDirectory>true</copyConfigurationDirectory>
<!-- Include the target configuration directory in the beginning of
the classpath declaration in the bin scripts -->
<includeConfigurationDirectoryInClasspath>
true
</includeConfigurationDirectoryInClasspath>
...
</configuration>
More information is here
You could try the maven assembly plugin. I used it in conjunction with the appassembler plugin.
Configure appassembler to point to whatever name you want for your configuration directory, if you don't want 'etc'. The assembly plugin assembles everything in its own output directory, so I configure the assembly plugin to copy the bin and repo dirs from the appassembler directory into its output dir, then I have it copy the config files (mine are in src/main/config) into the expected config dir. There is some duplication in this, because you are copying the appassembler outputs, but that didn't really bother me.
So what you have after executing the assembly plugin is your bin, repo, and config dir are all peer directories under the assembly output directory. You can configure it to have a different structure if you prefer, I just wanted mine to mirror the appassembler structure.
The nice thing is that you can also configure the assembly plugin to change your binaries to executables, which I could't see how to do with appassembler. And, if you then bind appassembler:assemble and assembly:single goals to the package phase, all you have to do is 'mvn package', and it assembles everything.
I don't know if I understand you correctly. But what I have done in the past for a project where I needed to copy configuration files, is use the Maven AntRun plugin. What I did is execute the plugin in the process-resources phase and copied my configuration files to the specified directory using the Ant copy task. The Assembler plugin executes in the package phase so it should pick up your configuration files if you put it in the right place. Hope this answers your question a little bit.
I had been looking for an answer to what I think is your question, or at least a very similar question. Maven allows you to specify directories for resources using the maven-resources-plugin. I have a few configuration files in one of my resource directories. I've noticed that by putting copies of those files in the etc/ directory that you mention (which is at the beginning of my CLASSPATH) I can change values in those files for use at run time. I then wanted to have that etc/ directory created with copies of everything from my resource directory by default. The copy-resources goal from the maven-resources-plugin allowed me to do that. This stanza from Examples > Copy Resources on the left sidebar (I'm limited to 2 links in this post) is what did it for me:
<project>
...
<build>
<plugins>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>copy-resources</id>
<!-- here the phase you need -->
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/target/extra-resources</outputDirectory>
<resources>
<resource>
<directory>src/non-packaged-resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
...
</build>
...
</project>

Resources