diff --git a/maven-external-dependency-plugin/maven-external-dependency-plugin-test/pom.xml b/maven-external-dependency-plugin/maven-external-dependency-plugin-test/pom.xml index fd3c15a6b..9724869e4 100644 --- a/maven-external-dependency-plugin/maven-external-dependency-plugin-test/pom.xml +++ b/maven-external-dependency-plugin/maven-external-dependency-plugin-test/pom.xml @@ -1,268 +1,369 @@ - 4.0.0 - com.savage7.maven.plugins - maven-external-dependency-plugin-test - jar - 2.0.7-SNAPSHOT - ${project.groupId}.${project.artifactId} - http://code.google.com/p/maven-external-dependency-plugin/ - + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + 4.0.0 + org.openidentityplatform.commons + maven-external-dependency-plugin-test + jar + 3.0.5-SNAPSHOT + ${project.groupId}.${project.artifactId} + https://github.com/OpenIdentityPlatform/commons/tree/master/maven-external-dependency-plugin + UTF-8 UTF-8 + + ${project.build.directory}/dependencies/ - - ${project.groupId}.${project.artifactId} - - - - org.apache.maven.wagon - wagon-http-lightweight - 2.2 - - - - + + ${project.groupId}.${project.artifactId} + + + + org.apache.maven.wagon + wagon-http-lightweight + 3.4.3 + + + + + + + + maven-compiler-plugin + + 11 + 11 + + + + + + + maven-surefire-plugin + 2.22.2 + + + ${staging.directory} + + + + + - + + org.openidentityplatform.commons + maven-external-dependency-plugin + 3.0.5-SNAPSHOT + false + + ${staging.directory} + + true + + false + + false + - - com.savage7.maven.plugins - maven-external-dependency-plugin - 2.0.7-SNAPSHOT - false - - - ${project.build.directory}/dependencies/ - - true - false - false - + + + commons-io + commons-io + 2.14.0 + jar + https://repo1.maven.org/maven2/commons-io/commons-io/{version}/{artifactId}-{version}.{packaging} + true + true + + true + - - - com.google.code - google-api-translate-java - 0.97 - jar - - http://google-api-translate-java.googlecode.com/files/{artifactId}-{version}.jar - - + + + org.hamcrest + hamcrest-core + 1.3 + jar + https://repo1.maven.org/maven2/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar + 42a25dc3219429f0e5d060061f71acb49bf010a0 + false + + 30000 + true + true + - - - org.papervision3d - Papervision3D - 2.1.932 - swc - - http://papervision3d.googlecode.com/files/{artifactId}_{version}.{packaging} - - + + + org.slf4j + slf4j-api + 1.7.36 + jar + https://repo1.maven.org/maven2/org/slf4j/slf4j-api/1.7.36/slf4j-api-1.7.36.jar + false + false + true + - - - org.apache.ant - apache-ant - 1.8.4 - bin - zip - - http://apache.securedservers.com/ant/binaries/{artifactId}-{version}-{classifier}.zip - - f1fe34f9de8b40cb8811a6286faec4ec7a35ba23 - + + + commons-lang + commons-lang + 2.6 + sources + jar + https://repo1.maven.org/maven2/commons-lang/commons-lang/{version}/{artifactId}-{version}-{classifier}.{packaging} + true + + false + true + - - - com.google.code - tweener - 1.33.74 - swc - - http://tweener.googlecode.com/files/tweener_1_33_74_as3_swc.zip - - tweener.swc - + + - - - com.maxmind.geoip - GeoIP.dat - ${project.version} - dat - - {artifactId} - - - + + + + - - + + - + + - - - - clean-external-dependencies - clean - - - clean-external - - - - resolve-install-external-dependencies - process-resources - - - resolve-external + + - - install-external - - - - deploy-external-dependencies - deploy - - - deploy-external - - - - - + + + + + clean-external-dependencies + clean + + clean-external + + + + resolve-install-external-dependencies + process-resources + + resolve-external + install-external + + + + deploy-external-dependencies + deploy + + deploy-external + + + + + - - - - - - - - - - - - - + + + + + + + + - - - - - org.eclipse.m2e - lifecycle-mapping - 1.0.0 - - - - - - - com.savage7.maven.plugins - - - maven-external-dependency-plugin - - - [0.5-SNAPSHOT,) - - - - resolve-external - - - install-external - - - - - - - - - - - - - - + + + + + org.eclipse.m2e + lifecycle-mapping + 1.0.0 + + + + + + org.openidentityplatform.commons + maven-external-dependency-plugin + [3.0.0-SNAPSHOT,) + + resolve-external + install-external + + + + + + + + + + + + + - + - + - - com.google.code - google-api-translate-java - 0.97 - + + + commons-io + commons-io + 2.14.0 + - - org.papervision3d - Papervision3D - 2.1.932 - swc - + + org.hamcrest + hamcrest-core + 1.3 + - - junit - junit - 3.8.1 - test - - - - org.json - json - + + junit + junit + 4.13.2 + test + - + diff --git a/maven-external-dependency-plugin/maven-external-dependency-plugin-test/src/main/java/com/savage7/maven/plugin/dependency/App.java b/maven-external-dependency-plugin/maven-external-dependency-plugin-test/src/main/java/com/savage7/maven/plugin/dependency/App.java index ff28949db..51083a0d0 100644 --- a/maven-external-dependency-plugin/maven-external-dependency-plugin-test/src/main/java/com/savage7/maven/plugin/dependency/App.java +++ b/maven-external-dependency-plugin/maven-external-dependency-plugin-test/src/main/java/com/savage7/maven/plugin/dependency/App.java @@ -1,28 +1,25 @@ package com.savage7.maven.plugin.dependency; -import com.google.api.translate.Language; -import com.google.api.translate.TranslateV2; +import org.apache.commons.io.FileUtils; + +import java.io.File; +import java.nio.charset.StandardCharsets; /** - * Hello world! - * + * Demonstrates that an externally-downloaded artifact (commons-io) is available + * on the classpath after the maven-external-dependency-plugin has resolved and + * installed it during the {@code process-resources} phase. */ -public class App -{ - public static void main( String[] args ) throws Exception - { - // Set the HTTP referrer to your website address. - TranslateV2 translate = new TranslateV2(); - TranslateV2.setHttpReferrer("http://localhost"); +public class App { + public static void main(String[] args) throws Exception { + // Write a temporary file and read it back using commons-io, + // which was downloaded by the external-dependency plugin. + File temp = File.createTempFile("external-dep-demo", ".txt"); + temp.deleteOnExit(); - String englishText = "Hello World"; - String spanishTranslatedText = translate.execute(englishText, Language.ENGLISH, Language.SPANISH); - String frenchTranslatedText = translate.execute(englishText, Language.ENGLISH, Language.FRENCH); - String germanTranslatedText = translate.execute(englishText, Language.ENGLISH, Language.GERMAN); + FileUtils.writeStringToFile(temp, "Hello from commons-io!", StandardCharsets.UTF_8); + String content = FileUtils.readFileToString(temp, StandardCharsets.UTF_8); - System.out.println("ENLGISH : " + englishText); - System.out.println("SPANISH : " + spanishTranslatedText); - System.out.println("FRENCH : " + frenchTranslatedText); - System.out.println("GERMAN : " + germanTranslatedText); + System.out.println("commons-io is on the classpath: " + content); } } diff --git a/maven-external-dependency-plugin/maven-external-dependency-plugin-test/src/test/java/com/savage7/maven/plugin/dependency/AppTest.java b/maven-external-dependency-plugin/maven-external-dependency-plugin-test/src/test/java/com/savage7/maven/plugin/dependency/AppTest.java index 3e6db22de..8da0acbbe 100644 --- a/maven-external-dependency-plugin/maven-external-dependency-plugin-test/src/test/java/com/savage7/maven/plugin/dependency/AppTest.java +++ b/maven-external-dependency-plugin/maven-external-dependency-plugin-test/src/test/java/com/savage7/maven/plugin/dependency/AppTest.java @@ -1,38 +1,78 @@ package com.savage7.maven.plugin.dependency; -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; +import org.junit.Test; + +import java.io.File; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; /** - * Unit test for simple App. + * Verifies that the maven-external-dependency-plugin correctly downloaded + * and staged the declared artifact items. + * + * The {@code resolve-external} and {@code install-external} goals run in the + * {@code process-resources} phase, which precedes the {@code test} phase, so + * the staging directory is populated by the time these tests execute. + * + * The staging directory path is injected via the {@code staging.directory} + * system property configured in the maven-surefire-plugin. */ -public class AppTest - extends TestCase -{ - /** - * Create the test case - * - * @param testName name of the test case - */ - public AppTest( String testName ) - { - super( testName ); +public class AppTest { + + /** Staging directory configured in pom.xml and passed as a system property. */ + private static final String STAGING_DIR = + System.getProperty("staging.directory", "target/dependencies/"); + + @Test + public void testStagingDirectoryExists() { + File stagingDir = new File(STAGING_DIR); + assertTrue("Staging directory should exist after resolve-external goal: " + stagingDir.getAbsolutePath(), + stagingDir.exists() && stagingDir.isDirectory()); } - /** - * @return the suite of tests being tested - */ - public static Test suite() - { - return new TestSuite( AppTest.class ); + @Test + public void testStagingDirectoryIsNotEmpty() { + File stagingDir = new File(STAGING_DIR); + if (stagingDir.exists()) { + String[] files = stagingDir.list(); + assertNotNull("Staging directory listing should not be null", files); + assertTrue("Staging directory should contain at least one downloaded artifact", + files.length > 0); + } } - /** - * Rigourous Test :-) - */ - public void testApp() - { - assertTrue( true ); + /** Example 1 – basic JAR downloaded via URL template. */ + @Test + public void testCommonsIoDownloaded() { + assertStagedFileExists("commons-io-2.14.0.jar"); + } + + /** Example 2 – JAR downloaded with explicit SHA-1 checksum verification. */ + @Test + public void testHamcrestCoreDownloaded() { + assertStagedFileExists("hamcrest-core-1.3.jar"); + } + + /** Example 3 – download-only artifact (install=false, deploy=false). */ + @Test + public void testSlf4jApiDownloaded() { + assertStagedFileExists("slf4j-api-1.7.36.jar"); + } + + /** Example 4 – JAR with sources classifier. */ + @Test + public void testCommonsLangSourcesDownloaded() { + assertStagedFileExists("commons-lang-2.6-sources.jar"); + } + + // ------------------------------------------------------------------------- + // Helper + // ------------------------------------------------------------------------- + + private void assertStagedFileExists(String fileName) { + File artifact = new File(STAGING_DIR, fileName); + assertTrue("Expected staged artifact to exist and be non-empty: " + artifact.getAbsolutePath(), + artifact.exists() && artifact.length() > 0); } } diff --git a/maven-external-dependency-plugin/maven-external-dependency-plugin/src/main/java/com/savage7/maven/plugin/dependency/AbstractExternalDependencyMojo.java b/maven-external-dependency-plugin/maven-external-dependency-plugin/src/main/java/com/savage7/maven/plugin/dependency/AbstractExternalDependencyMojo.java index 410be2474..1e0e6f040 100644 --- a/maven-external-dependency-plugin/maven-external-dependency-plugin/src/main/java/com/savage7/maven/plugin/dependency/AbstractExternalDependencyMojo.java +++ b/maven-external-dependency-plugin/maven-external-dependency-plugin/src/main/java/com/savage7/maven/plugin/dependency/AbstractExternalDependencyMojo.java @@ -20,9 +20,14 @@ package com.savage7.maven.plugin.dependency; import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import java.io.Writer; import java.util.ArrayList; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; @@ -515,4 +520,56 @@ else if(artifactProperty.getNodeName().equalsIgnoreCase("version")) ); } } + + /** + * Attempts to extract a POM file from within the JAR artifact. + * Maven-built JARs contain their POM at + * META-INF/maven/{groupId}/{artifactId}/pom.xml. + * + * @param artifactItem + * the artifact configuration + * @param jarFile + * the JAR file to search within + * @return extracted POM File, or null if not found + * @throws IOException + * if an I/O error occurs while reading the JAR + */ + protected File extractPomFromJar(ArtifactItem artifactItem, File jarFile) + throws IOException + { + String pomPath = "META-INF/maven/" + artifactItem.getGroupId() + + "/" + artifactItem.getArtifactId() + "/pom.xml"; + + getLog().debug("looking for embedded POM in JAR at: " + pomPath); + + try (JarFile jar = new JarFile(jarFile)) + { + JarEntry entry = jar.getJarEntry(pomPath); + if (entry != null) + { + File tempPom = File.createTempFile( + artifactItem.getGroupId() + "." + artifactItem.getArtifactId(), + ".pom"); + tempPom.deleteOnExit(); + + try (InputStream is = jar.getInputStream(entry); + OutputStream os = new FileOutputStream(tempPom)) + { + byte[] buffer = new byte[4096]; + int bytesRead; + while ((bytesRead = is.read(buffer)) != -1) + { + os.write(buffer, 0, bytesRead); + } + } + + getLog().info( + "extracted POM from JAR: " + pomPath); + return tempPom; + } + } + + getLog().debug("no embedded POM found in JAR at: " + pomPath); + return null; + } } diff --git a/maven-external-dependency-plugin/maven-external-dependency-plugin/src/main/java/com/savage7/maven/plugin/dependency/ArtifactItem.java b/maven-external-dependency-plugin/maven-external-dependency-plugin/src/main/java/com/savage7/maven/plugin/dependency/ArtifactItem.java index aa8b5b07c..962a38def 100644 --- a/maven-external-dependency-plugin/maven-external-dependency-plugin/src/main/java/com/savage7/maven/plugin/dependency/ArtifactItem.java +++ b/maven-external-dependency-plugin/maven-external-dependency-plugin/src/main/java/com/savage7/maven/plugin/dependency/ArtifactItem.java @@ -181,6 +181,16 @@ public class ArtifactItem * @parameter */ private boolean repack = false; + + /** + * Flag whether to attempt extracting POM from the JAR's META-INF directory. + * When true (default), the plugin will look for an embedded POM at + * META-INF/maven/{groupId}/{artifactId}/pom.xml inside the JAR and use it + * instead of generating a minimal one. + * + * @parameter default-value="true" + */ + private Boolean extractPom = true; /** * default constructor. @@ -668,4 +678,21 @@ public void setRepack(boolean repack) this.repack = repack; } + /** + * @return ExtractPom. + */ + public final Boolean getExtractPom() + { + return extractPom; + } + + /** + * @param extractPom + * ExtractPom. + */ + public final void setExtractPom(final Boolean extractPom) + { + this.extractPom = extractPom; + } + } diff --git a/maven-external-dependency-plugin/maven-external-dependency-plugin/src/main/java/com/savage7/maven/plugin/dependency/DeployExternalDependencyMojo.java b/maven-external-dependency-plugin/maven-external-dependency-plugin/src/main/java/com/savage7/maven/plugin/dependency/DeployExternalDependencyMojo.java index 8db51cfd7..d0b1b4e39 100644 --- a/maven-external-dependency-plugin/maven-external-dependency-plugin/src/main/java/com/savage7/maven/plugin/dependency/DeployExternalDependencyMojo.java +++ b/maven-external-dependency-plugin/maven-external-dependency-plugin/src/main/java/com/savage7/maven/plugin/dependency/DeployExternalDependencyMojo.java @@ -142,14 +142,34 @@ public void execute() throws MojoExecutionException, MojoFailureException } else { - // dynamically create a new POM file for this - // artifact - generatedPomFile = generatePomFile(artifactItem); - ArtifactMetadata pomMetadata = new ProjectArtifactMetadata( - artifact, generatedPomFile); + // try to extract POM from within the JAR + File extractedPom = null; + if (artifactItem.getExtractPom() == true + && "jar".equals(artifactItem.getPackaging())) + { + extractedPom = extractPomFromJar( + artifactItem, installedArtifactFile); + } - if (artifactItem.getGeneratePom() == true) + if (extractedPom != null) + { + getLog().debug( + "deploying POM extracted from JAR: " + + extractedPom.getAbsolutePath()); + ArtifactMetadata pomMetadata = + new ProjectArtifactMetadata( + artifact, extractedPom); + artifact.addMetadata(pomMetadata); + generatedPomFile = extractedPom; + } + else if (artifactItem.getGeneratePom() == true) { + // dynamically create a new POM file for this + // artifact + generatedPomFile = generatePomFile(artifactItem); + ArtifactMetadata pomMetadata = + new ProjectArtifactMetadata( + artifact, generatedPomFile); artifact.addMetadata(pomMetadata); } } @@ -193,6 +213,11 @@ public void execute() throws MojoExecutionException, MojoFailureException throw new MojoExecutionException( "Deployment of external dependency failed.", e); } + catch (IOException e) + { + throw new MojoExecutionException( + "Error reading artifact file for deployment.", e); + } } else diff --git a/maven-external-dependency-plugin/maven-external-dependency-plugin/src/main/java/com/savage7/maven/plugin/dependency/InstallExternalDependencyMojo.java b/maven-external-dependency-plugin/maven-external-dependency-plugin/src/main/java/com/savage7/maven/plugin/dependency/InstallExternalDependencyMojo.java index 78f2784c9..cf8d27ac2 100644 --- a/maven-external-dependency-plugin/maven-external-dependency-plugin/src/main/java/com/savage7/maven/plugin/dependency/InstallExternalDependencyMojo.java +++ b/maven-external-dependency-plugin/maven-external-dependency-plugin/src/main/java/com/savage7/maven/plugin/dependency/InstallExternalDependencyMojo.java @@ -186,18 +186,38 @@ public void execute() throws MojoExecutionException, MojoFailureException } else { - // dynamically create a new POM file for - // this artifact - generatedPomFile = generatePomFile(artifactItem); - ArtifactMetadata pomMetadata = new ProjectArtifactMetadata( - artifact, generatedPomFile); + // try to extract POM from within the JAR + File extractedPom = null; + if (artifactItem.getExtractPom() == true + && "jar".equals(artifactItem.getPackaging())) + { + extractedPom = extractPomFromJar( + artifactItem, stagedArtifactFile); + } - if (artifactItem.getGeneratePom() == true) + if (extractedPom != null) + { + getLog().debug( + "installing POM extracted from JAR: " + + extractedPom.getAbsolutePath()); + ArtifactMetadata pomMetadata = + new ProjectArtifactMetadata( + artifact, extractedPom); + artifact.addMetadata(pomMetadata); + generatedPomFile = extractedPom; + } + else if (artifactItem.getGeneratePom() == true) { + // dynamically create a new POM file for + // this artifact + generatedPomFile = generatePomFile(artifactItem); + ArtifactMetadata pomMetadata = + new ProjectArtifactMetadata( + artifact, generatedPomFile); getLog().debug( "installing generated POM file: " + generatedPomFile - .getCanonicalPath()); + .getAbsolutePath()); artifact.addMetadata(pomMetadata); } }