From ad9a74a3d31b521fea0903ce2284a6e3a7450ef6 Mon Sep 17 00:00:00 2001 From: jonvolfson Date: Tue, 26 May 2020 11:05:15 -0400 Subject: [PATCH 1/8] Created new mojo GetClassesMojo which lists all class dependencies for a specified artifact --- .../plugins/dependency/GetClassesMojo.java | 396 ++++++++++++++++++ 1 file changed, 396 insertions(+) create mode 100644 src/main/java/org/apache/maven/plugins/dependency/GetClassesMojo.java diff --git a/src/main/java/org/apache/maven/plugins/dependency/GetClassesMojo.java b/src/main/java/org/apache/maven/plugins/dependency/GetClassesMojo.java new file mode 100644 index 000000000..d87236880 --- /dev/null +++ b/src/main/java/org/apache/maven/plugins/dependency/GetClassesMojo.java @@ -0,0 +1,396 @@ +package org.apache.maven.plugins.dependency; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; +import java.util.Map; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.maven.artifact.handler.ArtifactHandler; +import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager; +import org.apache.maven.artifact.repository.ArtifactRepository; +import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy; +import org.apache.maven.artifact.repository.MavenArtifactRepository; +import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout; +import org.apache.maven.execution.MavenSession; +import org.apache.maven.plugin.AbstractMojo; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugins.annotations.Component; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; +import org.apache.maven.project.DefaultProjectBuildingRequest; +import org.apache.maven.project.ProjectBuildingRequest; +import org.apache.maven.repository.RepositorySystem; +import org.apache.maven.settings.Settings; +import org.apache.maven.shared.transfer.artifact.ArtifactCoordinate; +import org.apache.maven.shared.transfer.artifact.DefaultArtifactCoordinate; +import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResolver; +import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResolverException; +import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResult; +import org.apache.maven.shared.transfer.dependencies.DefaultDependableCoordinate; +import org.apache.maven.shared.transfer.dependencies.DependableCoordinate; +import org.apache.maven.shared.transfer.dependencies.resolve.DependencyResolver; +import org.apache.maven.shared.transfer.dependencies.resolve.DependencyResolverException; +import org.codehaus.plexus.util.StringUtils; + +@Mojo( name = "get-classes", requiresProject = false, threadSafe = true ) +public class GetClassesMojo + extends AbstractMojo +{ + private static final Pattern ALT_REPO_SYNTAX_PATTERN = Pattern.compile( "(.+)::(.*)::(.+)" ); + + @Parameter( defaultValue = "${session}", required = true, readonly = true ) + private MavenSession session; + + @Component + private ArtifactResolver artifactResolver; + + @Component + private DependencyResolver dependencyResolver; + + @Component + private ArtifactHandlerManager artifactHandlerManager; + + /** + * Map that contains the layouts. + */ + @Component( role = ArtifactRepositoryLayout.class ) + private Map repositoryLayouts; + + /** + * The repository system. + */ + @Component + private RepositorySystem repositorySystem; + + private DefaultDependableCoordinate coordinate = new DefaultDependableCoordinate(); + + /** + * The groupId of the artifact to download. Ignored if {@link #artifact} is used. + */ + @Parameter( property = "groupId" ) + private String groupId; + + /** + * The artifactId of the artifact to download. Ignored if {@link #artifact} is used. + */ + @Parameter( property = "artifactId" ) + private String artifactId; + + /** + * The version of the artifact to download. Ignored if {@link #artifact} is used. + */ + @Parameter( property = "version" ) + private String version; + + /** + * The classifier of the artifact to download. Ignored if {@link #artifact} is used. + * + * @since 2.3 + */ + @Parameter( property = "classifier" ) + private String classifier; + + /** + * The packaging of the artifact to download. Ignored if {@link #artifact} is used. + */ + @Parameter( property = "packaging", defaultValue = "jar" ) + private String packaging = "jar"; + + /** + * Repositories in the format id::[layout]::url or just url, separated by comma. ie. + * central::default::https://repo.maven.apache.org/maven2,myrepo::::https://repo.acme.com,https://repo.acme2.com + */ + @Parameter( property = "remoteRepositories" ) + private String remoteRepositories; + + /** + * A string of the form groupId:artifactId:version[:packaging[:classifier]]. + */ + @Parameter( property = "artifact" ) + private String artifact; + + @Parameter( defaultValue = "${project.remoteArtifactRepositories}", readonly = true, required = true ) + private List pomRemoteRepositories; + + /** + * Download transitively, retrieving the specified artifact and all of its dependencies. + */ + @Parameter( property = "transitive", defaultValue = "true" ) + private boolean transitive = true; + + /** + * Skip plugin execution completely. + * + * @since 2.7 + */ + @Parameter( property = "mdep.skip", defaultValue = "false" ) + private boolean skip; + + @Override + public void execute() throws MojoExecutionException, MojoFailureException + { + ProjectBuildingRequest buildingRequest = buildBuildingRequest(); + DefaultDependableCoordinate coordinate = getCoordinate(); + + try + { + getLog().info( "Retrieving classes of dependencies for " + artifact ); + if ( isTransitive() ) + { + Iterable artifacts = getDependencyResolver().resolveDependencies( buildingRequest, coordinate, null ); + + for ( ArtifactResult result : artifacts ) + { + PrintClassesFromArtifactResult( result ); + } + } + else + { + ArtifactResult result = getArtifactResolver().resolveArtifact( buildingRequest, toArtifactCoordinate( coordinate ) ); + + PrintClassesFromArtifactResult( result ); + } + } + catch ( ArtifactResolverException | DependencyResolverException | IOException e ) + { + throw new MojoExecutionException( "Couldn't download artifact: " + e.getMessage(), e ); + } + } + + public void PrintClassesFromArtifactResult( ArtifactResult result ) + throws IOException + { + JarFile jarFile = new JarFile( result.getArtifact().getFile() ); + Enumeration e = jarFile.entries(); + + while ( e.hasMoreElements() ) + { + JarEntry entry = ( JarEntry )e.nextElement(); + String name = entry.getName(); + + // filter out files that do not end in .class + if ( name.length() <= 6 || !name.substring( name.length() - 6 ).equals( ".class" )) { + continue; + } + + // 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 ); + } + jarFile.close(); + } + + public ProjectBuildingRequest buildBuildingRequest() + throws MojoExecutionException, MojoFailureException + { + if ( coordinate.getArtifactId() == null && artifact == null ) + { + throw new MojoFailureException( "You must specify an artifact, " + + "e.g. -Dartifact=org.apache.maven.plugins:maven-downloader-plugin:1.0" ); + } + if ( artifact != null ) + { + String[] tokens = StringUtils.split( artifact, ":" ); + if ( tokens.length < 3 || tokens.length > 5 ) + { + throw new MojoFailureException( "Invalid artifact, you must specify " + + "groupId:artifactId:version[:packaging[:classifier]] " + artifact ); + } + coordinate.setGroupId( tokens[0] ); + coordinate.setArtifactId( tokens[1] ); + coordinate.setVersion( tokens[2] ); + if ( tokens.length >= 4 ) + { + coordinate.setType( tokens[3] ); + } + if ( tokens.length == 5 ) + { + coordinate.setClassifier( tokens[4] ); + } + } + + ArtifactRepositoryPolicy always = + new ArtifactRepositoryPolicy( true, ArtifactRepositoryPolicy.UPDATE_POLICY_ALWAYS, + ArtifactRepositoryPolicy.CHECKSUM_POLICY_WARN ); + + List repoList = new ArrayList<>(); + + if ( pomRemoteRepositories != null ) + { + repoList.addAll( pomRemoteRepositories ); + } + + if ( remoteRepositories != null ) + { + // Use the same format as in the deploy plugin id::layout::url + String[] repos = StringUtils.split( remoteRepositories, "," ); + for ( String repo : repos ) + { + repoList.add( parseRepository( repo, always ) ); + } + } + + ProjectBuildingRequest buildingRequest = + new DefaultProjectBuildingRequest( session.getProjectBuildingRequest() ); + + Settings settings = session.getSettings(); + repositorySystem.injectMirror( repoList, settings.getMirrors() ); + repositorySystem.injectProxy( repoList, settings.getProxies() ); + repositorySystem.injectAuthentication( repoList, settings.getServers() ); + + buildingRequest.setRemoteRepositories( repoList ); + + return buildingRequest; + } + + protected ArtifactCoordinate toArtifactCoordinate(DependableCoordinate dependableCoordinate ) + { + ArtifactHandler artifactHandler = artifactHandlerManager.getArtifactHandler( dependableCoordinate.getType() ); + DefaultArtifactCoordinate artifactCoordinate = new DefaultArtifactCoordinate(); + artifactCoordinate.setGroupId( dependableCoordinate.getGroupId() ); + artifactCoordinate.setArtifactId( dependableCoordinate.getArtifactId() ); + artifactCoordinate.setVersion( dependableCoordinate.getVersion() ); + artifactCoordinate.setClassifier( dependableCoordinate.getClassifier() ); + artifactCoordinate.setExtension( artifactHandler.getExtension() ); + return artifactCoordinate; + } + + ArtifactRepository parseRepository( String repo, ArtifactRepositoryPolicy policy ) + throws MojoFailureException + { + // if it's a simple url + String id = "temp"; + ArtifactRepositoryLayout layout = getLayout( "default" ); + String url = repo; + + // if it's an extended repo URL of the form id::layout::url + if ( repo.contains( "::" ) ) + { + Matcher matcher = ALT_REPO_SYNTAX_PATTERN.matcher( repo ); + if ( !matcher.matches() ) + { + throw new MojoFailureException( repo, "Invalid syntax for repository: " + repo, + "Invalid syntax for repository. Use \"id::layout::url\" or \"URL\"." ); + } + + id = matcher.group( 1 ).trim(); + if ( !StringUtils.isEmpty( matcher.group( 2 ) ) ) + { + layout = getLayout( matcher.group( 2 ).trim() ); + } + url = matcher.group( 3 ).trim(); + } + return new MavenArtifactRepository( id, url, layout, policy, policy ); + } + + private ArtifactRepositoryLayout getLayout( String id ) + throws MojoFailureException + { + ArtifactRepositoryLayout layout = repositoryLayouts.get( id ); + + if ( layout == null ) + { + throw new MojoFailureException( id, "Invalid repository layout", "Invalid repository layout: " + id ); + } + + return layout; + } + + /** + * @return {@link #skip} + */ + protected boolean isSkip() + { + return skip; + } + + protected boolean isTransitive() + { + return transitive; + } + + protected DefaultDependableCoordinate getCoordinate() + { + return coordinate; + } + + protected DependencyResolver getDependencyResolver() + { + return dependencyResolver; + } + + protected ArtifactResolver getArtifactResolver() + { + return artifactResolver; + } + + /** + * @param artifact The artifact + */ + public void setArtifact( String artifact ) { this.artifact = artifact; } + + /** + * @param groupId The groupId. + */ + public void setGroupId( String groupId ) + { + this.coordinate.setGroupId( groupId ); + } + + /** + * @param artifactId The artifactId. + */ + public void setArtifactId( String artifactId ) + { + this.coordinate.setArtifactId( artifactId ); + } + + /** + * @param version The version. + */ + public void setVersion( String version ) + { + this.coordinate.setVersion( version ); + } + + /** + * @param classifier The classifier to be used. + */ + public void setClassifier( String classifier ) + { + this.coordinate.setClassifier( classifier ); + } + + /** + * @param type packaging. + */ + public void setPackaging( String type ) + { + this.coordinate.setType( type ); + } +} From 3cf44ac3a6d9779ec272b76b27657f30fcadebc1 Mon Sep 17 00:00:00 2001 From: jonvolfson Date: Tue, 26 May 2020 11:09:16 -0400 Subject: [PATCH 2/8] adding test file and fixing small function name --- .../plugins/dependency/GetClassesMojo.java | 6 +- .../dependency/TestGetClassesMojo.java | 88 +++++++++++++++++++ 2 files changed, 91 insertions(+), 3 deletions(-) create mode 100644 src/test/java/org/apache/maven/plugins/dependency/TestGetClassesMojo.java diff --git a/src/main/java/org/apache/maven/plugins/dependency/GetClassesMojo.java b/src/main/java/org/apache/maven/plugins/dependency/GetClassesMojo.java index d87236880..e346953ce 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/GetClassesMojo.java +++ b/src/main/java/org/apache/maven/plugins/dependency/GetClassesMojo.java @@ -166,14 +166,14 @@ public void execute() throws MojoExecutionException, MojoFailureException for ( ArtifactResult result : artifacts ) { - PrintClassesFromArtifactResult( result ); + printClassesFromArtifactResult( result ); } } else { ArtifactResult result = getArtifactResolver().resolveArtifact( buildingRequest, toArtifactCoordinate( coordinate ) ); - PrintClassesFromArtifactResult( result ); + printClassesFromArtifactResult( result ); } } catch ( ArtifactResolverException | DependencyResolverException | IOException e ) @@ -182,7 +182,7 @@ public void execute() throws MojoExecutionException, MojoFailureException } } - public void PrintClassesFromArtifactResult( ArtifactResult result ) + public void printClassesFromArtifactResult( ArtifactResult result ) throws IOException { JarFile jarFile = new JarFile( result.getArtifact().getFile() ); diff --git a/src/test/java/org/apache/maven/plugins/dependency/TestGetClassesMojo.java b/src/test/java/org/apache/maven/plugins/dependency/TestGetClassesMojo.java new file mode 100644 index 000000000..c41433f69 --- /dev/null +++ b/src/test/java/org/apache/maven/plugins/dependency/TestGetClassesMojo.java @@ -0,0 +1,88 @@ +package org.apache.maven.plugins.dependency; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import org.apache.maven.execution.MavenSession; +import org.apache.maven.plugin.LegacySupport; +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; +import org.sonatype.aether.util.DefaultRepositorySystemSession; + +import java.io.File; + +public class TestGetClassesMojo + extends AbstractDependencyMojoTestCase +{ + GetClassesMojo mojo; + + protected void setUp() + throws Exception + { + // required for mojo lookups to work + super.setUp( "markers", false ); + + File testPom = new File( getBasedir(), "target/test-classes/unit/get-test/plugin-config.xml" ); + assert testPom.exists(); + mojo = (GetClassesMojo) lookupMojo( "get-classes", testPom ); + + assertNotNull( mojo ); + + LegacySupport legacySupport = lookup( LegacySupport.class ); + MavenSession session = newMavenSession( new MavenProjectStub() ); + Settings settings = session.getSettings(); + Server server = new Server(); + server.setId( "myserver" ); + server.setUsername( "foo" ); + server.setPassword( "bar" ); + settings.addServer( server ); + legacySupport.setSession( session ); + DefaultRepositorySystemSession repoSession = + (DefaultRepositorySystemSession) legacySupport.getRepositorySession(); + repoSession.setLocalRepositoryManager( new SimpleLocalRepositoryManager( testDir.getAbsolutePath() ) ); + + setVariableValueToObject( mojo, "session", legacySupport.getSession() ); + } + + public void test2() + throws Exception + { + setVariableValueToObject( mojo, "remoteRepositories", "central::default::https://repo.maven.apache.org/maven2," + + "central::::https://repo.maven.apache.org/maven2," + "https://repo.maven.apache.org/maven2" ); + mojo.setArtifact("org.apache.commons:commons-lang3:3.6"); + setVariableValueToObject( mojo, "transitive", Boolean.FALSE ); + + mojo.execute(); + return; + } + + public void test4() + throws Exception + { + setVariableValueToObject( mojo, "remoteRepositories", "central::default::https://repo.maven.apache.org/maven2," + + "central::::https://repo.maven.apache.org/maven2," + "https://repo.maven.apache.org/maven2" ); + mojo.setArtifact("org.apache.commons:commons-lang3:3.6"); + setVariableValueToObject( mojo, "transitive", Boolean.TRUE ); + + mojo.execute(); + return; + } +} From 1ae2324d645297899852350cc11d7c23cf68481c Mon Sep 17 00:00:00 2001 From: jonvolfson Date: Tue, 26 May 2020 11:10:28 -0400 Subject: [PATCH 3/8] Updating test functions names to be self-describing --- .../apache/maven/plugins/dependency/TestGetClassesMojo.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/org/apache/maven/plugins/dependency/TestGetClassesMojo.java b/src/test/java/org/apache/maven/plugins/dependency/TestGetClassesMojo.java index c41433f69..39577c0c6 100644 --- a/src/test/java/org/apache/maven/plugins/dependency/TestGetClassesMojo.java +++ b/src/test/java/org/apache/maven/plugins/dependency/TestGetClassesMojo.java @@ -62,7 +62,7 @@ protected void setUp() setVariableValueToObject( mojo, "session", legacySupport.getSession() ); } - public void test2() + public void testGetClassesNotTransitive() throws Exception { setVariableValueToObject( mojo, "remoteRepositories", "central::default::https://repo.maven.apache.org/maven2," @@ -74,7 +74,7 @@ public void test2() return; } - public void test4() + public void testGetClassesTransitive() throws Exception { setVariableValueToObject( mojo, "remoteRepositories", "central::default::https://repo.maven.apache.org/maven2," From 71000a70e819b277a001a2ac31a63d65f6c24f3a Mon Sep 17 00:00:00 2001 From: jonvolfson Date: Tue, 26 May 2020 11:34:42 -0400 Subject: [PATCH 4/8] Fixing styling issues preventing build completion --- .../plugins/dependency/GetClassesMojo.java | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/apache/maven/plugins/dependency/GetClassesMojo.java b/src/main/java/org/apache/maven/plugins/dependency/GetClassesMojo.java index e346953ce..2ab6e98f9 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/GetClassesMojo.java +++ b/src/main/java/org/apache/maven/plugins/dependency/GetClassesMojo.java @@ -57,6 +57,10 @@ import org.apache.maven.shared.transfer.dependencies.resolve.DependencyResolverException; import org.codehaus.plexus.util.StringUtils; + +/** + * 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 extends AbstractMojo @@ -162,7 +166,8 @@ public void execute() throws MojoExecutionException, MojoFailureException getLog().info( "Retrieving classes of dependencies for " + artifact ); if ( isTransitive() ) { - Iterable artifacts = getDependencyResolver().resolveDependencies( buildingRequest, coordinate, null ); + Iterable artifacts = getDependencyResolver() + .resolveDependencies( buildingRequest, coordinate, null ); for ( ArtifactResult result : artifacts ) { @@ -171,7 +176,8 @@ public void execute() throws MojoExecutionException, MojoFailureException } else { - ArtifactResult result = getArtifactResolver().resolveArtifact( buildingRequest, toArtifactCoordinate( coordinate ) ); + ArtifactResult result = getArtifactResolver() + .resolveArtifact( buildingRequest, toArtifactCoordinate( coordinate ) ); printClassesFromArtifactResult( result ); } @@ -190,11 +196,12 @@ public void printClassesFromArtifactResult( ArtifactResult result ) while ( e.hasMoreElements() ) { - JarEntry entry = ( JarEntry )e.nextElement(); + JarEntry entry = (JarEntry) e.nextElement(); String name = entry.getName(); // filter out files that do not end in .class - if ( name.length() <= 6 || !name.substring( name.length() - 6 ).equals( ".class" )) { + if ( name.length() <= 6 || !name.substring( name.length() - 6 ).equals( ".class" ) ) + { continue; } @@ -268,7 +275,7 @@ public ProjectBuildingRequest buildBuildingRequest() return buildingRequest; } - protected ArtifactCoordinate toArtifactCoordinate(DependableCoordinate dependableCoordinate ) + protected ArtifactCoordinate toArtifactCoordinate( DependableCoordinate dependableCoordinate ) { ArtifactHandler artifactHandler = artifactHandlerManager.getArtifactHandler( dependableCoordinate.getType() ); DefaultArtifactCoordinate artifactCoordinate = new DefaultArtifactCoordinate(); @@ -352,7 +359,10 @@ protected ArtifactResolver getArtifactResolver() /** * @param artifact The artifact */ - public void setArtifact( String artifact ) { this.artifact = artifact; } + public void setArtifact( String artifact ) + { + this.artifact = artifact; + } /** * @param groupId The groupId. From 45cc37305cd28dbc8e6b880036df2e1830a8d1cc Mon Sep 17 00:00:00 2001 From: jonvolfson Date: Tue, 26 May 2020 12:01:45 -0400 Subject: [PATCH 5/8] Removed return statements from test cases, removed unneeded piece of recycled code for building the ProjectBuildRequest --- .../org/apache/maven/plugins/dependency/GetClassesMojo.java | 2 +- .../org/apache/maven/plugins/dependency/TestGetClassesMojo.java | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/org/apache/maven/plugins/dependency/GetClassesMojo.java b/src/main/java/org/apache/maven/plugins/dependency/GetClassesMojo.java index 2ab6e98f9..54ca22b1f 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/GetClassesMojo.java +++ b/src/main/java/org/apache/maven/plugins/dependency/GetClassesMojo.java @@ -215,7 +215,7 @@ public void printClassesFromArtifactResult( ArtifactResult result ) public ProjectBuildingRequest buildBuildingRequest() throws MojoExecutionException, MojoFailureException { - if ( coordinate.getArtifactId() == null && artifact == null ) + if ( artifact == null ) { throw new MojoFailureException( "You must specify an artifact, " + "e.g. -Dartifact=org.apache.maven.plugins:maven-downloader-plugin:1.0" ); diff --git a/src/test/java/org/apache/maven/plugins/dependency/TestGetClassesMojo.java b/src/test/java/org/apache/maven/plugins/dependency/TestGetClassesMojo.java index 39577c0c6..18c707432 100644 --- a/src/test/java/org/apache/maven/plugins/dependency/TestGetClassesMojo.java +++ b/src/test/java/org/apache/maven/plugins/dependency/TestGetClassesMojo.java @@ -71,7 +71,6 @@ public void testGetClassesNotTransitive() setVariableValueToObject( mojo, "transitive", Boolean.FALSE ); mojo.execute(); - return; } public void testGetClassesTransitive() @@ -83,6 +82,5 @@ public void testGetClassesTransitive() setVariableValueToObject( mojo, "transitive", Boolean.TRUE ); mojo.execute(); - return; } } From 8eae2544d33ecc8029aa8c4d523f9c2f2a458444 Mon Sep 17 00:00:00 2001 From: jonvolfson Date: Tue, 26 May 2020 14:13:52 -0400 Subject: [PATCH 6/8] Changed GetClassesMojo to ListClassesMojo, fixed comments, changed transitive default value to false, changed ListClassesMojo methods to private if able, replaced assert in test case. --- ...tClassesMojo.java => ListClassesMojo.java} | 48 +++++++++---------- .../dependency/TestGetClassesMojo.java | 7 +-- 2 files changed, 26 insertions(+), 29 deletions(-) rename src/main/java/org/apache/maven/plugins/dependency/{GetClassesMojo.java => ListClassesMojo.java} (88%) diff --git a/src/main/java/org/apache/maven/plugins/dependency/GetClassesMojo.java b/src/main/java/org/apache/maven/plugins/dependency/ListClassesMojo.java similarity index 88% rename from src/main/java/org/apache/maven/plugins/dependency/GetClassesMojo.java rename to src/main/java/org/apache/maven/plugins/dependency/ListClassesMojo.java index 54ca22b1f..0c8c1fd33 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/GetClassesMojo.java +++ b/src/main/java/org/apache/maven/plugins/dependency/ListClassesMojo.java @@ -55,14 +55,13 @@ import org.apache.maven.shared.transfer.dependencies.DependableCoordinate; import org.apache.maven.shared.transfer.dependencies.resolve.DependencyResolver; import org.apache.maven.shared.transfer.dependencies.resolve.DependencyResolverException; -import org.codehaus.plexus.util.StringUtils; /** - * Retrieves and lists all class dependencies for the specified artifact from the specified remote repositories. + * Retrieves and lists all classes contained in the specified artifact from the specified remote repositories. */ -@Mojo( name = "get-classes", requiresProject = false, threadSafe = true ) -public class GetClassesMojo +@Mojo( name = "list-classes", requiresProject = false, threadSafe = true ) +public class ListClassesMojo extends AbstractMojo { private static final Pattern ALT_REPO_SYNTAX_PATTERN = Pattern.compile( "(.+)::(.*)::(.+)" ); @@ -94,13 +93,13 @@ public class GetClassesMojo private DefaultDependableCoordinate coordinate = new DefaultDependableCoordinate(); /** - * The groupId of the artifact to download. Ignored if {@link #artifact} is used. + * The group ID of the artifact to download. Ignored if {@link #artifact} is used. */ @Parameter( property = "groupId" ) private String groupId; /** - * The artifactId of the artifact to download. Ignored if {@link #artifact} is used. + * The artifact ID of the artifact to download. Ignored if {@link #artifact} is used. */ @Parameter( property = "artifactId" ) private String artifactId; @@ -126,7 +125,7 @@ public class GetClassesMojo private String packaging = "jar"; /** - * Repositories in the format id::[layout]::url or just url, separated by comma. ie. + * Repositories in the format id::[layout]::url or just URLs, separated by comma. ie. * central::default::https://repo.maven.apache.org/maven2,myrepo::::https://repo.acme.com,https://repo.acme2.com */ @Parameter( property = "remoteRepositories" ) @@ -144,13 +143,12 @@ public class GetClassesMojo /** * Download transitively, retrieving the specified artifact and all of its dependencies. */ - @Parameter( property = "transitive", defaultValue = "true" ) - private boolean transitive = true; + @Parameter( property = "transitive", defaultValue = "false" ) + private boolean transitive = false; /** * Skip plugin execution completely. * - * @since 2.7 */ @Parameter( property = "mdep.skip", defaultValue = "false" ) private boolean skip; @@ -163,7 +161,6 @@ public void execute() throws MojoExecutionException, MojoFailureException try { - getLog().info( "Retrieving classes of dependencies for " + artifact ); if ( isTransitive() ) { Iterable artifacts = getDependencyResolver() @@ -188,19 +185,19 @@ public void execute() throws MojoExecutionException, MojoFailureException } } - public void printClassesFromArtifactResult( ArtifactResult result ) + private void printClassesFromArtifactResult( ArtifactResult result ) throws IOException { JarFile jarFile = new JarFile( result.getArtifact().getFile() ); - Enumeration e = jarFile.entries(); + Enumeration entries = jarFile.entries(); - while ( e.hasMoreElements() ) + while ( entries.hasMoreElements() ) { - JarEntry entry = (JarEntry) e.nextElement(); + JarEntry entry = (JarEntry) entries.nextElement(); String name = entry.getName(); // filter out files that do not end in .class - if ( name.length() <= 6 || !name.substring( name.length() - 6 ).equals( ".class" ) ) + if ( !name.endsWith( ".class" ) ) { continue; } @@ -212,7 +209,7 @@ public void printClassesFromArtifactResult( ArtifactResult result ) jarFile.close(); } - public ProjectBuildingRequest buildBuildingRequest() + private ProjectBuildingRequest buildBuildingRequest() throws MojoExecutionException, MojoFailureException { if ( artifact == null ) @@ -222,7 +219,7 @@ public ProjectBuildingRequest buildBuildingRequest() } if ( artifact != null ) { - String[] tokens = StringUtils.split( artifact, ":" ); + String[] tokens = artifact.split( ":" ); if ( tokens.length < 3 || tokens.length > 5 ) { throw new MojoFailureException( "Invalid artifact, you must specify " @@ -255,7 +252,7 @@ public ProjectBuildingRequest buildBuildingRequest() if ( remoteRepositories != null ) { // Use the same format as in the deploy plugin id::layout::url - String[] repos = StringUtils.split( remoteRepositories, "," ); + String[] repos = remoteRepositories.split( "," ); for ( String repo : repos ) { repoList.add( parseRepository( repo, always ) ); @@ -293,7 +290,6 @@ ArtifactRepository parseRepository( String repo, ArtifactRepositoryPolicy policy // if it's a simple url String id = "temp"; ArtifactRepositoryLayout layout = getLayout( "default" ); - String url = repo; // if it's an extended repo URL of the form id::layout::url if ( repo.contains( "::" ) ) @@ -306,13 +302,13 @@ ArtifactRepository parseRepository( String repo, ArtifactRepositoryPolicy policy } id = matcher.group( 1 ).trim(); - if ( !StringUtils.isEmpty( matcher.group( 2 ) ) ) + if ( !( matcher.group( 2 ) == null || matcher.group( 2 ).trim().isEmpty() ) ) { layout = getLayout( matcher.group( 2 ).trim() ); } - url = matcher.group( 3 ).trim(); + repo = matcher.group( 3 ).trim(); } - return new MavenArtifactRepository( id, url, layout, policy, policy ); + return new MavenArtifactRepository( id, repo, layout, policy, policy ); } private ArtifactRepositoryLayout getLayout( String id ) @@ -357,7 +353,7 @@ protected ArtifactResolver getArtifactResolver() } /** - * @param artifact The artifact + * @param artifact The artifact. */ public void setArtifact( String artifact ) { @@ -365,7 +361,7 @@ public void setArtifact( String artifact ) } /** - * @param groupId The groupId. + * @param groupId The group ID. */ public void setGroupId( String groupId ) { @@ -373,7 +369,7 @@ public void setGroupId( String groupId ) } /** - * @param artifactId The artifactId. + * @param artifactId The artifact ID. */ public void setArtifactId( String artifactId ) { diff --git a/src/test/java/org/apache/maven/plugins/dependency/TestGetClassesMojo.java b/src/test/java/org/apache/maven/plugins/dependency/TestGetClassesMojo.java index 18c707432..af50ae223 100644 --- a/src/test/java/org/apache/maven/plugins/dependency/TestGetClassesMojo.java +++ b/src/test/java/org/apache/maven/plugins/dependency/TestGetClassesMojo.java @@ -24,6 +24,7 @@ import org.apache.maven.plugin.testing.stubs.MavenProjectStub; import org.apache.maven.settings.Server; import org.apache.maven.settings.Settings; +import org.junit.Assert; import org.sonatype.aether.impl.internal.SimpleLocalRepositoryManager; import org.sonatype.aether.util.DefaultRepositorySystemSession; @@ -32,7 +33,7 @@ public class TestGetClassesMojo extends AbstractDependencyMojoTestCase { - GetClassesMojo mojo; + ListClassesMojo mojo; protected void setUp() throws Exception @@ -41,8 +42,8 @@ protected void setUp() super.setUp( "markers", false ); File testPom = new File( getBasedir(), "target/test-classes/unit/get-test/plugin-config.xml" ); - assert testPom.exists(); - mojo = (GetClassesMojo) lookupMojo( "get-classes", testPom ); + assertTrue(testPom.exists()); + mojo = (ListClassesMojo) lookupMojo( "list-classes", testPom ); assertNotNull( mojo ); From 44330b92c118e03fa9412c6700c9bd87da82f950 Mon Sep 17 00:00:00 2001 From: jonvolfson Date: Wed, 27 May 2020 12:26:40 -0400 Subject: [PATCH 7/8] 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 --- .../plugins/dependency/ListClassesMojo.java | 55 ++++++++----------- 1 file changed, 22 insertions(+), 33 deletions(-) diff --git a/src/main/java/org/apache/maven/plugins/dependency/ListClassesMojo.java b/src/main/java/org/apache/maven/plugins/dependency/ListClassesMojo.java index 0c8c1fd33..65caea533 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/ListClassesMojo.java +++ b/src/main/java/org/apache/maven/plugins/dependency/ListClassesMojo.java @@ -125,7 +125,7 @@ public class ListClassesMojo private String packaging = "jar"; /** - * Repositories in the format id::[layout]::url or just URLs, separated by comma. ie. + * Repositories in the format id::[layout]::url or just URLs, separated by comma. That is, * central::default::https://repo.maven.apache.org/maven2,myrepo::::https://repo.acme.com,https://repo.acme2.com */ @Parameter( property = "remoteRepositories" ) @@ -156,14 +156,13 @@ public class ListClassesMojo @Override public void execute() throws MojoExecutionException, MojoFailureException { - ProjectBuildingRequest buildingRequest = buildBuildingRequest(); - DefaultDependableCoordinate coordinate = getCoordinate(); + ProjectBuildingRequest buildingRequest = makeBuildingRequest(); try { if ( isTransitive() ) { - Iterable artifacts = getDependencyResolver() + Iterable artifacts = dependencyResolver .resolveDependencies( buildingRequest, coordinate, null ); for ( ArtifactResult result : artifacts ) @@ -173,7 +172,7 @@ public void execute() throws MojoExecutionException, MojoFailureException } else { - ArtifactResult result = getArtifactResolver() + ArtifactResult result = artifactResolver .resolveArtifact( buildingRequest, toArtifactCoordinate( coordinate ) ); printClassesFromArtifactResult( result ); @@ -181,7 +180,7 @@ public void execute() throws MojoExecutionException, MojoFailureException } catch ( ArtifactResolverException | DependencyResolverException | IOException e ) { - throw new MojoExecutionException( "Couldn't download artifact: " + e.getMessage(), e ); + throw new MojoExecutionException( "Couldn't download artifact " + artifact + ": " + e.getMessage(), e ); } } @@ -194,22 +193,22 @@ private void printClassesFromArtifactResult( ArtifactResult result ) while ( entries.hasMoreElements() ) { JarEntry entry = (JarEntry) entries.nextElement(); - String name = entry.getName(); + String entryName = entry.getName(); // filter out files that do not end in .class - if ( !name.endsWith( ".class" ) ) + if ( !entryName.endsWith( ".class" ) ) { continue; } // 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 ); + String className = entryName.substring( 0, entryName.length() - 6 ).replace( '/', '.' ); + getLog().info( className ); } jarFile.close(); } - private ProjectBuildingRequest buildBuildingRequest() + private ProjectBuildingRequest makeBuildingRequest() throws MojoExecutionException, MojoFailureException { if ( artifact == null ) @@ -342,60 +341,50 @@ protected DefaultDependableCoordinate getCoordinate() return coordinate; } - protected DependencyResolver getDependencyResolver() - { - return dependencyResolver; - } - - protected ArtifactResolver getArtifactResolver() - { - return artifactResolver; - } - /** - * @param artifact The artifact. + * @param artifact the artifact */ - public void setArtifact( String artifact ) + protected void setArtifact( String artifact ) { this.artifact = artifact; } /** - * @param groupId The group ID. + * @param groupId the group ID */ - public void setGroupId( String groupId ) + protected void setGroupId( String groupId ) { this.coordinate.setGroupId( groupId ); } /** - * @param artifactId The artifact ID. + * @param artifactId the artifact ID */ - public void setArtifactId( String artifactId ) + protected void setArtifactId( String artifactId ) { this.coordinate.setArtifactId( artifactId ); } /** - * @param version The version. + * @param version the version */ - public void setVersion( String version ) + protected void setVersion( String version ) { this.coordinate.setVersion( version ); } /** - * @param classifier The classifier to be used. + * @param classifier the classifier to be used */ - public void setClassifier( String classifier ) + protected void setClassifier( String classifier ) { this.coordinate.setClassifier( classifier ); } /** - * @param type packaging. + * @param type the packaging */ - public void setPackaging( String type ) + protected void setPackaging( String type ) { this.coordinate.setType( type ); } From 448432a32ce0e590c2c25108fae4650fcf69580d Mon Sep 17 00:00:00 2001 From: jonvolfson Date: Wed, 27 May 2020 15:13:33 -0400 Subject: [PATCH 8/8] 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. --- .../plugins/dependency/ListClassesMojo.java | 103 ++++-------------- .../dependency/TestGetClassesMojo.java | 6 +- 2 files changed, 22 insertions(+), 87 deletions(-) diff --git a/src/main/java/org/apache/maven/plugins/dependency/ListClassesMojo.java b/src/main/java/org/apache/maven/plugins/dependency/ListClassesMojo.java index 65caea533..fa33031a8 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/ListClassesMojo.java +++ b/src/main/java/org/apache/maven/plugins/dependency/ListClassesMojo.java @@ -148,7 +148,6 @@ public class ListClassesMojo /** * Skip plugin execution completely. - * */ @Parameter( property = "mdep.skip", defaultValue = "false" ) private boolean skip; @@ -160,7 +159,7 @@ public void execute() throws MojoExecutionException, MojoFailureException try { - if ( isTransitive() ) + if ( transitive ) { Iterable artifacts = dependencyResolver .resolveDependencies( buildingRequest, coordinate, null ); @@ -180,32 +179,34 @@ public void execute() throws MojoExecutionException, MojoFailureException } catch ( ArtifactResolverException | DependencyResolverException | IOException e ) { - throw new MojoExecutionException( "Couldn't download artifact " + artifact + ": " + e.getMessage(), e ); + throw new MojoExecutionException( "Couldn't download artifact: " + e.getMessage(), e ); } } private void printClassesFromArtifactResult( ArtifactResult result ) throws IOException { - JarFile jarFile = new JarFile( result.getArtifact().getFile() ); - Enumeration entries = jarFile.entries(); - - while ( entries.hasMoreElements() ) + // open jar file in try-with-resources statement to guarantee the file closes after use regardless of errors + try ( JarFile jarFile = new JarFile( result.getArtifact().getFile() ) ) { - JarEntry entry = (JarEntry) entries.nextElement(); - String entryName = entry.getName(); + Enumeration entries = jarFile.entries(); - // filter out files that do not end in .class - if ( !entryName.endsWith( ".class" ) ) + while ( entries.hasMoreElements() ) { - continue; - } + JarEntry entry = (JarEntry) entries.nextElement(); + String entryName = entry.getName(); + + // filter out files that do not end in .class + if ( !entryName.endsWith( ".class" ) ) + { + continue; + } - // remove .class from the end and change format to use periods instead of forward slashes - String className = entryName.substring( 0, entryName.length() - 6 ).replace( '/', '.' ); - getLog().info( className ); + // remove .class from the end and change format to use periods instead of forward slashes + String className = entryName.substring( 0, entryName.length() - 6 ).replace( '/', '.' ); + getLog().info( className ); + } } - jarFile.close(); } private ProjectBuildingRequest makeBuildingRequest() @@ -283,7 +284,7 @@ protected ArtifactCoordinate toArtifactCoordinate( DependableCoordinate dependab return artifactCoordinate; } - ArtifactRepository parseRepository( String repo, ArtifactRepositoryPolicy policy ) + protected ArtifactRepository parseRepository( String repo, ArtifactRepositoryPolicy policy ) throws MojoFailureException { // if it's a simple url @@ -322,70 +323,4 @@ private ArtifactRepositoryLayout getLayout( String id ) return layout; } - - /** - * @return {@link #skip} - */ - protected boolean isSkip() - { - return skip; - } - - protected boolean isTransitive() - { - return transitive; - } - - protected DefaultDependableCoordinate getCoordinate() - { - return coordinate; - } - - /** - * @param artifact the artifact - */ - protected void setArtifact( String artifact ) - { - this.artifact = artifact; - } - - /** - * @param groupId the group ID - */ - protected void setGroupId( String groupId ) - { - this.coordinate.setGroupId( groupId ); - } - - /** - * @param artifactId the artifact ID - */ - protected void setArtifactId( String artifactId ) - { - this.coordinate.setArtifactId( artifactId ); - } - - /** - * @param version the version - */ - protected void setVersion( String version ) - { - this.coordinate.setVersion( version ); - } - - /** - * @param classifier the classifier to be used - */ - protected void setClassifier( String classifier ) - { - this.coordinate.setClassifier( classifier ); - } - - /** - * @param type the packaging - */ - protected void setPackaging( String type ) - { - this.coordinate.setType( type ); - } } diff --git a/src/test/java/org/apache/maven/plugins/dependency/TestGetClassesMojo.java b/src/test/java/org/apache/maven/plugins/dependency/TestGetClassesMojo.java index af50ae223..6139ed747 100644 --- a/src/test/java/org/apache/maven/plugins/dependency/TestGetClassesMojo.java +++ b/src/test/java/org/apache/maven/plugins/dependency/TestGetClassesMojo.java @@ -33,7 +33,7 @@ public class TestGetClassesMojo extends AbstractDependencyMojoTestCase { - ListClassesMojo mojo; + private ListClassesMojo mojo; protected void setUp() throws Exception @@ -68,7 +68,7 @@ public void testGetClassesNotTransitive() { setVariableValueToObject( mojo, "remoteRepositories", "central::default::https://repo.maven.apache.org/maven2," + "central::::https://repo.maven.apache.org/maven2," + "https://repo.maven.apache.org/maven2" ); - mojo.setArtifact("org.apache.commons:commons-lang3:3.6"); + setVariableValueToObject( mojo, "artifact", "org.apache.commons:commons-lang3:3.6" ); setVariableValueToObject( mojo, "transitive", Boolean.FALSE ); mojo.execute(); @@ -79,7 +79,7 @@ public void testGetClassesTransitive() { setVariableValueToObject( mojo, "remoteRepositories", "central::default::https://repo.maven.apache.org/maven2," + "central::::https://repo.maven.apache.org/maven2," + "https://repo.maven.apache.org/maven2" ); - mojo.setArtifact("org.apache.commons:commons-lang3:3.6"); + setVariableValueToObject( mojo, "artifact", "org.apache.commons:commons-lang3:3.6" ); setVariableValueToObject( mojo, "transitive", Boolean.TRUE ); mojo.execute();