Java packaging common problems

From FedoraProject

Jump to: navigation, search

Packaging Maven in Fedora can be quite frustrating experience, especially in the beginning. I'll try to collect common error messages and fixes that will show you how to workaround these problems

Contents

Basic issues with dependencies

Compilation failures

plexus-container-default

If you trace some build error to missing classes in plexus-container-default there is usually quite simple reason. We have two different versions of plexus-container-default (second one is plexus-containers-container-default). A lot of packages still use prehistoric alpha version (plexus-container-default) and don't build correctly with new version. There are usually more solutions (listed from best way to handle this):

  • Modify package to support new plexus-container-default and send patch upstream. This can take some time but is the best way to handle this.
  • Use custom depmap to map plexus-container-default to JPP/plexus:plexus-container-default

If you find package that doesn't work with either the old or new plexus-container-default you will have to fix it to support new container style.

Test failures

Test WILL fail sooner or later for some of your packages. There are several ways to fix or workaround them and I ordered them from best to worst:

Fixing those tests properly

Best way to solve failing tests is to fix them so that they will work OK. This is not always possible, sometimes running tests require network access (not available on koji) or are too resource-hungry to successfully run there. How do these failing tests show up? For example like this:

[ERROR] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Compilation failure
/builddir/build/BUILD/modello-1.4/modello-plugins/modello-plugin-xml/src/test/java/org/codehaus/modello/plugins/xml/XmlModelloPluginTest.java:[58,44] container has private access in org.codehaus.plexus.PlexusTestCase
[INFO] ------------------------------------------------------------------------
[INFO] Trace
org.apache.maven.BuildFailureException: Compilation failure
/builddir/build/BUILD/modello-1.4/modello-plugins/modello-plugin-xml/src/test/java/org/codehaus/modello/plugins/xml/XmlModelloPluginTest.java:[58,44] container has private access in org.codehaus.plexus.PlexusTestCase                                                 
        at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:715)     
        at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalWithLifecycle(DefaultLifecycleExecutor.java:556)        
        at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoal(DefaultLifecycleExecutor.java:535)

This is typical compilation failure caused by different version of dependency that we provide vs. what package expects. In this case we can inspect XmlModelloPluginTest.java and on line 58 we'll find:

ModelloCore modello = (ModelloCore) container.lookup( ModelloCore.ROLE );

container variable was inherited from PlexusTestCase. Older versions of PlexusTestCase class within plexus-default-container had this variable as protected (plus public getContainer() function). Newer versions of PlexusTestCase changed container variable permissions to private and offer only public getContainer() function. Most test compilation failures I have encountered were caused by changes in API and these should generally be relatively easy to fix.

Therefore simple solution for this is this patch:

+diff --git a/modello-plugins/modello-plugin-xml/src/test/java/org/codehaus/modello/plugins/xml/XmlModelloPluginTest.java b/modello-plugins
+index d9a2113..ab737bc 100644
+--- a/modello-plugins/modello-plugin-xml/src/test/java/org/codehaus/modello/plugins/xml/XmlModelloPluginTest.java
++++ b/modello-plugins/modello-plugin-xml/src/test/java/org/codehaus/modello/plugins/xml/XmlModelloPluginTest.java
+@@ -55,7 +55,7 @@ public class XmlModelloPluginTest
+     public void testXmlPlugin()
+         throws Exception
+     {
+-        ModelloCore modello = (ModelloCore) container.lookup( ModelloCore.ROLE );
++        ModelloCore modello = (ModelloCore) getContainer().lookup( ModelloCore.ROLE );
+ 
+         Model model = modello.loadModel( getTestFile( "src/test/resources/model.mdo" ) );
+ 

After updating package to newer dependency it might be a good idea to contact upstream and work with them on updating their dependency too.

Removing tests expected to fail

As mentioned in the previous section, sometimes tests need Internet access or a lot of resources. When it's not possible to modify tests and these are known to fail because of koji specifics, you can remove some of them specifically to enable rest of tests to work.

Ignoring failures

Sometimes tests compile OK but fail during runtime. Maybe there are genuine problems with the package and test failures should be inspected so that these problems will not affect users/developers. Usually it's best to test this failing package at least with some other package depending on it so that some of functionality is tested.

You can ignore test failures using: -Dmaven.test.failure.ignore=true

Using this should be accompanied with a comment why are the test failures ignored, if there are tests expected to fail, etc.

Skipping tests entirely

This solution should be used as a last resort and always accompanied with a comment explaining at least basic reasoning why tests were skipped and what other solutions were tried. This is needed mostly when some of required packages are too old. You should file a bug to update the out-of-date package. Perhaps include a comment like: "# skip tests because we have too old xmlunit in Fedora now (1.0.8). See update bug #xxxxx"

To skip tests you can use: -Dmaven.test.skip=true

Examples

javadoc:javadoc issue

You can encounter this bug when trying to create javadocs for multi-module maven projects:

[ERROR] BUILD ERROR
[INFO] ------------------------------------------------------------------------
[INFO] Internal error in the plugin manager executing goal 'org.apache.maven.plugins:maven-javadoc-plugin:2.7:javadoc': Unable to load the mojo 'org.apache.maven.plugins:maven-javadoc-plugin:2.7:javadoc' in the plugin 'org.apache.maven.plugins:maven-javadoc-plugin'. A required class is missing: org/apache/maven/shared/invoker/MavenInvocationException
org.apache.maven.shared.invoker.MavenInvocationException
[INFO] ------------------------------------------------------------------------
[INFO] Trace
org.apache.maven.lifecycle.LifecycleExecutionException: Internal error in the plugin manager executing goal 'org.apache.maven.plugins:maven-javadoc-plugin:2.7:javadoc': Unable to load the mojo 'org.apache.maven.plugins:maven-javadoc-plugin:2.7:javadoc' in the plugin 'org.apache.maven.plugins:maven-javadoc-plugin'. A required class is missing: org/apache/maven/shared/invoker/MavenInvocationException
	at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:698)
	at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeStandaloneGoal(DefaultLifecycleExecutor.java:569)
	at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoal(DefaultLifecycleExecutor.java:539)

Solution is pretty simple: use javadoc:aggregate instead. Another advantage of this approach is that you will not have to merge javadocs for all modules manually. Merged javadoc will be created in target/site/apidocs in top-level project

CommandLineException: Error inside systemErr parser

This error shows up during test phase and looks something like this:

[INFO] ------------------------------------------------------------------------
[ERROR] BUILD ERROR
[INFO] ------------------------------------------------------------------------
[INFO] Error while executing forked tests.; nested exception is org.apache.maven.surefire.booter.shade.org.codehaus.plexus.util.cli.CommandLineException: Error inside systemErr parser
[INFO] ------------------------------------------------------------------------
[INFO] For more information, run Maven with the -e switch 

This issue is caused by updated maven-surefire. See [1] for details. Until the bug is fixed you can call mvn-jpp with -Dmaven.test.redirectTestOutputToFile=false