Skip to content

Conversation

@jonvolfson
Copy link
Contributor

@khmarbaise
Copy link
Member

First please create an appropriate JIRA issue for that and describe the use case for this.

@jonvolfson jonvolfson changed the title Created new mojo GetClassesMojo which lists all class dependencies for a specified artifact. [MDEP-645] Created new mojo GetClassesMojo which lists all class dependencies for a specified artifact. May 26, 2020
@jonvolfson
Copy link
Contributor Author

Updated PR title. This is a fix for MDEP-645

*
* @since 2.7
*/
@Parameter( property = "mdep.skip", defaultValue = "false" )
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can remove all of the 'skip' processing; it's not terribly useful for a mojo intended for CLI.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bimargulies-google I'd keep it since you never know how it is used and maven does not control that

public ProjectBuildingRequest buildBuildingRequest()
throws MojoExecutionException, MojoFailureException
{
if ( coordinate.getArtifactId() == null && artifact == null )
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't use coordinate below. Are you missing an else clause? Is that the code that would run if someone used -DgroupId ... instead of -Dartifact?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. Removed the coordinate.getArtifactId() part. This was recycled code from the GetMojo with a similar use case.


for ( ArtifactResult result : artifacts )
{
printClassesFromArtifactResult( result );
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Print the file name of the jar before printing its contents if you are printing more than one jar file's worth?

setVariableValueToObject( mojo, "transitive", Boolean.FALSE );

mojo.execute();
return;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for return.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

setVariableValueToObject( mojo, "transitive", Boolean.TRUE );

mojo.execute();
return;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for return.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

return;
}

public void testGetClassesTransitive()
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Um, this does not seem to test anything except that it does not explode.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When listing classes for something like org.apache.maven:maven-model:2.0.9, setting -Dtransitive=true lists more classes than the false alternative. It's possible that the artifact used in the test has little/no transitive dependencies which means the results would be similar/the same.


// remove .class from the end and change format to use periods instead of forward slashes
name = name.substring( 0, name.length() - 6 ).replace( '/', '.' );
getLog().info( name );
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that using the log is the best delivery mechanism, but I could be confused. @elharo what do you think? Also, I have no idea how to test for log output, you'd need to mock the log somehow.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1, can be neat to be able to inject the list of classes in a maven project properties to reuse it downstream (exec-maven-plugin is my immediate thought but i'm sure there are more use cases). A dump in a file can be useful too.

side note: what about multi release jars (META-INF/versions)? should it be filtered?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think logging is how we usually do this. The log can be injected or tested.

…recycled code for building the ProjectBuildRequest


/**
* Retrieves and lists all class dependencies for the specified artifact from the specified remote repositories.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

class dependencies for --> "classes contained in" as these are not dependencies

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

* Retrieves and lists all class dependencies for the specified artifact from the specified remote repositories.
*/
@Mojo( name = "get-classes", requiresProject = false, threadSafe = true )
public class GetClassesMojo
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps ListClassesMojo?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

private DefaultDependableCoordinate coordinate = new DefaultDependableCoordinate();

/**
* The groupId of the artifact to download. Ignored if {@link #artifact} is used.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

group ID

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

private String groupId;

/**
* The artifactId of the artifact to download. Ignored if {@link #artifact} is used.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

artifact ID

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

* The packaging of the artifact to download. Ignored if {@link #artifact} is used.
*/
@Parameter( property = "packaging", defaultValue = "jar" )
private String packaging = "jar";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will this work for anything that's not a jar?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will work for a .war or any other 'renamed jar'. But the substitution of dots and slashes should perhaps be removed for non-.jar.

}

/**
* @param artifact The artifact
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doc comments begin with lower case, per Oracle guidelines

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More clarification? This is taken from the GetMojo.

}

/**
* @param artifactId The artifactId.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

artifact ID

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

import org.apache.maven.plugin.testing.stubs.MavenProjectStub;
import org.apache.maven.settings.Server;
import org.apache.maven.settings.Settings;
import org.sonatype.aether.impl.internal.SimpleLocalRepositoryManager;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tricky but can we replace this with org.eclipse equivalents? Probably not a 1:1 replacement.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you have an example to point at here?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not off the top of my head but try calling lookup(LocalRepositoryManager.class) in the setUp method and see if that returns an object that works.

public class TestGetClassesMojo
extends AbstractDependencyMojoTestCase
{
GetClassesMojo mojo;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

private

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

private is not allowed for this test class

super.setUp( "markers", false );

File testPom = new File( getBasedir(), "target/test-classes/unit/get-test/plugin-config.xml" );
assert testPom.exists();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NEVER use assert

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh, whoops, sorry I missed this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

…ansitive default value to false, changed ListClassesMojo methods to private if able, replaced assert in test case.
private String packaging = "jar";

/**
* Repositories in the format id::[layout]::url or just URLs, separated by comma. ie.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

avoid Latin. ie. --> That is,

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

return dependencyResolver;
}

protected ArtifactResolver getArtifactResolver()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you need this method?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed, removed this method and other getters that weren't needed

{
if ( isTransitive() )
{
Iterable<ArtifactResult> artifacts = getDependencyResolver()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can access fields like dependencyResolver directly. There's no need to use a getter method in the same class.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

public void execute() throws MojoExecutionException, MojoFailureException
{
ProjectBuildingRequest buildingRequest = buildBuildingRequest();
DefaultDependableCoordinate coordinate = getCoordinate();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't shadow the field here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

}
catch ( ArtifactResolverException | DependencyResolverException | IOException e )
{
throw new MojoExecutionException( "Couldn't download artifact: " + e.getMessage(), e );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exception message should contain coordinates of artifact it was trying to download

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

jarFile.close();
}

private ProjectBuildingRequest buildBuildingRequest()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

makeBuildingRequest?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

}

// remove .class from the end and change format to use periods instead of forward slashes
name = name.substring( 0, name.length() - 6 ).replace( '/', '.' );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

try to avoid reusing local variables. Here you have two things: an entry name and a class name, so two different variables make this clearer

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

}

/**
* @param artifact The artifact.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

…eract with the mojo, fixed comments to follow oracle javadoc guidelines, changes method names to be more descriptive of their purpose, fixed shadowing variable names and renamed variables to be more descriptive

/**
* Skip plugin execution completely.
*
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: remove blank line

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

}
catch ( ArtifactResolverException | DependencyResolverException | IOException e )
{
throw new MojoExecutionException( "Couldn't download artifact " + artifact + ": " + e.getMessage(), e );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This message might not be quite accurate when you're downloading all transitive dependencies. That is, it could be one of the transitive deps we can't download instead of the original.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the original message was correct before I changed it to include artifact. If a transitive dependency wasn't able to be resolved, e.getMessage() should have included the correct one.

String className = entryName.substring( 0, entryName.length() - 6 ).replace( '/', '.' );
getLog().info( className );
}
jarFile.close();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use try-with-resources to guarantee that this is closed when an exception is thrown

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

}

/**
* @return {@link #skip}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think you need these getter methods, and probably not the setters

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

public class TestGetClassesMojo
extends AbstractDependencyMojoTestCase
{
ListClassesMojo mojo;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make field private

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

…test class a private field, included printing logic to use a try-with-resource statement to guarantee JarFile closure, reverted thrown error message when resolving dependencies to original to be less confusing.
@elharo elharo merged commit e86cbe2 into apache:master Jun 17, 2020
pmoerenhout pushed a commit to pmoerenhout/maven-dependency-plugin that referenced this pull request Jun 18, 2020
…ndencies for a specified artifact. (apache#57)

* Created new mojo GetClassesMojo which lists all class dependencies for a specified artifact

* adding test file and fixing small function name

* Updating test functions names to be self-describing

* Fixing styling issues preventing build completion

* Removed return statements from test cases, removed unneeded piece of recycled code for building the ProjectBuildRequest

* Changed GetClassesMojo to ListClassesMojo, fixed comments, changed transitive default value to false, changed ListClassesMojo methods to private if able, replaced assert in test case.

* Changed modifying methods to private since outside classes do not interact with the mojo, fixed comments to follow oracle javadoc guidelines, changes method names to be more descriptive of their purpose, fixed shadowing variable names and renamed variables to be more descriptive

* Removed unneccessary setter and getter methods, made the mojo in the test class a private field, included printing logic to use a try-with-resource statement to guarantee JarFile closure, reverted thrown error message when resolving dependencies to original to be less confusing.
cosmin pushed a commit to cosmin/maven-dependency-plugin that referenced this pull request Nov 24, 2020
…ndencies for a specified artifact. (apache#57)

* Created new mojo GetClassesMojo which lists all class dependencies for a specified artifact

* adding test file and fixing small function name

* Updating test functions names to be self-describing

* Fixing styling issues preventing build completion

* Removed return statements from test cases, removed unneeded piece of recycled code for building the ProjectBuildRequest

* Changed GetClassesMojo to ListClassesMojo, fixed comments, changed transitive default value to false, changed ListClassesMojo methods to private if able, replaced assert in test case.

* Changed modifying methods to private since outside classes do not interact with the mojo, fixed comments to follow oracle javadoc guidelines, changes method names to be more descriptive of their purpose, fixed shadowing variable names and renamed variables to be more descriptive

* Removed unneccessary setter and getter methods, made the mojo in the test class a private field, included printing logic to use a try-with-resource statement to guarantee JarFile closure, reverted thrown error message when resolving dependencies to original to be less confusing.
@jira-importer
Copy link

Resolve #1075

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants