[Git][java-team/maven-shared-jar][master] 7 commits: New upstream version 3.1.0
Emmanuel Bourg (@ebourg)
gitlab at salsa.debian.org
Thu Oct 24 15:08:31 BST 2024
Emmanuel Bourg pushed to branch master at Debian Java Maintainers / maven-shared-jar
Commits:
7c1d2350 by Emmanuel Bourg at 2024-10-24T15:57:51+02:00
New upstream version 3.1.0
- - - - -
278ba6e2 by Emmanuel Bourg at 2024-10-24T15:58:00+02:00
New upstream version 3.1.1
- - - - -
95057ae0 by Emmanuel Bourg at 2024-10-24T15:58:01+02:00
Update upstream source from tag 'upstream/3.1.1'
Update to upstream version '3.1.1'
with Debian dir 89914881f3e0ba18654957b74970e29430d791a6
- - - - -
b9925872 by Emmanuel Bourg at 2024-10-24T16:06:37+02:00
New dependency on libplexus-xml-java
- - - - -
3fff39b9 by Emmanuel Bourg at 2024-10-24T16:07:01+02:00
New dependency on libmodello-maven-plugin-java
- - - - -
68798e16 by Emmanuel Bourg at 2024-10-24T16:07:29+02:00
Updated the Maven rules
- - - - -
1a1ee8a4 by Emmanuel Bourg at 2024-10-24T16:08:02+02:00
Upload to unstable
- - - - -
20 changed files:
- debian/changelog
- debian/control
- debian/libmaven-shared-jar-java.poms
- debian/maven.rules
- pom.xml
- src/main/java/org/apache/maven/shared/jar/JarAnalyzer.java
- src/main/java/org/apache/maven/shared/jar/JarData.java
- src/main/java/org/apache/maven/shared/jar/classes/JarClassesAnalysis.java
- + src/main/java/org/apache/maven/shared/jar/classes/JarVersionedRuntime.java
- + src/main/java/org/apache/maven/shared/jar/classes/JarVersionedRuntimes.java
- src/main/java/org/apache/maven/shared/jar/identification/JarIdentificationAnalysis.java
- src/main/java/org/apache/maven/shared/jar/identification/exposers/TextFileExposer.java
- src/main/java/org/apache/maven/shared/jar/identification/exposers/TimestampExposer.java
- src/test/java/org/apache/maven/shared/jar/JarAnalyzerTest.java
- src/test/java/org/apache/maven/shared/jar/classes/JarClassesAnalyzerTest.java
- + src/test/resources/jars/module-info-only-test-0.0.1.jar
- + src/test/resources/jars/multi-release-resources-only-0.0.1.jar
- + src/test/resources/jars/multi-release-test-0.0.1.jar
- + src/test/resources/jars/multi-release-version-with-lower-jdk-revision-class-0.0.1.jar
- + src/test/resources/jars/tomcat-jni-9.0.75.jar
Changes:
=====================================
debian/changelog
=====================================
@@ -1,3 +1,13 @@
+maven-shared-jar (3.1.1-1) unstable; urgency=medium
+
+ * Team upload.
+ * New upstream release
+ - New dependency on libplexus-xml-java
+ - New dependency on libmodello-maven-plugin-java
+ - Updated the Maven rules
+
+ -- Emmanuel Bourg <ebourg at apache.org> Thu, 24 Oct 2024 16:07:56 +0200
+
maven-shared-jar (3.0.0-1) unstable; urgency=medium
* Team upload.
=====================================
debian/control
=====================================
@@ -10,10 +10,13 @@ Build-Depends:
libbcel-java,
libcommons-collections4-java,
libeclipse-sisu-maven-plugin-java,
+ libmaven-parent-java,
libmaven-shared-utils-java,
libmaven3-core-java,
+ libmodello-maven-plugin-java,
libplexus-digest-java,
libplexus-testing-java,
+ libplexus-xml-java,
maven-debian-helper (>= 1.4)
Standards-Version: 4.7.0
Vcs-Git: https://salsa.debian.org/java-team/maven-shared-jar.git
=====================================
debian/libmaven-shared-jar-java.poms
=====================================
@@ -25,4 +25,4 @@
# --site-xml=<location>: Optional, the location for site.xml if it needs to be installed.
# Empty by default. [mh_install]
#
-pom.xml --no-parent --has-package-version
+pom.xml --has-package-version
=====================================
debian/maven.rules
=====================================
@@ -16,9 +16,5 @@
# and version starting with 3., replacing the version with 3.x
# junit junit jar s/3\\..*/3.x/
-commons-collections commons-collections jar s/3\..*/3.x/ * *
-s/com.google.code.findbugs/org.apache.bcel/ s/bcel-findbugs/bcel/ jar s/.*/5.x/ * *
-org.apache.maven.shared maven-shared-jar jar s/.*/debian/ * *
-junit junit * s/.*/3.x/ * *
org.apache.maven maven-* * s/.*/3.x/ * *
-org.codehaus.plexus plexus-container-default * s/.*/1.5.5/ * *
+org.apache.maven.shared maven-shared-components pom s/.*/debian/ * *
=====================================
pom.xml
=====================================
@@ -23,12 +23,12 @@
<parent>
<groupId>org.apache.maven.shared</groupId>
<artifactId>maven-shared-components</artifactId>
- <version>39</version>
+ <version>42</version>
<relativePath />
</parent>
<artifactId>maven-shared-jar</artifactId>
- <version>3.0.0</version>
+ <version>3.1.1</version>
<name>Apache Maven JAR Utilities</name>
<description>Utilities that help identify the contents of a JAR, including Java class analysis and Maven metadata analysis.</description>
@@ -36,7 +36,7 @@
<scm>
<connection>scm:git:https://gitbox.apache.org/repos/asf/maven-shared-jar.git</connection>
<developerConnection>scm:git:https://gitbox.apache.org/repos/asf/maven-shared-jar.git</developerConnection>
- <tag>maven-shared-jar-3.0.0</tag>
+ <tag>maven-shared-jar-3.1.1</tag>
<url>https://github.com/apache/maven-shared-jar/tree/${project.scm.tag}</url>
</scm>
<issueManagement>
@@ -56,10 +56,9 @@
<properties>
<javaVersion>8</javaVersion>
- <mavenVersion>3.2.5</mavenVersion>
+ <mavenVersion>3.6.3</mavenVersion>
<slf4jVersion>1.7.36</slf4jVersion>
- <project.build.outputTimestamp>2023-04-15T15:52:19Z</project.build.outputTimestamp>
- <junitVersion>5.9.2</junitVersion>
+ <project.build.outputTimestamp>2024-06-20T20:40:38Z</project.build.outputTimestamp>
</properties>
<dependencies>
@@ -88,18 +87,28 @@
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-utils</artifactId>
- <version>3.5.1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-xml</artifactId>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
- <version>1.15</version>
+ <version>1.17.0</version>
</dependency>
<dependency>
<groupId>org.apache.bcel</groupId>
<artifactId>bcel</artifactId>
- <version>6.7.0</version>
+ <version>6.9.0</version>
+ </dependency>
+ <!-- Required by BCEL overwritten by maven-artifact -->
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-lang3</artifactId>
+ <version>3.14.0</version>
+ <scope>runtime</scope>
</dependency>
<dependency>
@@ -111,19 +120,17 @@
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
- <version>${junitVersion}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
- <version>${junitVersion}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-testing</artifactId>
- <version>1.1.0</version>
+ <version>1.3.0</version>
<scope>test</scope>
</dependency>
<dependency>
=====================================
src/main/java/org/apache/maven/shared/jar/JarAnalyzer.java
=====================================
@@ -151,9 +151,20 @@ public class JarAnalyzer {
* @return the list of files found, in {@link java.util.jar.JarEntry} elements
*/
public List<JarEntry> filterEntries(Pattern pattern) {
+ return filterEntries(pattern, getEntries());
+ }
+
+ /**
+ * Filter a list of JAR entries against the pattern.
+ *
+ * @param pattern the pattern to filter against.
+ * @param entryList the list of entries to filter from.
+ * @return the filtered list of JarEntry.
+ */
+ private List<JarEntry> filterEntries(Pattern pattern, List<JarEntry> entryList) {
List<JarEntry> ret = new ArrayList<>();
- for (JarEntry entry : getEntries()) {
+ for (JarEntry entry : entryList) {
Matcher mat = pattern.matcher(entry.getName());
if (mat.find()) {
ret.add(entry);
@@ -171,6 +182,18 @@ public class JarAnalyzer {
return filterEntries(CLASS_FILTER);
}
+ /**
+ * Get all the classes in the entry list.
+ *
+ * @param entryList the entry list.
+ * @return the filtered entry list.
+ *
+ * @since 3.1.0
+ */
+ public List<JarEntry> getClassEntries(List<JarEntry> entryList) {
+ return filterEntries(CLASS_FILTER, entryList);
+ }
+
/**
* Get all the Maven POM entries in the JAR.
*
=====================================
src/main/java/org/apache/maven/shared/jar/JarData.java
=====================================
@@ -22,17 +22,21 @@ import java.io.File;
import java.util.Collections;
import java.util.List;
import java.util.jar.Attributes;
+import java.util.jar.Attributes.Name;
import java.util.jar.JarEntry;
import java.util.jar.Manifest;
import org.apache.maven.shared.jar.classes.JarClasses;
+import org.apache.maven.shared.jar.classes.JarVersionedRuntimes;
import org.apache.maven.shared.jar.identification.JarIdentification;
-import org.codehaus.plexus.util.StringUtils;
/**
* Class that contains details of a single JAR file and it's entries.
*/
public final class JarData {
+
+ private static final Name ATTR_MULTI_RELEASE = new Attributes.Name("Multi-Release");
+
/**
* The JAR file.
*/
@@ -43,6 +47,11 @@ public final class JarData {
*/
private final boolean aSealed;
+ /**
+ * Whether the JAR file is Multi-Release.
+ */
+ private boolean multiRelease;
+
/**
* The hashcode for the entire file's contents.
*/
@@ -68,11 +77,21 @@ public final class JarData {
*/
private final List<JarEntry> entries;
+ /**
+ * The JAR entries of the root content, when it is a multi-release JAR
+ */
+ private List<JarEntry> rootEntries;
+
/**
* Information about the JAR's identifying features.
*/
private JarIdentification jarIdentification;
+ /**
+ * Information about the JAR's Multi-Release entries
+ */
+ private JarVersionedRuntimes versionedRuntimes;
+
/**
* Constructor.
*
@@ -87,20 +106,22 @@ public final class JarData {
this.entries = Collections.unmodifiableList(entries);
- boolean aSealed = false;
- if (this.manifest != null) {
- String sval = this.manifest.getMainAttributes().getValue(Attributes.Name.SEALED);
- if (StringUtils.isNotEmpty(sval)) {
- aSealed = "true".equalsIgnoreCase(sval.trim());
- }
- }
- this.aSealed = aSealed;
+ this.aSealed = isAttributePresent(Attributes.Name.SEALED);
+ this.multiRelease = isAttributePresent(ATTR_MULTI_RELEASE);
}
public List<JarEntry> getEntries() {
return entries;
}
+ public List<JarEntry> getRootEntries() {
+ return rootEntries;
+ }
+
+ public void setRootEntries(List<JarEntry> rootEntries) {
+ this.rootEntries = rootEntries;
+ }
+
public Manifest getManifest() {
return manifest;
}
@@ -113,6 +134,10 @@ public final class JarData {
return aSealed;
}
+ public boolean isMultiRelease() {
+ return multiRelease;
+ }
+
public void setFileHash(String fileHash) {
this.fileHash = fileHash;
}
@@ -141,6 +166,10 @@ public final class JarData {
return entries.size();
}
+ public int getNumRootEntries() {
+ return rootEntries.size();
+ }
+
public int getNumClasses() {
return jarClasses.getClassNames().size();
}
@@ -164,4 +193,20 @@ public final class JarData {
public JarClasses getJarClasses() {
return jarClasses;
}
+
+ public void setVersionedRuntimes(JarVersionedRuntimes versionedRuntimes) {
+ this.versionedRuntimes = versionedRuntimes;
+ }
+
+ public JarVersionedRuntimes getVersionedRuntimes() {
+ return this.versionedRuntimes;
+ }
+
+ private boolean isAttributePresent(Attributes.Name attrName) {
+ if (this.manifest != null) {
+ String sval = this.manifest.getMainAttributes().getValue(attrName);
+ return sval != null && "true".equalsIgnoreCase(sval.trim());
+ }
+ return false;
+ }
}
=====================================
src/main/java/org/apache/maven/shared/jar/classes/JarClassesAnalysis.java
=====================================
@@ -26,8 +26,13 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.NavigableMap;
import java.util.Optional;
+import java.util.TreeMap;
import java.util.jar.JarEntry;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
import org.apache.bcel.classfile.ClassFormatException;
import org.apache.bcel.classfile.ClassParser;
@@ -36,6 +41,7 @@ import org.apache.bcel.classfile.JavaClass;
import org.apache.bcel.classfile.LineNumberTable;
import org.apache.bcel.classfile.Method;
import org.apache.maven.shared.jar.JarAnalyzer;
+import org.apache.maven.shared.jar.JarData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -51,8 +57,17 @@ import org.slf4j.LoggerFactory;
@Named
@SuppressWarnings("checkstyle:MagicNumber")
public class JarClassesAnalysis {
+
private final Logger logger = LoggerFactory.getLogger(getClass());
+ /**
+ * Constant representing the root content of a Multi-Release JAR file, thus outside of
+ * any given META-INF/versions/N/... entry.
+ */
+ private static final Integer ROOT = 0;
+
+ private static final Pattern ENTRY_FILTER_MULTI_RELEASE = Pattern.compile("^META-INF/versions/([1-9]\\d*)/.*$");
+
private static final Map<Double, String> JAVA_CLASS_VERSIONS;
static {
@@ -90,68 +105,134 @@ public class JarClassesAnalysis {
* @return the details of the classes found
*/
public JarClasses analyze(JarAnalyzer jarAnalyzer) {
- JarClasses classes = jarAnalyzer.getJarData().getJarClasses();
+ JarData jarData = jarAnalyzer.getJarData();
+ JarClasses classes = jarData.getJarClasses();
if (classes == null) {
- String jarfilename = jarAnalyzer.getFile().getAbsolutePath();
- classes = new JarClasses();
+ if (jarData.isMultiRelease()) {
+ classes = analyzeMultiRelease(jarAnalyzer);
+ } else {
+ classes = analyzeRoot(jarAnalyzer);
+ }
+ }
+ return classes;
+ }
+
+ private Integer jarEntryVersion(JarEntry entry) {
+ Matcher matcher = ENTRY_FILTER_MULTI_RELEASE.matcher(entry.getName());
+ if (matcher.matches()) {
+ return Integer.valueOf(matcher.group(1));
+ }
+ return ROOT;
+ }
- List<JarEntry> classList = jarAnalyzer.getClassEntries();
+ private JarClasses analyzeMultiRelease(JarAnalyzer jarAnalyzer) {
+ String jarFilename = jarAnalyzer.getFile().getAbsolutePath();
- classes.setDebugPresent(false);
+ Map<Integer, List<JarEntry>> mapEntries =
+ jarAnalyzer.getEntries().stream().collect(Collectors.groupingBy(this::jarEntryVersion));
- double maxVersion = 0.0;
+ // ordered by increasing Java version
+ NavigableMap<Integer, JarVersionedRuntime> runtimeVersionsMap = new TreeMap<>();
- for (JarEntry entry : classList) {
- String classname = entry.getName();
+ for (Map.Entry<Integer, List<JarEntry>> mapEntry : mapEntries.entrySet()) {
+ Integer runtimeVersion = mapEntry.getKey();
+ List<JarEntry> runtimeVersionEntryList = mapEntry.getValue();
- try {
- ClassParser classParser = new ClassParser(jarfilename, classname);
+ List<JarEntry> classList = jarAnalyzer.getClassEntries(runtimeVersionEntryList);
- JavaClass javaClass = classParser.parse();
+ JarClasses classes = analyze(jarFilename, classList);
- String classSignature = javaClass.getClassName();
+ runtimeVersionsMap.put(runtimeVersion, new JarVersionedRuntime(runtimeVersionEntryList, classes));
+ }
- if (!classes.isDebugPresent()) {
- if (hasDebugSymbols(javaClass)) {
- classes.setDebugPresent(true);
- }
- }
+ JarData jarData = jarAnalyzer.getJarData();
- double classVersion = javaClass.getMajor();
- if (javaClass.getMinor() > 0) {
- classVersion = classVersion + javaClass.getMinor() / 10.0;
- }
+ JarVersionedRuntime rootContentVersionedRuntime = runtimeVersionsMap.remove(ROOT);
+ jarData.setRootEntries(rootContentVersionedRuntime.getEntries());
+ JarClasses rootJarClasses = rootContentVersionedRuntime.getJarClasses();
+ jarData.setJarClasses(rootJarClasses);
- if (classVersion > maxVersion) {
- maxVersion = classVersion;
- }
+ jarData.setVersionedRuntimes(new JarVersionedRuntimes(runtimeVersionsMap));
- Method[] methods = javaClass.getMethods();
- for (Method method : methods) {
- classes.addMethod(classSignature + "." + method.getName() + method.getSignature());
- }
+ return rootJarClasses;
+ }
+
+ private JarClasses analyzeRoot(JarAnalyzer jarAnalyzer) {
+ String jarFilename = jarAnalyzer.getFile().getAbsolutePath();
+
+ List<JarEntry> classList = jarAnalyzer.getClassEntries();
- String classPackageName = javaClass.getPackageName();
+ JarClasses classes = analyze(jarFilename, classList);
- classes.addClassName(classSignature);
- classes.addPackage(classPackageName);
+ jarAnalyzer.getJarData().setJarClasses(classes);
+ return classes;
+ }
- ImportVisitor importVisitor = new ImportVisitor(javaClass);
- DescendingVisitor descVisitor = new DescendingVisitor(javaClass, importVisitor);
- javaClass.accept(descVisitor);
+ private JarClasses analyze(String jarFilename, List<JarEntry> classList) {
+ JarClasses classes = new JarClasses();
- classes.addImports(importVisitor.getImports());
- } catch (ClassFormatException e) {
- logger.warn("Unable to process class " + classname + " in JarAnalyzer File " + jarfilename, e);
- } catch (IOException e) {
- logger.warn("Unable to process JarAnalyzer File " + jarfilename, e);
+ classes.setDebugPresent(false);
+
+ double maxVersion = 0.0;
+ double moduleInfoVersion = 0.0;
+
+ for (JarEntry entry : classList) {
+ String classname = entry.getName();
+
+ try {
+ ClassParser classParser = new ClassParser(jarFilename, classname);
+
+ JavaClass javaClass = classParser.parse();
+
+ String classSignature = javaClass.getClassName();
+
+ if (!classes.isDebugPresent()) {
+ if (hasDebugSymbols(javaClass)) {
+ classes.setDebugPresent(true);
+ }
}
- }
- Optional.ofNullable(JAVA_CLASS_VERSIONS.get(maxVersion)).ifPresent(classes::setJdkRevision);
+ double classVersion = javaClass.getMajor();
+ if (javaClass.getMinor() > 0) {
+ classVersion = classVersion + javaClass.getMinor() / 10.0;
+ }
+
+ if ("module-info".equals(classSignature)) {
+ // ignore the module-info.class for computing the maxVersion, since it will always be >= 9
+ moduleInfoVersion = classVersion;
+ } else if (classVersion > maxVersion) {
+ maxVersion = classVersion;
+ }
- jarAnalyzer.getJarData().setJarClasses(classes);
+ Method[] methods = javaClass.getMethods();
+ for (Method method : methods) {
+ classes.addMethod(classSignature + "." + method.getName() + method.getSignature());
+ }
+
+ String classPackageName = javaClass.getPackageName();
+
+ classes.addClassName(classSignature);
+ classes.addPackage(classPackageName);
+
+ ImportVisitor importVisitor = new ImportVisitor(javaClass);
+ DescendingVisitor descVisitor = new DescendingVisitor(javaClass, importVisitor);
+ javaClass.accept(descVisitor);
+
+ classes.addImports(importVisitor.getImports());
+ } catch (ClassFormatException e) {
+ logger.warn("Unable to process class " + classname + " in JarAnalyzer File " + jarFilename, e);
+ } catch (IOException e) {
+ logger.warn("Unable to process JarAnalyzer File " + jarFilename, e);
+ }
+ }
+
+ if (maxVersion == 0.0 && moduleInfoVersion > 0.0) {
+ // the one and only class file was module-info.class
+ maxVersion = moduleInfoVersion;
}
+
+ Optional.ofNullable(JAVA_CLASS_VERSIONS.get(maxVersion)).ifPresent(classes::setJdkRevision);
+
return classes;
}
=====================================
src/main/java/org/apache/maven/shared/jar/classes/JarVersionedRuntime.java
=====================================
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+package org.apache.maven.shared.jar.classes;
+
+import java.util.List;
+import java.util.jar.JarEntry;
+
+public class JarVersionedRuntime {
+
+ /**
+ * The JAR entries.
+ */
+ private final List<JarEntry> entries;
+
+ private final JarClasses jarClasses;
+
+ public JarVersionedRuntime(List<JarEntry> entries, JarClasses jarClasses) {
+ this.entries = entries;
+ this.jarClasses = jarClasses;
+ }
+
+ /**
+ * @return the entries
+ */
+ public List<JarEntry> getEntries() {
+ return entries;
+ }
+
+ /**
+ * @return the jarClasses
+ */
+ public JarClasses getJarClasses() {
+ return jarClasses;
+ }
+
+ public int getNumEntries() {
+ return entries.size();
+ }
+}
=====================================
src/main/java/org/apache/maven/shared/jar/classes/JarVersionedRuntimes.java
=====================================
@@ -0,0 +1,110 @@
+/*
+ * 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.
+ */
+package org.apache.maven.shared.jar.classes;
+
+import java.util.Map.Entry;
+import java.util.NavigableMap;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * Gathered facts about the runtime versions contained within a Multi-Release JAR file.
+ *
+ * @see org.apache.maven.shared.jar.classes.JarClassesAnalysis#analyze(org.apache.maven.shared.jar.JarAnalyzer)
+ */
+public class JarVersionedRuntimes {
+
+ /**
+ * Information about the JAR's Multi-Release entries
+ */
+ private NavigableMap<Integer, JarVersionedRuntime> versionedRuntimeMap;
+
+ public JarVersionedRuntimes(NavigableMap<Integer, JarVersionedRuntime> versionedRuntimeMap) {
+ this.versionedRuntimeMap = versionedRuntimeMap;
+ }
+
+ /**
+ * @return the versionedRuntimeMap
+ */
+ public NavigableMap<Integer, JarVersionedRuntime> getVersionedRuntimeMap() {
+ return versionedRuntimeMap;
+ }
+
+ public JarVersionedRuntime getJarVersionedRuntime(Integer version) {
+ return versionedRuntimeMap.get(version);
+ }
+
+ /**
+ * Return the JarClasses associated to the release.
+ * @param version the release version.
+ * @return the JarClasses.
+ */
+ public JarClasses getJarClasses(Integer version) {
+ return versionedRuntimeMap.get(version).getJarClasses();
+ }
+
+ /**
+ * Get a set of release versions included in the JAR file.
+ * @return a set with the Java versions as Strings.
+ */
+ public Set<Integer> getRuntimeVersionsAsSet() {
+ return versionedRuntimeMap.keySet();
+ }
+
+ /**
+ * Return the highest the JarClasses of the Jdk version that would be executed if they would be executed on a JVM given by the release parameter.
+ * @param version the Jdk version number of the executing JVM.
+ * @return The fittest JarClasses object matching if found one, or null otherwise.
+ * @throws NullPointerException if release is null.
+ */
+ public JarVersionedRuntime getBestFitJarVersionedRuntime(Integer version) {
+ Objects.requireNonNull(version, "version cannot be null");
+ Entry<Integer, JarVersionedRuntime> entry = versionedRuntimeMap.floorEntry(version);
+ if (entry == null) {
+ return null;
+ }
+ return entry.getValue();
+ }
+
+ /**
+ * Return the highest the JarClasses of the Jdk version that would be executed if they would be executed given a System property.
+ * Example values: "java.version.specification" or "java.vm.specification.version".
+ * @param key the System property.
+ * @return The best fitting JarClasses object matching if found one, or null otherwise.
+ * @throws NullPointerException if key is null
+ * @throws IllegalStateException if system property value of key is null
+ * @throws IllegalStateException if system property cannot be converted to Integer
+ */
+ public JarVersionedRuntime getBestFitJarVersionedRuntimeBySystemProperty(String key) {
+ Objects.requireNonNull(key, "key cannot null");
+ String property = System.getProperty(key);
+ if (property == null) {
+ throw new IllegalStateException("The value of the system property '" + key + "' is null");
+ }
+ try {
+ Integer release = Integer.parseInt(property);
+ return getBestFitJarVersionedRuntime(release);
+ } catch (NumberFormatException e) {
+ throw new IllegalStateException(
+ "The value of the system property '" + key + "' [" + property
+ + "] cannot be converted to an Integer",
+ e);
+ }
+ }
+}
=====================================
src/main/java/org/apache/maven/shared/jar/identification/JarIdentificationAnalysis.java
=====================================
@@ -105,7 +105,7 @@ public class JarIdentificationAnalysis {
int size = Integer.MAX_VALUE;
for (String val : list) {
- if (StringUtils.isNotEmpty(val)) {
+ if (val != null && !val.isEmpty()) {
if (val.length() < size) {
smallest = val;
size = val.length();
@@ -120,7 +120,7 @@ public class JarIdentificationAnalysis {
String largest = null;
int size = Integer.MIN_VALUE;
for (String val : list) {
- if (StringUtils.isNotEmpty(val)) {
+ if (val != null && !val.isEmpty()) {
if (val.length() > size) {
largest = val;
size = val.length();
=====================================
src/main/java/org/apache/maven/shared/jar/identification/exposers/TextFileExposer.java
=====================================
@@ -32,7 +32,6 @@ import java.util.jar.JarEntry;
import org.apache.maven.shared.jar.JarAnalyzer;
import org.apache.maven.shared.jar.identification.JarIdentification;
import org.apache.maven.shared.jar.identification.JarIdentificationExposer;
-import org.codehaus.plexus.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -70,7 +69,7 @@ public class TextFileExposer implements JarIdentificationExposer {
// TODO: maybe even for groupId entries.
logger.debug(line);
- if (StringUtils.isNotEmpty(line)) {
+ if (line != null && !line.isEmpty()) {
textVersions.add(line);
}
} catch (IOException e) {
=====================================
src/main/java/org/apache/maven/shared/jar/identification/exposers/TimestampExposer.java
=====================================
@@ -32,7 +32,6 @@ import org.apache.commons.collections4.bag.HashBag;
import org.apache.maven.shared.jar.JarAnalyzer;
import org.apache.maven.shared.jar.identification.JarIdentification;
import org.apache.maven.shared.jar.identification.JarIdentificationExposer;
-import org.codehaus.plexus.util.StringUtils;
/**
* Exposer that examines a a JAR and uses the most recent timestamp as a potential version.
@@ -61,7 +60,7 @@ public class TimestampExposer implements JarIdentificationExposer {
}
}
- if (StringUtils.isNotEmpty(ts)) {
+ if (ts != null && !ts.isEmpty()) {
identification.addVersion(ts);
}
}
=====================================
src/test/java/org/apache/maven/shared/jar/JarAnalyzerTest.java
=====================================
@@ -64,6 +64,18 @@ class JarAnalyzerTest extends AbstractJarAnalyzerTestCase {
assertFalse(jarData.isSealed());
}
+ @Test
+ void testMultiRelease() throws Exception {
+ JarData jarData = getJarData("multi-release-test-0.0.1.jar");
+ assertTrue(jarData.isMultiRelease());
+ }
+
+ @Test
+ void testNotMultiRelease() throws Exception {
+ JarData jarData = getJarData("codec.jar");
+ assertFalse(jarData.isMultiRelease());
+ }
+
@Test
void testMissingFile() {
assertThrows(IOException.class, () -> new JarAnalyzer(new File("foo-bar-this-should-not-exist.jar")));
=====================================
src/test/java/org/apache/maven/shared/jar/classes/JarClassesAnalyzerTest.java
=====================================
@@ -21,9 +21,13 @@ package org.apache.maven.shared.jar.classes;
import javax.inject.Inject;
import java.io.File;
+import java.util.List;
+import java.util.Map;
+import java.util.jar.JarEntry;
import org.apache.maven.shared.jar.AbstractJarAnalyzerTestCase;
import org.apache.maven.shared.jar.JarAnalyzer;
+import org.apache.maven.shared.jar.JarData;
import org.codehaus.plexus.testing.PlexusTest;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
@@ -34,6 +38,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
/**
* JarAnalyzer Classes Test Case
@@ -137,6 +142,244 @@ class JarClassesAnalyzerTest extends AbstractJarAnalyzerTestCase {
assertEquals(expectedRevision, jclass.getJdkRevision());
}
+ @Test
+ void testAnalyzeJarWithModuleInfoClass() throws Exception {
+ JarData jarData = getJarData("tomcat-jni-9.0.75.jar");
+ JarClasses jclass = jarData.getJarClasses();
+ assertEquals("1.8", jclass.getJdkRevision());
+ }
+
+ @Test
+ void testAnalyzeJarWithOnlyModuleInfoClass() throws Exception {
+ JarData jarData = getJarData("module-info-only-test-0.0.1.jar");
+ assertEquals(10, jarData.getNumEntries());
+ // root level information
+ assertEquals(8, jarData.getNumRootEntries());
+ JarClasses jclass = jarData.getJarClasses();
+ assertTrue(jclass.getImports().isEmpty());
+ assertTrue(jclass.getPackages().isEmpty());
+ assertTrue(jclass.getClassNames().isEmpty());
+ assertTrue(jclass.getMethods().isEmpty());
+ assertNull(jclass.getJdkRevision());
+
+ JarVersionedRuntimes jarVersionedRuntimes = jarData.getVersionedRuntimes();
+ assertNotNull(jarVersionedRuntimes);
+ Map<Integer, JarVersionedRuntime> jarVersionedRuntimeMap = jarVersionedRuntimes.getVersionedRuntimeMap();
+ assertNotNull(jarVersionedRuntimeMap);
+ assertEquals(1, jarVersionedRuntimeMap.size()); // 11
+
+ JarVersionedRuntime jarVersionedRuntime11 = jarVersionedRuntimes.getJarVersionedRuntime(11);
+ JarClasses jarClasses11 = jarVersionedRuntime11.getJarClasses();
+ assertEquals("11", jarClasses11.getJdkRevision());
+ assertTrue(jarClasses11.getImports().isEmpty());
+ assertEquals(1, jarClasses11.getPackages().size());
+ assertEquals("", jarClasses11.getPackages().get(0));
+ assertEquals(1, jarClasses11.getClassNames().size());
+ assertTrue(jarClasses11.getMethods().isEmpty());
+ assertEquals(2, jarVersionedRuntime11.getNumEntries());
+ assertEntriesContains(jarVersionedRuntime11.getEntries(), "META-INF/versions/11/module-info.class");
+ }
+
+ @Test
+ void testAnalyzeMultiReleaseJarVersion() throws Exception {
+ JarData jarData = getJarData("multi-release-test-0.0.1.jar");
+ assertEquals(37, jarData.getNumEntries());
+ // root level information
+ assertEquals(17, jarData.getNumRootEntries());
+ JarClasses jclass = jarData.getJarClasses();
+ assertEquals("1.8", jclass.getJdkRevision());
+ assertFalse(jclass.getImports().isEmpty());
+ assertEquals(1, jclass.getPackages().size());
+ assertEquals(1, jclass.getClassNames().size());
+ assertFalse(jclass.getMethods().isEmpty());
+ assertEntriesContains(jarData.getEntries(), "resource.txt");
+
+ JarVersionedRuntimes jarVersionedRuntimes = jarData.getVersionedRuntimes();
+ assertNotNull(jarVersionedRuntimes);
+ Map<Integer, JarVersionedRuntime> jarVersionedRuntimeMap = jarVersionedRuntimes.getVersionedRuntimeMap();
+ assertNotNull(jarVersionedRuntimeMap);
+ assertEquals(2, jarVersionedRuntimeMap.size()); // 9 and 11
+
+ JarVersionedRuntime jarVersionedRuntime9 = jarVersionedRuntimes.getJarVersionedRuntime(9);
+ JarClasses jarClasses9 = jarVersionedRuntime9.getJarClasses();
+ assertEquals("9", jarClasses9.getJdkRevision());
+ assertFalse(jarClasses9.getImports().isEmpty());
+ assertEquals(1, jarClasses9.getPackages().size());
+ assertEquals(1, jarClasses9.getClassNames().size());
+ assertFalse(jarClasses9.getMethods().isEmpty());
+ assertEquals(10, jarVersionedRuntime9.getNumEntries());
+ assertEntriesContains(jarVersionedRuntime9.getEntries(), "META-INF/versions/9/resource.txt");
+
+ JarVersionedRuntime jarVersionedRuntime11 = jarVersionedRuntimes.getJarVersionedRuntime(11);
+ JarClasses jarClasses11 = jarVersionedRuntime11.getJarClasses();
+ assertEquals("11", jarClasses11.getJdkRevision());
+ assertFalse(jarClasses11.getImports().isEmpty());
+ assertEquals(1, jarClasses11.getPackages().size());
+ assertEquals(1, jarClasses11.getClassNames().size());
+ assertFalse(jarClasses11.getMethods().isEmpty());
+ assertEquals(10, jarVersionedRuntime11.getNumEntries());
+ assertEntriesContains(jarVersionedRuntime11.getEntries(), "META-INF/versions/11/resource.txt");
+
+ // test ordering
+ assertEquals("[9, 11]", jarVersionedRuntimeMap.keySet().toString());
+
+ // test best fit
+ try {
+ jarVersionedRuntimes.getBestFitJarVersionedRuntime(null);
+ fail("It should throw an NPE");
+ } catch (NullPointerException e) {
+ assertTrue(true);
+ }
+ assertNull(jarVersionedRuntimes.getBestFitJarVersionedRuntime(8)); // unreal value but good just for testing
+ assertEquals(
+ "9",
+ jarVersionedRuntimes
+ .getBestFitJarVersionedRuntime(9)
+ .getJarClasses()
+ .getJdkRevision());
+ assertEquals(
+ "9",
+ jarVersionedRuntimes
+ .getBestFitJarVersionedRuntime(10)
+ .getJarClasses()
+ .getJdkRevision());
+ assertEquals(
+ "11",
+ jarVersionedRuntimes
+ .getBestFitJarVersionedRuntime(11)
+ .getJarClasses()
+ .getJdkRevision());
+ assertEquals(
+ "11",
+ jarVersionedRuntimes
+ .getBestFitJarVersionedRuntime(20)
+ .getJarClasses()
+ .getJdkRevision());
+
+ try {
+ jarVersionedRuntimes.getBestFitJarVersionedRuntimeBySystemProperty(null);
+ fail("It should throw an NPE");
+ } catch (NullPointerException e) {
+ assertTrue(true);
+ }
+
+ try {
+ getBestFitReleaseBySystemProperty(jarVersionedRuntimes, null);
+ fail("It should throw an NPE");
+ } catch (NullPointerException e) {
+ assertTrue(true);
+ }
+
+ try {
+ getBestFitReleaseBySystemProperty(jarVersionedRuntimes, "xxx");
+ fail("It should throw an ISE");
+ } catch (IllegalStateException e) {
+ assertTrue(true);
+ }
+
+ assertNull(getBestFitReleaseBySystemProperty(jarVersionedRuntimes, "8"));
+ assertEquals(
+ "9",
+ getBestFitReleaseBySystemProperty(jarVersionedRuntimes, "9")
+ .getJarClasses()
+ .getJdkRevision());
+ assertEquals(
+ "9",
+ getBestFitReleaseBySystemProperty(jarVersionedRuntimes, "10")
+ .getJarClasses()
+ .getJdkRevision());
+ assertEquals(
+ "11",
+ getBestFitReleaseBySystemProperty(jarVersionedRuntimes, "11")
+ .getJarClasses()
+ .getJdkRevision());
+ assertEquals(
+ "11",
+ getBestFitReleaseBySystemProperty(jarVersionedRuntimes, "20")
+ .getJarClasses()
+ .getJdkRevision());
+ }
+
+ /**
+ * Exposes issue MSHARED-1413
+ */
+ @Test
+ public void testAnalyzeMultiReleaseJarWithVersion11HasALowerJdkRevisionClass() {
+ try {
+ // Version 11 has one class compiled to target Java 1.8
+ JarData jarData = getJarData("multi-release-version-with-lower-jdk-revision-class-0.0.1.jar");
+ JarClasses jclass = jarData.getJarClasses();
+
+ assertNull(jclass.getJdkRevision());
+
+ JarVersionedRuntimes jarVersionedRuntimes = jarData.getVersionedRuntimes();
+ assertNotNull(jarVersionedRuntimes);
+ Map<Integer, JarVersionedRuntime> jarVersionedRuntimeMap = jarVersionedRuntimes.getVersionedRuntimeMap();
+ assertNotNull(jarVersionedRuntimeMap);
+ assertEquals(1, jarVersionedRuntimeMap.size()); // 11
+
+ JarVersionedRuntime jarVersionedRuntime11 = jarVersionedRuntimes.getJarVersionedRuntime(11);
+ JarClasses jarClasses11 = jarVersionedRuntime11.getJarClasses();
+ assertEquals("1.8", jarClasses11.getJdkRevision());
+ } catch (Exception e) {
+ fail("It should not raise an exception", e);
+ }
+ }
+
+ /**
+ * Ensures no exceptions are raised when versioned content does not contain classes (just resources)
+ */
+ @Test
+ public void testAnalyzeMultiReleaseJarResourcesOnly() {
+ try {
+ JarData jarData = getJarData("multi-release-resources-only-0.0.1.jar");
+ JarClasses jclass = jarData.getJarClasses();
+
+ assertEquals("1.8", jclass.getJdkRevision());
+
+ JarVersionedRuntimes jarVersionedRuntimes = jarData.getVersionedRuntimes();
+ assertNotNull(jarVersionedRuntimes);
+ Map<Integer, JarVersionedRuntime> jarVersionedRuntimeMap = jarVersionedRuntimes.getVersionedRuntimeMap();
+ assertNotNull(jarVersionedRuntimeMap);
+ assertEquals(2, jarVersionedRuntimeMap.size()); // 9 and 11
+
+ JarVersionedRuntime jarVersionedRuntime9 = jarVersionedRuntimes.getJarVersionedRuntime(9);
+ JarClasses jarClasses9 = jarVersionedRuntime9.getJarClasses();
+ // no classes found
+ assertNull(jarClasses9.getJdkRevision());
+
+ JarVersionedRuntime jarVersionedRuntime11 = jarVersionedRuntimes.getJarVersionedRuntime(11);
+ JarClasses jarClasses11 = jarVersionedRuntime11.getJarClasses();
+ // no classes found
+ assertNull(jarClasses11.getJdkRevision());
+ } catch (Exception e) {
+ fail("It should not raise an exception", e);
+ }
+ }
+
+ private void assertEntriesContains(List<JarEntry> list, final String entryToFind) {
+ assertTrue(list.stream().anyMatch(entry -> entry.getName().equals(entryToFind)));
+ }
+
+ private JarVersionedRuntime getBestFitReleaseBySystemProperty(
+ JarVersionedRuntimes jarVersionedRuntimes, String value) {
+ String key = "maven.shared.jar.test.vm";
+ System.setProperty(key, value);
+ return jarVersionedRuntimes.getBestFitJarVersionedRuntimeBySystemProperty(key);
+ }
+
+ private JarData getJarData(String filename) throws Exception {
+ File file = getSampleJar(filename);
+
+ JarAnalyzer jarAnalyzer = new JarAnalyzer(file);
+ JarClasses jclass = analyzer.analyze(jarAnalyzer);
+ JarData jarData = jarAnalyzer.getJarData();
+ assertNotNull(jclass, "JarClasses");
+ assertNotNull(jarData, "JarData");
+
+ return jarData;
+ }
+
private JarClasses getJarClasses(String filename) throws Exception {
File file = getSampleJar(filename);
=====================================
src/test/resources/jars/module-info-only-test-0.0.1.jar
=====================================
Binary files /dev/null and b/src/test/resources/jars/module-info-only-test-0.0.1.jar differ
=====================================
src/test/resources/jars/multi-release-resources-only-0.0.1.jar
=====================================
Binary files /dev/null and b/src/test/resources/jars/multi-release-resources-only-0.0.1.jar differ
=====================================
src/test/resources/jars/multi-release-test-0.0.1.jar
=====================================
Binary files /dev/null and b/src/test/resources/jars/multi-release-test-0.0.1.jar differ
=====================================
src/test/resources/jars/multi-release-version-with-lower-jdk-revision-class-0.0.1.jar
=====================================
Binary files /dev/null and b/src/test/resources/jars/multi-release-version-with-lower-jdk-revision-class-0.0.1.jar differ
=====================================
src/test/resources/jars/tomcat-jni-9.0.75.jar
=====================================
Binary files /dev/null and b/src/test/resources/jars/tomcat-jni-9.0.75.jar differ
View it on GitLab: https://salsa.debian.org/java-team/maven-shared-jar/-/compare/3528475ed2af16c9a17233605f91b51de6b72afd...1a1ee8a4bb47b858dedf8fc9e710f62d31857efc
--
View it on GitLab: https://salsa.debian.org/java-team/maven-shared-jar/-/compare/3528475ed2af16c9a17233605f91b51de6b72afd...1a1ee8a4bb47b858dedf8fc9e710f62d31857efc
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-java-commits/attachments/20241024/fc68dd95/attachment.htm>
More information about the pkg-java-commits
mailing list