/** * If the given jarResource is configured with a main class, the underlying artifact is checked to * see if it actually contains the specified class. * * @param jarResource * @throws IllegalStateException if the jarResource's underlying artifact has not yet been * resolved. * @throws MojoExecutionException */ private void checkForMainClass(JarResource jarResource) throws MojoExecutionException { String mainClass = jarResource.getMainClass(); if (mainClass == null) { return; } Artifact artifact = jarResource.getArtifact(); if (artifact == null) { throw new IllegalStateException( "Implementation Error: The given jarResource cannot be checked for " + "a main class until the underlying artifact has been resolved: [" + jarResource + "]"); } try { if (!artifactContainsClass(artifact, mainClass)) { throw new MojoExecutionException( "The jar specified by the following jarResource does not contain the declared main class:" + jarResource); } } catch (MalformedURLException e) { throw new MojoExecutionException( "Attempting to find main class [" + mainClass + "] in [" + artifact + "]", e); } }
@Override public Map<String, JarResource> namedMap() { Map<String, JarResource> map = new HashMap<String, JarResource>(); for (JarResource resource : this) { map.put(resource.getName(), resource); } return map; }
/* ------------------------------------------------------------ */ @Test public void testJarFileCopyToDirectoryTraversal() throws Exception { String s = "jar:" + __userURL + "TestData/extract.zip!/"; Resource r = Resource.newResource(s); assertTrue(r instanceof JarResource); JarResource jarResource = (JarResource) r; File destParent = File.createTempFile("copyjar", null); if (destParent.exists()) destParent.delete(); destParent.mkdir(); destParent.deleteOnExit(); File dest = new File(destParent.getCanonicalPath() + "/extract"); if (dest.exists()) dest.delete(); dest.mkdir(); dest.deleteOnExit(); jarResource.copyTo(dest); // dest contains only the valid entry; dest.getParent() contains only the dest directory assertEquals(1, dest.listFiles().length); assertEquals(1, dest.getParentFile().listFiles().length); FilenameFilter dotdotFilenameFilter = new FilenameFilter() { public boolean accept(File directory, String name) { return name.equals("dotdot.txt"); } }; assertEquals(0, dest.listFiles(dotdotFilenameFilter).length); assertEquals(0, dest.getParentFile().listFiles(dotdotFilenameFilter).length); FilenameFilter extractfileFilenameFilter = new FilenameFilter() { public boolean accept(File directory, String name) { return name.equals("extract-filenotdir"); } }; assertEquals(0, dest.listFiles(extractfileFilenameFilter).length); assertEquals(0, dest.getParentFile().listFiles(extractfileFilenameFilter).length); FilenameFilter currentDirectoryFilenameFilter = new FilenameFilter() { public boolean accept(File directory, String name) { return name.equals("current.txt"); } }; assertEquals(1, dest.listFiles(currentDirectoryFilenameFilter).length); assertEquals(0, dest.getParentFile().listFiles(currentDirectoryFilenameFilter).length); IO.delete(dest); assertFalse(dest.exists()); }
private void checkMandatoryJarResourceFields(JarResource jarResource) throws MojoExecutionException { if (StringUtils.isEmpty(jarResource.getGroupId()) || StringUtils.isEmpty(jarResource.getArtifactId()) || StringUtils.isEmpty(jarResource.getVersion())) { throw new MojoExecutionException( "Configuration error: groupId, artifactId or version missing for jarResource[" + jarResource + "]."); } }
/* ------------------------------------------------------------ */ @Override public synchronized void release() { _list = null; _entry = null; _file = null; _jarFile = null; super.release(); }
/** * Checks the configuration of common jar resources. Specifying common jar resources is optional * but if present, each jar resource must have the same mandatory fields as jar resources * configured directly within a jnlpFile element, but it must not have a configured mainClass * element. * * @throws MojoExecutionException if the config is invalid. */ private void checkCommonJarResources() throws MojoExecutionException { if (this.commonJarResources == null) { return; } for (Iterator itr = this.commonJarResources.iterator(); itr.hasNext(); ) { JarResource jarResource = (JarResource) itr.next(); checkMandatoryJarResourceFields(jarResource); if (jarResource.getMainClass() != null) { throw new MojoExecutionException( "Configuration Error: A mainClass must not be specified " + "on a JarResource in the commonJarResources collection."); } } }
/** * Checks the collection of jarResources configured for a given jnlpFile element. * * @param jnlpFile The configuration element whose jarResources are to be checked. * @throws MojoExecutionException if any config is invalid. */ private void checkJnlpJarResources(JnlpFile jnlpFile) throws MojoExecutionException { List jnlpJarResources = jnlpFile.getJarResources(); if (jnlpJarResources == null || jnlpJarResources.isEmpty()) { throw new MojoExecutionException( "Configuration error: A non-empty <jarResources> element must be specified in the plugin " + "configuration for the JNLP file named [" + jnlpFile.getOutputFilename() + "]"); } Iterator itr = jnlpJarResources.iterator(); List /*JarResource*/ jarsWithMainClass = new ArrayList(); while (itr.hasNext()) { JarResource jarResource = (JarResource) itr.next(); checkMandatoryJarResourceFields(jarResource); if (jarResource.getMainClass() != null) { jnlpFile.setMainClass(jarResource.getMainClass()); jarsWithMainClass.add(jarResource); } } if (jarsWithMainClass.isEmpty()) { throw new MojoExecutionException( "Configuration error: Exactly one <jarResource> element must " + "be declared with a <mainClass> element in the configuration for JNLP file [" + jnlpFile.getOutputFilename() + "]"); } if (jarsWithMainClass.size() > 1) { throw new MojoExecutionException( "Configuration error: More than one <jarResource> element has been declared " + "with a <mainClass> element in the configuration for JNLP file [" + jnlpFile.getOutputFilename() + "]"); } }
private void retrieveTransitiveDependencies(Set jarResourceArtifacts, List jarResources) throws ArtifactResolutionException, ArtifactNotFoundException { // this restricts to runtime and compile scope ScopeArtifactFilter artifactFilter = new ScopeArtifactFilter(Artifact.SCOPE_RUNTIME); ArtifactResolutionResult result = getArtifactResolver() .resolveTransitively( jarResourceArtifacts, getProject().getArtifact(), null, // managedVersions getLocalRepository(), getRemoteRepositories(), this.artifactMetadataSource, artifactFilter); Set transitiveResolvedArtifacts = result.getArtifacts(); if (getLog().isDebugEnabled()) { getLog().debug("transitively resolved artifacts = " + transitiveResolvedArtifacts); getLog().debug("jarResources = " + jarResources); getLog().debug("jarResourceArtifacts = " + jarResourceArtifacts); } // for each transitive dependency, wrap it in a JarResource and add it to the collection of // existing jar resources for (Iterator itr = transitiveResolvedArtifacts.iterator(); itr.hasNext(); ) { Artifact resolvedArtifact = (Artifact) itr.next(); // this whole double check is ugly as well as this method changing the input variable // we should really improve the way we collect the jarResources if (!jarResourceArtifacts.contains(resolvedArtifact)) { JarResource newJarResource = new JarResource(resolvedArtifact); if (!jarResources.contains(newJarResource)) { newJarResource.setOutputJarVersion(true); jarResources.add(newJarResource); } } } }
/* ------------------------------------------------------------ */ @Override protected synchronized boolean checkConnection() { try { super.checkConnection(); } finally { if (_jarConnection == null) { _entry = null; _file = null; _jarFile = null; _list = null; } } return _jarFile != null; }
/* ------------------------------------------------------------ */ @Override protected synchronized void newConnection() throws IOException { super.newConnection(); _entry = null; _file = null; _jarFile = null; _list = null; int sep = _urlString.indexOf("!/"); _jarUrl = _urlString.substring(0, sep + 2); _path = _urlString.substring(sep + 2); if (_path.length() == 0) _path = null; _jarFile = _jarConnection.getJarFile(); _file = new File(_jarFile.getName()); }
private Artifact createArtifact(JarResource jarResource) { if (jarResource.getClassifier() == null) { return getArtifactFactory() .createArtifact( jarResource.getGroupId(), jarResource.getArtifactId(), jarResource.getVersion(), Artifact.SCOPE_RUNTIME, "jar"); } else { return getArtifactFactory() .createArtifactWithClassifier( jarResource.getGroupId(), jarResource.getArtifactId(), jarResource.getVersion(), "jar", jarResource.getClassifier()); } }
/** * Resolve the artifacts represented by the given collection of JarResources and copy them to the * working directory if a newer copy of the file doesn't already exist there. Transitive * dependencies will also be retrieved. * * <p>Transitive dependencies are added to the list specified as parameter. TODO fix that. * * @throws MojoExecutionException */ private void retrieveJarResources(List jarResources) throws MojoExecutionException { Set jarResourceArtifacts = new HashSet(); try { // for each configured JarResource, create and resolve the corresponding artifact and // check it for the mainClass if specified for (Iterator itr = jarResources.iterator(); itr.hasNext(); ) { JarResource jarResource = (JarResource) itr.next(); Artifact artifact = createArtifact(jarResource); getArtifactResolver().resolve(artifact, getRemoteRepositories(), getLocalRepository()); jarResource.setArtifact(artifact); checkForMainClass(jarResource); jarResourceArtifacts.add(artifact); } if (!isExcludeTransitive()) { retrieveTransitiveDependencies(jarResourceArtifacts, jarResources); } // for each JarResource, copy its artifact to the lib directory if necessary for (Iterator itr = jarResources.iterator(); itr.hasNext(); ) { JarResource jarResource = (JarResource) itr.next(); Artifact artifact = jarResource.getArtifact(); boolean copied = copyJarAsUnprocessedToDirectoryIfNecessary(artifact.getFile(), getLibDirectory()); if (copied) { String name = artifact.getFile().getName(); if (getLog().isDebugEnabled()) { getLog().debug("Adding " + name + " to modifiedJnlpArtifacts list."); } getModifiedJnlpArtifacts().add(name.substring(0, name.lastIndexOf('.'))); } if (jarResource.isOutputJarVersion()) { // Create and set a version-less href for this jarResource String hrefValue = buildHrefValue(artifact); jarResource.setHrefValue(hrefValue); } } } catch (ArtifactResolutionException e) { throw new MojoExecutionException("Unable to resolve an artifact", e); } catch (ArtifactNotFoundException e) { throw new MojoExecutionException("Unable to find an artifact", e); } catch (IOException e) { throw new MojoExecutionException("Unable to copy an artifact to the working directory", e); } }