Compile scala classes with debug info through Maven - maven-2

I have a scala project that I use Maven and the maven-scala-plugin to compile. I need to include debug information in the compiled classes and I was wondering is there a way to ask Maven or the scala plugin to do this. I found this page that makes it sound possible but it's not clear where to put the params in the pom.xml.
If possible I'd like this option to be something specified in the pom.xml rather than on the command line.

Compiling .class files with debugging information needs to be done at the maven-scala-plugin level. Doing it at the maven-compiler-plugin - which is by the way the default as we can see in the documentation of the debug option that defaults to true - is useless as it's not compiling your Scala sources.
Now, if we look at the scalac man page, the scalac compiler has a –g option that can take the following values:
"none" generates no debugging info,
"source" generates only the source file attribute,
"line" generates source and line number information,
"vars" generates source, line number and local variable information,
"notc" generates all of the above and will not perform tail call optimization.
The good news is that scala:compile has a nice args optional parameter that can be used to pass compiler additionnals arguments. So, to use it and pass the -g option to the scala compiler, you just need to configure the maven plugin as follow:
<plugin>
<groupId>org.scala-tools</groupId>
<artifactId>maven-scala-plugin</artifactId>
<version>2.9.1</version>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
<configuration>
<args>
<arg>-g:notc</arg>
</args>
...
</configuration>
</plugin>
I'm skipping other parts of the configuration (such are repositories, pluginRepositories, etc) as this is not what you're asking for :)

Related

Run static analysis tools in compile or package step in Maven2?

I'm researching using Maven for my team, and one of my goals for the build is to have static analysis tools run for every build, and perhaps fail the build for certain severe errors. However, in maven it seems that these are treated as reports and run on the site lifecycle. This presents a couple of problems as we don't intend to use the site for most projects, and it requires an extra step (or at least additional phase) to get the static analysis.
Is there a way to run static analysis tools in maven-2 in the compile or package phase (or equivalent)?
This can be done by configuring the plugin (findbugs for example) in the <build> section and configuring the <phase> in the <executions>:
<executions>
<execution>
<id>findbugs-run</id>
<phase>process-classes</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>

How to structure Maven3 project to produce inputs to generate-sources in another project?

I need to generate a few small text files that will be used as inputs during generate-sources phase of another project (data files input to FMPP/FreeMarker). The generator is Java source code - that is, the code that generates the text files is compiled in the first project. In this kind of scenario, how are the data files normally conveyed from one project to the other?
I could cobble together a dozen lame ways to do this - I'm looking for best practice.
At the moment, I'm avoiding the problem by having the first project just produce an executable jar, which is run by the second project to produce the data files. But there's really no reason for the code to be "public" - to be installed - the output of the first project really should just be the TDD files.
I'm not sure I have the full picture of what you're trying to do here but it sounds to me like you should be using the maven dependency plugin.
I'm assuming that the first project would create an artifact with the data files you need for the second and other projects. The second project could use the dependency plugin to unpack that artifact into target/generated-sources or wherever it is needed as part of its build.
For example:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.1</version>
<executions>
<execution>
<id>unpack-interfaces</id>
<phase>initialize</phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<configuration>
<includeArtifactIds>first-project-artifact</includeArtifactIds>
<includes>*.TDD</includes>
</configuration>
</execution>
</executions>
</plugin>
I hope I don't misunderstand you. You can run a maven2 project with exec-maven-plugin. This will run the first project and produces input for the next. If you should copy the *.tdd files, maybe you can use maven-resources-plugin for this. Hope it helps.

Maven - Skip building test classes

Is there a simple way to not build the test classes?
mvn clean install -Dmaven.test.skip=true
According to the documentation on the Maven Surefire Plugin, -Dmaven.test.skip should skip both compilation and execution of the tests. By contrast, -DskipTests just skips the test execution: the tests are still compiled.
Just to be explicitly clear:
skipTests will compile anything in the <testSourceDirectory>, but will not execute them.
maven.test.skip will NOT compile any tests, but WILL execute any compiled tests that made their way into the <testOutputDirectory>.
So the behavior of the above 2 is opposite. Just wanted to point out that maven.test.skip doesn't skip compilation AND execution if test files are unpacked/copied/etc. into <testOutputDirectory>.
Also, depending on which version of Maven your using, there's also maven.test.skip.exec=true which additionally skips test execution similar to skipTests.
Run a phase that doesn't include test-compile, for example compile.
mvn clean compile
I'm not an expert at maven, but what I use in my current project is:
mvn clean install -DskipTests=true
Depending on your use case using:
mvn compile -DskipTests=true
might work for you too.
I found a work-around in another question, which actually overrides a plugin execution by adding the following snippet in your pom.xml by default:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<executions>
<execution>
<id>default-testCompile</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
This seems to work but definitely does not disable phase but disables the default actions that a plugin defines at a specific phase.

Combined site/deploy goal for Maven

When running a Maven build on the CI server, I generate the site to publish the documentation and reports, and also deploy the artifact to the snapshot repository for use by other projects. To do this I run the following goals:
mvn clean site deploy
This means the unit tests are run twice, once for the site lifecycle and once for the deploy lifecycle. If I configure the site goal to be bound to the standard lifecycle the tests are still run twice, running the site goal always causes the tests to be run because of the #requiresDependencyResolution test annotation. This is fine if you're only creating the site, but in the context of a deploy it greatly increases the build time for no benefit.
I have a workaround that involves copying the SiteMojo (and the required parents) to a new plugin and removing the #requiresDependencyResolution test annotation from the copy.
This modified mojo will generate the reports without forcing the tests to be run again but I'd prefer a solution that doesn't involve any hacking of the site plugin. Is there a way to suppress the requiresDependencyResolution annotation?
I'm surprised this works - the #requiresDependencyResolution test tag doesn't actually trigger the tests being built - that should be one of the reports that you've included. Normally, I recommend running the site and the build in separate Maven executions in CI so you can get fast feedback on your build and publish the latest site only when that succeeds.
Another alternative is to run it as mvn clean deploy site, and choose the report-only mojo for surefire-report-maven-plugin (this is usually the report that is running the tests again). This will use the previous test results. Of course, another alternative is disabling that report altogether, since you likely get those results from another source such as your CI server anyway.
My current approach is to create a new plugin with copies of the relevant types from the maven-site-plugin. These types are identical to the standard versions except for changing the type name, the goal name and the removal of the #requiresDependencyResolution test annotation.
The copied types are:
org.apache.maven.plugins.site.AbstractSiteMojo
org.apache.maven.plugins.site.AbstractSiteRenderingMojo
The parent mojos are required so Maven can process the javadoc-based annotations (this shouldn't be required for Maven 2.2.0+).
org.apache.maven.plugins.site.SiteMojo
org.apache.maven.plugins.site.SiteJarMojo
These two are copied as SiteOnlyMojo and SiteJarOnlyMojo respectively, SiteJarOnlyMojo is changed to inherit from SiteOnlyMojo . Otherwise the only changes are to change the goal namess and remove the annotation.
So SiteOnlyMojo has:
* #goal site
* #requiresDependencyResolution test
changed to:
* #goal site-only
and SiteJarOnlyMojo has:
* #goal jar
* #phase package
changed to:
* #goal jar-only
* #phase package
These types are declared in a maven-plugin project with artifactId maven-site-only-plugin with a dependency declared on the proper site plugin.
To use this I define a profile (I don't want the reports running on every execution, only when -Psite is declared on the command line) and bind it to the prepare-package phase (prior to 2.1.0, you'd have to bind it to the package phase instead).
<profile>
<id>site</id>
<build>
<plugins>
<plugin>
<artifactId>maven-site-only-plugin</artifactId>
<version>1.0.0</version>
<executions>
<execution>
<phase>prepare-package</phase>
<goals>
<goal>jar-only</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<build>
<pluginManagement>
<plugins>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-site-plugin</artifactId>
<version>3.2</version>
<executions>
<execution>
<goals>
<goal>site</goal>
<goal>deploy</goal>
</goals>
<phase>deploy</phase>
</execution>
</executions>
</plugin>
...
</plugins>
</pluginManagement>
</build>
This will automatically execute the site action when issuing a 'mvn deploy' command, as well as ensuring the testing suite is only executed once.

maven compilation error: duplicate classes

In my maven2 project I have a directory ${basedir}/autogen that contains some autogenerated source code files produced by wsdl2java.
When running mvn compile I get an compilation error, because of duplicate classes, that lives in ${basedir}/autogen. This is true. But what is the compilation phase doing in ${basedir}/autogen? I have not told maven to add this directory as a source directory.
And there seems to be no way of telling maven to ignore the directory.
I had the same problem when using the maven-processor-plugin and found that the solution was to configure the maven-compiler plugin as follows:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
<compilerArgument>-proc:none</compilerArgument>
</configuration>
</plugin>
-proc:none means that compilation takes place without annotation processing and therefore no duplicate classes (which are typically generated in the generate-sources phase)
I hope that helps.
I've seen this a few times. In almost all cases, it is due to the generated classes being added to the main src tree then checked into version control.
In my case, it worked when I changed source directory.
New POM looks like,
<build>
<sourceDirectory>src</sourceDirectory>
Pointing just a src folder with sourceDirectory tag.
Earlier it was
<build>
<sourceDirectory>.</sourceDirectory>
Note that earlier it was working in IntellIJ, but not on cmd.
Now it works on both.
I had a similar problem with JPA model generator. It occurred on this dependency:
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.jpa.modelgen</artifactId>
<version>2.1.1</version>
</dependency>
I wrongly added the scope=provided and that resulted in:
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:2.3.1:compile (default-compile) on project mocker: Compilation failure: Compilation failure:
[ERROR] \Projects\entity\MockVehicle_.java:[10,7] duplicate class: entity.MockVehicle_
I had the exact same issue. In my case the problem was that I called maven with -f=./pom.xml. I have no idea why this leads to a different result (would be nice if someone can explain) but maybe good to know if someone else has the same issue.
I resolve it by remove generateAsync from my pom.xml the the GWT plugin will look like
<groupId>org.codehaus.mojo</groupId>
<artifactId>gwt-maven-plugin</artifactId>
<version>${gwtVersion}</version>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>test</goal>
<!-- <goal>i18n</goal> -->
</goals>
</execution>
</executions>
Its hard to change default maven behaviour, i think its better to go with it - you could generate those files with maven wsdl2java-maven-plugin
I my case helped this:
<!-- https://mvnrepository.com/artifact/javax.annotation/javax.annotation-api -->
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</dependency>
All answers here where not helpful. This may be the correct answer:
Another StackOverflow user wrote:
I have found an JetBrains Team member comment stating that:
IDEA automatically excludes the build 'target' folder, providing that
there are no generated sources under it, otherwise it excludes all
sub-folders but the generated.
Avro by standard in a generated-sources folder. This folder it not ignored by maven ans the generated classes in there will count as duplicate.
Maven will only igonre the target folder by default.
To fix add this line in the pom.xml:
<sourceDirectory>${project.basedir}/src/main/target/resources/avro</sourceDirectory>
Context:
<groupId>org.apache.avro</groupId>
<artifactId>avro-maven-plugin</artifactId>
<version>${avro.version}</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>schema</goal>
<goal>protocol</goal>
<goal>idl-protocol</goal>
</goals>
<configuration>
<sourceDirectory>${project.basedir}/src/main/target/resources/avro</sourceDirectory>
<stringType>String</stringType>
<createSetters>false</createSetters>
<outputDirectory>${project.basedir}/target/</outputDirectory><enableDecimalLogicalType>true</enableDecimalLogicalType>
<fieldVisibility>private</fieldVisibility>
</configuration>
</execution>
</executions>
This will put the generated-resources folder under the target folder.
I resolve the same issue
cleaning maven project :-mvn clean
delete com folder from src then compile
copy com from generated to src->main-->java
again compile
Hope this Help..