How to use Intellij IDEA and Maven 2 together for debugging and context help
Latest version of Intellij IDEA has excellent integration with Maven 2.
I want to explain one tip that could help you to gain productivity.
When
you debug with IDEA, it's nice to have sources and javadocs for each
used library registered with IDEA. If you have registered additional
sources, you can debug deeper, going inside those sources. If you have
registered additional javadocs, you can get context help for used
classes from that libraries.
Unfortunately, this process is manual and tedious. Usually you have to do the following actions:
- Find out on Internet sources for given library and unzip them locally.
- Find out on Internet javadocs for given library and unzip it locally.
- With the help of Intellij IDEA you have to register unzipped sources and javadocs.
This should be done for each external library in the project. If you have a lot of dependencies,
it'll take a lot of time.
Even if your project is dependent on other your own libraries, you still won't get sources and context helps
for them automatically. To have this support, you will do same things as what you did for external libraries -
IDEA should know where your dependent sources/javadocs are located.
Is it possible to make this process less time consuming, less painful? And the answer is: Yes.
When your project is equipped with maven's pom.xml file, you can do the following trick. Close your current
project
and next time, when you try to open this project again, use pom.xml
file as the project file (use "Open Project" functionality) instead of
regular IDEA project file.
What happens here, IDEA is trying
to resolve dependencies, defined inside maven project file and
populates them back into IDEA's project (synch up). After such
synchronization, IDEA is looking for sources and javadocs inside maven
reopsitory. They should be located in same folder as your jar file and
should have name built by special scheme. For example, my example
library is located here:
${maven.local.repository}/org/google/code/maven-archetypes/1.0.0/maven-archetypes-1.0.0.jar
My sources and javadocs should be layed out in this way
${maven.local.repository}/org/google/code/maven-archetypes/1.0.0/maven-archetypes-1.0.0-sources.jar
${maven.local.repository}/org/google/code/maven-archetypes/1.0.0/maven-archetypes-1.0.0-javadoc.jar
As you can see, maven has "classifier" notion that helps us to differentiate "jar" artifact from "sources" and
"javadocs" artifacts.
Good thing is that most of new artifacts to be deployed recently into maven repositories (or at least everybody who understand it and wants to benefit from it), follow this pattern.
Now, what we have to do for our project components to be "in synch" with this pattern? Follow these steps:
1. Generate sources and javadocs with the help of "maven-source-plugin" and "maven-javadoc-plugin"
plugins:
>mvn source:jar
>mvn javadoc:jar
After the execution of these commands, 2 new files will be created. By default, you will see these files in "target" folder:
maven-archetypes-1.0.0-javadoc.jar
maven-archetypes-1.0.0-sources.jar
2. Install sources into maven repository:
mvn install:install-file ^
-Dfile=target/yourArtifactId-yourVersion-sources.jar ^
-DgroupId=yourGroupId ^
-DartifactId=yourArtifactId ^
-Dversion=yourVersion ^
-Dpackaging=jar ^
-Dclassifier=sources ^
-DgeneratePom=false
3. Install javadocs into maven repository:
mvn install:install-file ^
-Dfile=target/yourArtifactId-yourVersion-javadoc.jar ^
-DgroupId=yourGroupId ^
-DartifactId=yourArtifactId ^
-Dversion=yourVersion ^
-Dpackaging=jar ^
-Dclassifier=javadoc ^
-DgeneratePom=false
You can use this batch script to do all commands in one step:
rem install-jar-javadoc-sources.bat
rem 1. generate sources jar file
call mvn source:jar
rem 2. generate javadoc jar file
call mvn javadoc:jar
SET GROUP_ID=org.google.code
SET ARTIFACT_ID=maven-archetypes
SET VERSION=1.0.0
SET SOURCES_CLASSIFIER=sources
SET JAVADOC_CLASSIFIER=javadoc
rem 3. install sources jar file
call mvn install:install-file ^
"-Dfile=target/%ARTIFACT_ID%-%VERSION%-%SOURCES_CLASSIFIER%.jar" ^
"-DgroupId=%GROUP_ID%" ^
"-DartifactId=%ARTIFACT_ID%" ^
"-Dversion=%VERSION%" ^
"-Dpackaging=jar" ^
"-Dclassifier=%SOURCES_CLASSIFIER%" ^
"-DgeneratePom=false"
rem 4. install javadoc jar file
call mvn install:install-file ^
"-Dfile=target/%ARTIFACT_ID%-%VERSION%-%JAVADOC_CLASSIFIER%.jar" ^
"-DgroupId=%GROUP_ID%" ^
"-DartifactId=%ARTIFACT_ID%" ^
"-Dversion=%VERSION%" ^
"-Dpackaging=jar" ^
"-Dclassifier=%JAVADOC_CLASSIFIER%" ^
"-DgeneratePom=false"
You also can run these commands as Beanshell script:
// installSourcesJavadocs.bsh
import org.sf.pomreader.PomReader;
import org.apache.maven.bootstrap.model.Model;
import org.sf.scriptlandia.MavenHelper;
MavenHelper.executeMaven(null, new String[] { "source:jar" });
MavenHelper.executeMaven(null, new String[] { "javadoc:jar" });
PomReader pomReader = new PomReader();
pomReader.init();
Model model = pomReader.readModel(new File("pom.xml"));
void installArtifact(Model model, String classifier) {
System.setProperty("file", "target/" + model.getArtifactId() + "-" + classifier + ".jar");
System.setProperty("groupId", model.getGroupId());
System.setProperty("artifactId", model.getArtifactId());
System.setProperty("version", model.getVersion());
System.setProperty("packaging", model.getPackaging());
System.setProperty("classifier", classifier);
System.setProperty("generatePom", "false");
MavenHelper.executeMaven(null, new String[] { "install:install-file" });
}
installArtifact(model, "sources");
installArtifact(model, "javadoc");
In order to run this script, you have to install Scriptlandia launcher on your computer. It will take care of downloading all required dependencies, installing them locally on your computer and then executing Beanshell script.
- Login or register to post comments
- 5015 reads
- Printer-friendly version
(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)










Comments
Dirk replied on Fri, 2008/02/15 - 2:00am
Hi!
Why not "bind" the javadoc and source-plugin to the install lifecycle phase via the following in the pom.xml?
<project>
<build>
<plugins>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<executions>
<execution>
<phase>install</phase>
<goals>
<goal>javadoc</goal>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<phase>install</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
...
</plugins>
</build>
</project
That way the source- and javaoc-artifacts are build during install and deployed to the repository with deploy.
Regards,
Dirk
Alexander Shvets replied on Fri, 2008/02/15 - 8:24am
hi, Dirk
Thanks for advice - it helps to automate generation of artifacts. Is it possible to automate installation part?
Alexander.
Dirk replied on Fri, 2008/02/15 - 9:37am
Hi!
Well I had the impression that its installed automatically when I execute "mvn install" on the project. does that noch work for you?
If not there must be some more in my pom related to this. :-)
Regards,
Dirk
Alexander Shvets replied on Fri, 2008/02/15 - 2:00pm
Dirk replied on Fri, 2008/02/15 - 3:52pm
in response to: shvets
Um,
I am sorry. You have to bind it to the package-phase instead of install to get it installed.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>javadoc</goal>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
Dirk
Alexander Shvets replied on Fri, 2008/02/15 - 6:44pm
package command prepares artifact in target folder, install command - installs it into local repository. Unfortunately solution 2 does not work (as well as solution 1).
I think it's because of maven limitation - it can produce/install only one atrifact in one moment. Maybe it will be better idea to wrap up my code into separate maven plugin... I think such plugin make good sence. Otherwise somebody should as authors of install plugin to trigger it with some additional input parameter.
Dirk replied on Sat, 2008/02/16 - 3:34pm
Hi Alex!
I am not sure why its not working for you. I compiled a little example-project. Its available at
http://biafra.diskordia.com/mvntest.tar.gz
It contains only a pom.xml and one little demo.class. Please try this! I am using mvn 2.0.7. But this project also builds fine with the embedded Maven2 for IntelliJ.
On install it creates three jars:
Test-1.0-SNAPSHOT-javadoc.jar
Test-1.0-SNAPSHOT-source.jar
Test-1.0-SNAPSHOT.jar
and installs them into the local repository.
Regards,
Dirk
Alexander Shvets replied on Sat, 2008/02/16 - 4:34pm
Thanks, Dirk
It works now. But could you explain how it works (especially the part where maven installs additional artifacts, why it does it).
Another task that is tightly related, is how to generate artifacts with different classifiers in one shot: e.g.
Test-1.0-SNAPSHOT.jar
Test-1.0-SNAPSHOT-jdk15.jar
Test-1.0-SNAPSHOT-jdk16.jar
And at the same time they should have different bytecode versions (first and second file have same version). Do you have any idea how to do it?
Thanks,
Alexander.
juanhernandezgomez replied on Mon, 2009/03/30 - 10:10am
Hi,
first of all thanks to both of you guys (Alexander and Dirk) because I was looking to how to do that and found this great post.
The last refinement is to wrap that into two different profiles so you can generate the javadoc and/or sources only when interested.
<project> <profiles> <profile> <id>javadoc</id> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-javadoc-plugin</artifactId> <executions> <execution> <phase>package</phase> <goals> <goal>jar</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </profile> <profile> <id>source</id> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-source-plugin</artifactId> <executions> <execution> <phase>package</phase> <goals> <goal>jar</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </profile> </profiles> </project>You can the run any lifecycle activating only the profiles that you are interested in. Eg.: