jira.codehaus.org

  • Log In Access more options
    • Online Help
    • Keyboard Shortcuts
    • About JIRA
    • JIRA Credits
    • What?s New
  • Dashboards Access more options (Alt+d)
  • Projects Access more options (Alt+p)
  • Issues Access more options (Alt+i)
  • Maven Surefire
  • SUREFIRE-502

Specified classesDirectory is added to the end of the classpath

  • Log In
  • Views
    • XML
    • Word
    • Printable

Details

  • Type: Bug Bug
  • Status: Closed Closed
  • Priority: Major Major
  • Resolution: Fixed
  • Affects Version/s: 2.4.3
  • Fix Version/s: 2.5
  • Component/s: classloading
  • Labels:
    None
  • Environment:
    Windows Vista SP1, Java 1.5.0_13, Maven 2.0.9
  • Complexity:
    Intermediate
  • Patch Submitted:
    Yes

Description

When you specify a classesDirectory in the configuration element of the Surefire plugin definition the classesDirectory is appended to the end of the classpath rather than replacing the build output directory. This means included dependencies take precedence over your source code.

The problem appears to be the following code:

if ( !project.getBuild().getOutputDirectory().equals( classesDirectory.getAbsolutePath() ) )

{ classpathElements.remove( project.getBuild().getOutputDirectory() ); classpathElements.add( classesDirectory.getAbsolutePath() ); }

The classes directory should replace the build output directory, e.g.

if ( !project.getBuild().getOutputDirectory().equals( classesDirectory.getAbsolutePath() ) )
{
final int replacementIndex = classpathElements.indexOf(project.getBuild().getOutputDirectory());
if (replacementIndex >= 0)

{ classpathElements.remove( project.getBuild().getOutputDirectory() ); classpathElements.add( replacementIndex, classesDirectory.getAbsolutePath() ); }

else

{ classpathElements.add( classesDirectory.getAbsolutePath() ); }

}

  • Options
    • Sort By Name
    • Sort By Date
    • Ascending
    • Descending
    • Download All

Attachments

  1. Text File
    SUREFIRE-502.patch
    18/Jun/08 9:50 AM
    1 kB
    James Shiell
  2. Java Source File
    SurefirePlugin.java
    01/Aug/08 2:40 AM
    36 kB
    M. Dahm

Issue Links

is duplicated by

Bug - A problem which impairs or prevents the functions of the product. SUREFIRE-504 own classes and test-classes at the end of test classpath

  • Major - Major loss of function.
  • Closed - The issue is considered finished, the resolution is correct. Issues which are not closed can be reopened.

Bug - A problem which impairs or prevents the functions of the product. SUREFIRE-517 Invalid classpath order with classesDirectory and testClassesDirectory

  • Major - Major loss of function.
  • Closed - The issue is considered finished, the resolution is correct. Issues which are not closed can be reopened.
relates to

Improvement - An improvement or enhancement to an existing feature or task. SUREFIRE-619 The surefire plugin should generate the test classpath

  • Major - Major loss of function.
  • Closed - The issue is considered finished, the resolution is correct. Issues which are not closed can be reopened.

Activity

Ascending order - Click to sort in descending order
  • All
  • Comments
  • Work Log
  • History
  • Activity
Hide
Permalink
James Shiell added a comment - 18/Jun/08 9:50 AM

Patch with suggested fix.

Show
James Shiell added a comment - 18/Jun/08 9:50 AM Patch with suggested fix.
Hide
Permalink
M. Dahm added a comment - 01/Aug/08 2:38 AM

the original code looks like this:

getLog().debug("Test Classpath :");

// Check if we need to add configured classes/test classes directories here.
// If they are configured, we should remove the default to avoid conflicts.

// Check if we need to add configured classes/test classes directories here.
// If they are configured, we should remove the default to avoid conflicts.
if ( !project.getBuild().getOutputDirectory().equals( classesDirectory.getAbsolutePath() ) )

{ getLog().debug( "Warning: changing classpath! " + project.getBuild().getOutputDirectory() + " != " + classesDirectory.getAbsolutePath() ); classpathElements.remove( project.getBuild().getOutputDirectory() ); classpathElements.add( classesDirectory.getAbsolutePath() ); }

if ( !project.getBuild().getTestOutputDirectory().equals( testClassesDirectory.getAbsolutePath() ) )

{ getLog().debug( "Warning: changing classpath! " + project.getBuild().getTestOutputDirectory() + " != " + testClassesDirectory.getAbsolutePath() ); classpathElements.remove( project.getBuild().getTestOutputDirectory() ); classpathElements.add( testClassesDirectory.getAbsolutePath() ); }

However there are two problems here:
1.) In a Windows environment (which I'm forced to use ... the may be paths with mixed separators like C:\foo\bar/target/classes.
This cause the above equals() to return false, also the paths may not be different actually.
2.) The order of the classes and the test-classes folder may be swapped if both if() apply

I'd suggest the following code which uses Files to compare the paths and ensures that the test class path entry always comes first:

getLog().debug("Test Classpath :");

// Check if we need to add configured classes/test classes directories here.
// If they are configured, we should remove the default to avoid conflicts.

// Ensure that test classes always come first
final File outputDirectory = new File(project.getBuild().getOutputDirectory());
classpathElements.remove(project.getBuild().getOutputDirectory());
final File testOutputDirectory = new File(project.getBuild().getTestOutputDirectory());
classpathElements.remove(project.getBuild().getTestOutputDirectory());

if (outputDirectory.equals(classesDirectory)) { // Add again at start of the list classpathElements.add(0, outputDirectory.getAbsolutePath()); } else { getLog().debug( "Warning: changing classpath! " + outputDirectory.getAbsolutePath() + " != " + classesDirectory.getAbsolutePath()); classpathElements.add(0, classesDirectory.getAbsolutePath()); }

if (testOutputDirectory.equals(testClassesDirectory)) { // Add again at the very start of the list classpathElements.add(0, testOutputDirectory.getAbsolutePath()); } else { getLog().debug( "Warning: changing classpath! " + testOutputDirectory.getAbsolutePath() + " != " + testClassesDirectory.getAbsolutePath()); classpathElements.add(0, testClassesDirectory.getAbsolutePath()); }

Cheers
Markus

Show
M. Dahm added a comment - 01/Aug/08 2:38 AM the original code looks like this: getLog().debug("Test Classpath :"); // Check if we need to add configured classes/test classes directories here. // If they are configured, we should remove the default to avoid conflicts. // Check if we need to add configured classes/test classes directories here. // If they are configured, we should remove the default to avoid conflicts. if ( !project.getBuild().getOutputDirectory().equals( classesDirectory.getAbsolutePath() ) ) { getLog().debug( "Warning: changing classpath! " + project.getBuild().getOutputDirectory() + " != " + classesDirectory.getAbsolutePath() ); classpathElements.remove( project.getBuild().getOutputDirectory() ); classpathElements.add( classesDirectory.getAbsolutePath() ); } if ( !project.getBuild().getTestOutputDirectory().equals( testClassesDirectory.getAbsolutePath() ) ) { getLog().debug( "Warning: changing classpath! " + project.getBuild().getTestOutputDirectory() + " != " + testClassesDirectory.getAbsolutePath() ); classpathElements.remove( project.getBuild().getTestOutputDirectory() ); classpathElements.add( testClassesDirectory.getAbsolutePath() ); } However there are two problems here: 1.) In a Windows environment (which I'm forced to use ... the may be paths with mixed separators like C:\foo\bar/target/classes. This cause the above equals() to return false, also the paths may not be different actually. 2.) The order of the classes and the test-classes folder may be swapped if both if() apply I'd suggest the following code which uses Files to compare the paths and ensures that the test class path entry always comes first: getLog().debug("Test Classpath :"); // Check if we need to add configured classes/test classes directories here. // If they are configured, we should remove the default to avoid conflicts. // Ensure that test classes always come first final File outputDirectory = new File(project.getBuild().getOutputDirectory()); classpathElements.remove(project.getBuild().getOutputDirectory()); final File testOutputDirectory = new File(project.getBuild().getTestOutputDirectory()); classpathElements.remove(project.getBuild().getTestOutputDirectory()); if (outputDirectory.equals(classesDirectory)) { // Add again at start of the list classpathElements.add(0, outputDirectory.getAbsolutePath()); } else { getLog().debug( "Warning: changing classpath! " + outputDirectory.getAbsolutePath() + " != " + classesDirectory.getAbsolutePath()); classpathElements.add(0, classesDirectory.getAbsolutePath()); } if (testOutputDirectory.equals(testClassesDirectory)) { // Add again at the very start of the list classpathElements.add(0, testOutputDirectory.getAbsolutePath()); } else { getLog().debug( "Warning: changing classpath! " + testOutputDirectory.getAbsolutePath() + " != " + testClassesDirectory.getAbsolutePath()); classpathElements.add(0, testClassesDirectory.getAbsolutePath()); } Cheers Markus
Hide
Permalink
M. Dahm added a comment - 01/Aug/08 2:40 AM

Well, here comes the code in a more readable fashion...

Show
M. Dahm added a comment - 01/Aug/08 2:40 AM Well, here comes the code in a more readable fashion...
Hide
Permalink
Paul Gier added a comment - 20/Aug/09 2:18 PM

Fixed in r806311.

Show
Paul Gier added a comment - 20/Aug/09 2:18 PM Fixed in r806311.

People

  • Assignee:
    Paul Gier
    Reporter:
    James Shiell
Vote (1)
Watch (2)

Dates

  • Created:
    18/Jun/08 9:25 AM
    Updated:
    14/May/10 4:43 PM
    Resolved:
    20/Aug/09 2:18 PM
  • Atlassian JIRA (v5.0.4#731-sha1:3aa7374)
  • Report a problem
  • Powered by a free Atlassian JIRA open source license for Codehaus. Try JIRA - bug tracking software for your team.