How can I organize source-generation in Maven? - java

I have a Maven plugin which generates sources for my java project and places them into 'target/generated-sources' folder. I need these sources at compile-time. I want to have them in my project while modifying it, already generated. And of course, I want to put them into the correct folder under 'src' folder, and not into 'target/generated-sources'. How can I organize this using Maven?
In other words, I want to be able:
generate sources I need by running some goal of my special source-generating plugin (already done, the sources have the package I specified)
move these generated sources to 'src/main/java/...' folder of standart Maven layout.
remove them from 'target/generated-sources' folder, because otherwise mvn clean install command raises error which says that I have "duplicate class". Indeed, if I just copy generated sources from target to src - I have to classes with the same name and package, though one of them is located in target folder.
Which Maven plugins can hlp with this? I suppose this is a typical task.

The standard solution in maven is to generate all source into target/generated-sources, all source code from target/generated-sources and from src is compiled into target/classes and merged into target jar.
Plugin should never touch files under src directory, because these files are managed by version control system (ex. git).
If plugin is badly written and source files from target/generated-sources is not automatically compilled into target, then use goal build-helper:add-source from Build Helper Maven Plugin as #James Kingsbery said.
In maven-com4j-plugin source code there are comments:
/**
* Directory in which to create the Java COM wrapper files. This directory
* will be added to the Maven project's compile source directory list and
* will therfore be auto-compiled when the Maven compile phase is run.
*
* #parameter expression="${outputDirectory}"
* default-value="${project.build.directory}/generated-sources/com4j/java"
*/
The more important part and solution to your problem is:
This directory
will be added to the Maven project's compile source directory list and
will therfore be auto-compiled when the Maven compile phase is run
So, generated source code should be automatically compiled and archived into builded jar.

You should have a look at the build helper plugin. It allows you to specify additional source directories (such as target/generated-sources). See also Usage of maven Build Helper Maven Plugin.

If your plugin works correctly it will add the generated sources to the internal project and other plugins like the maven-compiler-plugin will pick it up and compile the generatd code.
Within your plugin code you can accomplish this by using something similar:
mavenProject.addCompileSourceRoot( getOutputDirectory().getAbsolutePath() );

Related

Can files outside of the Maven folder structure get compiled?

We have a Java project that was modified about 2 years ago based on the dates.
The project uses a the Play Framework which as I recalled built and ran just fine back in 2012.
The developer apparently had tried to change the project to be a Maven project but the folder structure is all over the place and not within the Maven src folder structure.
Attempting to run the Play commands does not work on building the project any longer and using the Maven commands does not compile the code.
What occurs is just the packaging of all of the folders and source code into a .jar file.
So the question is 'Can files outside of the Maven folder structure get compiled?' if so how, OR do I need to restructure all the code to be placed into the proper Maven folder structure to try and get this to work again?
Thanks for your time.
Rough view of the folder tree below: Unable to post the POM as it is on another system
Project Name
src
main/java/
trunk
Project Name
... play framework folder structure in here eclipse, modules, precompiled, tmp
conf
lib
Web Content
META-INF
WEB-INF
Yes you can compile files in a non-standard Maven folder structure. Maven natively supports multiple source directories for the purposes of generated sources.
Read the Maven use guide When You Can't Use the Conventions
Using Multiple Source Directories This occurs when you are producing a
single JAR (or other artifact), and have several source directories
with classes you want to include.
This answer shows how to edit the directory structure in Maven by specifying the appropriate properties to override from the superpom.
The Maven pom docs show the build element set mentioned in the link above.
As a side note this answer covers a non standard directory layout for building war.

Javadoc for a New java maven project in eclipse

I created a new Maven project and generated Javadocs through eclipse. It created a lot of html files in the project directory inside a folder called "doc".
Now I want to distribute this project as a dependency to my colleague and he does not have the source of the project I created. He is only adding my project as a dependency. He says he cannot see the javadoc when he hovers on a method that I created in my project.
What am I missing here?
Add the maven-javadoc-plugin to the project (plugins section of your pom.xml), instead of generating the Javadocs through Eclipse. Please have a look at the jar goal. If done correctly, the Maven build will package a javadoc jar beside the normal jar file. The build will result in following jars:
${artifactId}-${version}.jar
${artifactId}-${version}-javadoc.jar
If you want to provide the sources additionally, the maven-source-plugin (goal jar) will do the job for you.
The installation of the jar file, the javadoc file and in case the source file into your colleague's local Maven repository can be done with the maven-install-plugin.

Intellij idea specify output folder for each source folder (like in eclipse)

I'm working with huge project which has almost hundred plugins which in turn has it's own folder. The issue is that this project was created in eclipse and for each plugin's source folder a corresponding output folder specified. I'm wondering if it is possible to do the same thing in intellij or I'm forced to use eclipse?
Just some screenshots to make thigs clearer:
In the project structure you can create an artifact for each of your library an specify an output directory.
Try File->Project Structure then in the Project Setting add new artifact and specify output directory

"Could not find or load main class" after removing Maven nature and files (pom.xml, target/) from an Eclipse Project

I accidentally converted my project to Maven by going to Configure > Convert to Maven Project. Now I want to undo this. I read that I need to right click Maven > Disable Maven Nature and that worked fine. However I want to totally remove Maven, so I deleted the pom.xml and the target folder. When I try to run my code now, I get the error:
Error: Could not find or load main class
So what am I missing? How do I revert from a Maven project to a non-Maven project?
When you convert a Java project to a Maven project in Eclipse, the Maven Integration for Eclipse (m2eclipse) configures the Java incremental compiler to put the compiled class files in the same location as Maven would put them, i.e. target/classes.
So when you remove the Maven nature and delete the target folder, you now also have deleted the compiled class files and your project can no longer run. AFAIK, the incremental compiler doesn't detect when you remove its output files, so you need to trigger a rebuild by cleaning the project (Project > Clean...)
This will fix the problem that you can not launch your project, but may re-create a target folder. If you also want this to be "fixed", you can switch back to some other folder name for the binaries, e.g. bin, in the project's Java Build Path configuration on the Source tab.
Is it basically a Maven project, i.e., do you have and maintain it through a pom.xml? Then my suggestion is to delete the project in Eclipse but keep the files on the disk (i.e., it removes it from the workspace). Then, run a simple mvn eclipse:clean eclipse:eclipse which creates a simple Java project without the Maven nature based on the POM (so the libraries are linked and the source/output directories are set up correctly - this may solve your ClassNotFoundError).
If it's a simple Java project, I would advise deleting it from the workspace, removing the .classpath and .project files and importing it again with the Create a Java project with existing sources wizard.
Either way, make a backup of your project before you start doing anything :-)

IntelliJ IDEA Gradle + Groovy

I am new to IDEA.
What I would like to do is have a project (or module?) that has maven folder structure (aka src/main/java, src/main/groovy, src/test/groovy, etc), be managed by Gradle and support creation of Groovy classes, their compilation and execution.
What I tried:
Create a "Groovy" Project.
I can add "Maven" support, but not Gradle.
Create a "Gradle" project and add "Groovy" module to it
I can manage dependencies and plugins, but the file structure is screwed up.
The code goes into a sub-folder of the project (aka the name of the module)
I cannot directly add folders to the "src" of the module. When I copy them into the src folder they are considered package names.
What I am looking for:
Solution to the particular problem
General workflow for creating multi-facet (aka Gradle+Groovy or Java+Maven or Web+YouNameIt) project/modules.
Explanation of what is the reason for this paradigm/structure shift in IDEA?
I would suggest not creating the project from inside Intellij.
Since Intellij imports Gradle projects quite nicely you can just import one of the pre-made Groovy Gradle Quick Starts you can find at the root of your Gradle installation.
For example $GRADLE_HOME/samples/groovy/mixedJavaAndGroovy has the exact Java/Groovy layout you describe with the HelloWorld Classes and Tests in place. Just copy it, rename the root folder, import it into Intellij and code!
Solution to the particular problem
0) Turn on Gradle plugin in Preferences -> Plugins
1) Create any Java project (Groovy, Maven, plain Java)
2) Create build.gradle file in base directory
3) Open JetGradle view and click Add. Then select your build file
4) When you do this first time, IDEA will prompt you to locate your local Gradle distribution (you may also change it later in Preferences -> Gradle settings)
As for project structure, Gradle follows Maven conventions, so in the build file you just write:
apply plugin: 'java'
and everything just works.
Create a "Gradle" project and add "Groovy" module to it
I can manage dependencies and plugins, but the file structure is screwed up.
The code goes into a sub-folder of the project (aka the name of the module)
I cannot directly add folders to the "src" of the module. When I copy them into the src folder they are considered package names.
Explanation of what is the reason for this paradigm/structure shift in IDEA?
The main reason is to provide possibility of logical decomposition of your application into separate modules, e.g. app-core, app-web, app-ear etc. Each of this modules produces an artifact: jar, war, ear.
Compare this with other IDEs, say Eclipse, where you would have several different projects (perhaps dependent on each other) to accomplish the same thing. So basically, you may think of IDEA module as of Eclipse project (roughly). Also this greatly simplifies usage of Maven multi-module projects.
As for the src folder: IDEA lets you mark directories inside the module "content root" (base directory of the module) as Source, Test Source or Excluded. If src is marked as Source directory, then obviously everything inside is treated as packages and sources.
I followed the steps in this video:
Create "Gradle" project, with Gradle plugin enabled and Gradle API plugin disabled. Select "Create empty folders" option.
Add "apply plugin: 'groovy'". This will create groovy folders.
Add "" to IML project file in order to be able to create Groovy classes.

Categories

Resources