[Git][java-team/plexus-archiver][upstream] New upstream version 4.3.0
Emmanuel Bourg (@ebourg)
gitlab at salsa.debian.org
Thu Sep 29 13:33:07 BST 2022
Emmanuel Bourg pushed to branch upstream at Debian Java Maintainers / plexus-archiver
Commits:
fab62d24 by Emmanuel Bourg at 2022-09-29T13:46:13+02:00
New upstream version 4.3.0
- - - - -
27 changed files:
- − .github/workflows/codeql-analysis.yml
- .github/workflows/maven.yml
- .github/workflows/release-drafter.yml
- README.md
- pom.xml
- src/main/java/org/codehaus/plexus/archiver/AbstractArchiver.java
- src/main/java/org/codehaus/plexus/archiver/AbstractUnArchiver.java
- src/main/java/org/codehaus/plexus/archiver/Archiver.java
- src/main/java/org/codehaus/plexus/archiver/diags/DelgatingArchiver.java
- src/main/java/org/codehaus/plexus/archiver/diags/NoOpArchiver.java
- src/main/java/org/codehaus/plexus/archiver/diags/TrackingArchiver.java
- src/main/java/org/codehaus/plexus/archiver/dir/DirectoryArchiver.java
- src/main/java/org/codehaus/plexus/archiver/jar/JarArchiver.java
- src/main/java/org/codehaus/plexus/archiver/jar/JarToolModularJarArchiver.java
- src/main/java/org/codehaus/plexus/archiver/jar/Manifest.java
- src/main/java/org/codehaus/plexus/archiver/tar/TarArchiver.java
- src/main/java/org/codehaus/plexus/archiver/util/Streams.java
- src/main/java/org/codehaus/plexus/archiver/zip/AbstractZipArchiver.java
- src/main/java/org/codehaus/plexus/archiver/zip/ConcurrentJarCreator.java
- src/main/java/org/codehaus/plexus/archiver/zip/ZipResource.java
- src/test/java/org/codehaus/plexus/archiver/DuplicateFilesTest.java
- src/test/java/org/codehaus/plexus/archiver/jar/BaseJarArchiverTest.java
- src/test/java/org/codehaus/plexus/archiver/jar/JarArchiverTest.java
- src/test/java/org/codehaus/plexus/archiver/jar/JarToolModularJarArchiverTest.java
- src/test/java/org/codehaus/plexus/archiver/zip/ArchiveFileComparator.java
- src/test/java/org/codehaus/plexus/archiver/zip/ConcurrentJarCreatorTest.java
- src/test/java/org/codehaus/plexus/archiver/zip/ZipArchiverTest.java
Changes:
=====================================
.github/workflows/codeql-analysis.yml deleted
=====================================
@@ -1,67 +0,0 @@
-# For most projects, this workflow file will not need changing; you simply need
-# to commit it to your repository.
-#
-# You may wish to alter this file to override the set of languages analyzed,
-# or to provide custom queries or build logic.
-#
-# ******** NOTE ********
-# We have attempted to detect the languages in your repository. Please check
-# the `language` matrix defined below to confirm you have the correct set of
-# supported CodeQL languages.
-#
-name: "CodeQL"
-
-on:
- push:
- branches: [ master ]
- pull_request:
- # The branches below must be a subset of the branches above
- branches: [ master ]
- schedule:
- - cron: '29 9 * * 5'
-
-jobs:
- analyze:
- name: Analyze
- runs-on: ubuntu-latest
-
- strategy:
- fail-fast: false
- matrix:
- language: [ 'java' ]
- # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
- # Learn more:
- # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
-
- steps:
- - name: Checkout repository
- uses: actions/checkout at v2.4.0
-
- # Initializes the CodeQL tools for scanning.
- - name: Initialize CodeQL
- uses: github/codeql-action/init at v1
- with:
- languages: ${{ matrix.language }}
- # If you wish to specify custom queries, you can do so here or in a config file.
- # By default, queries listed here will override any specified in a config file.
- # Prefix the list here with "+" to use these queries and those in the config file.
- # queries: ./path/to/local/query, your-org/your-repo/queries at main
-
- # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
- # If this step fails, then you should remove it and run the build manually (see below)
- - name: Autobuild
- uses: github/codeql-action/autobuild at v1
-
- # ℹ️ Command-line programs to run using the OS shell..
- # 📚 https://git.io/JvXDl
-
- # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
- # and modify them (or add more) to build your code if your project
- # uses a compiled language
-
- #- run: |
- # make bootstrap
- # make release
-
- - name: Perform CodeQL Analysis
- uses: github/codeql-action/analyze at v1
=====================================
.github/workflows/maven.yml
=====================================
@@ -35,9 +35,9 @@ jobs:
os: 'ubuntu-latest'
steps:
- name: Checkout
- uses: actions/checkout at v2.4.0
+ uses: actions/checkout at v3
- name: Set up JDK ${{ matrix.Java }} (${{ matrix.distribution }})
- uses: actions/setup-java at v2
+ uses: actions/setup-java at v3
with:
distribution: ${{ matrix.distribution }}
java-version: ${{ matrix.java }}
=====================================
.github/workflows/release-drafter.yml
=====================================
@@ -7,6 +7,6 @@ jobs:
update_release_draft:
runs-on: ubuntu-latest
steps:
- - uses: release-drafter/release-drafter at v5.15.0
+ - uses: release-drafter/release-drafter at v5.20.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
=====================================
README.md
=====================================
@@ -3,7 +3,7 @@ Plexus-archiver
[](http://www.apache.org/licenses/)
[](https://search.maven.org/artifact/org.codehaus.plexus/plexus-archiver)
-[](https://travis-ci.org/codehaus-plexus/plexus-archiver)
+[](https://github.com/codehaus-plexus/plexus-archiver/actions/workflows/maven.yml)
[](https://github.com/jvm-repo-rebuild/reproducible-central#org.codehaus.plexus:plexus-archiver)
The current master is now at https://github.com/codehaus-plexus/plexus-archiver
=====================================
pom.xml
=====================================
@@ -6,18 +6,18 @@
<parent>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus</artifactId>
- <version>8</version>
+ <version>10</version>
</parent>
<artifactId>plexus-archiver</artifactId>
- <version>4.2.7</version>
+ <version>4.3.0</version>
<name>Plexus Archiver Component</name>
<scm>
<connection>scm:git:git at github.com:codehaus-plexus/plexus-archiver.git</connection>
<developerConnection>scm:git:git at github.com:codehaus-plexus/plexus-archiver.git</developerConnection>
<url>http://github.com/codehaus-plexus/plexus-archiver/tree/${project.scm.tag}/</url>
- <tag>plexus-archiver-4.2.7</tag>
+ <tag>plexus-archiver-4.3.0</tag>
</scm>
<issueManagement>
<system>jira</system>
@@ -31,8 +31,8 @@
</distributionManagement>
<properties>
- <javaVersion>7</javaVersion>
- <project.build.outputTimestamp>2022-01-02T11:11:33Z</project.build.outputTimestamp>
+ <javaVersion>8</javaVersion>
+ <project.build.outputTimestamp>2022-06-10T17:04:44Z</project.build.outputTimestamp>
</properties>
<contributors>
@@ -49,37 +49,45 @@
</contributors>
<dependencies>
+ <!-- Plexus dependencies -->
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-container-default</artifactId>
- <version>1.0-alpha-30</version>
+ <version>2.1.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-utils</artifactId>
- <version>3.4.1</version>
+ <version>3.4.2</version>
</dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-io</artifactId>
- <version>3.2.0</version>
+ <version>3.3.1</version>
+ </dependency>
+ <!-- Apache Commons dependencies -->
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ <version>2.11.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>1.21</version>
</dependency>
+ <!-- Other dependencies -->
<dependency>
<groupId>org.iq80.snappy</groupId>
<artifactId>snappy</artifactId>
<version>0.4</version>
</dependency>
<dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>4.13.2</version>
- <scope>test</scope>
+ <groupId>org.tukaani</groupId>
+ <artifactId>xz</artifactId>
+ <version>1.9</version>
+ <scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.google.code.findbugs</groupId>
@@ -87,15 +95,15 @@
<version>3.0.2</version>
<scope>provided</scope>
</dependency>
+ <!-- Test dependencies -->
<dependency>
- <groupId>org.tukaani</groupId>
- <artifactId>xz</artifactId>
- <version>1.9</version>
- <scope>runtime</scope>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.13.2</version>
+ <scope>test</scope>
</dependency>
</dependencies>
-
<build>
<plugins>
<plugin>
=====================================
src/main/java/org/codehaus/plexus/archiver/AbstractArchiver.java
=====================================
@@ -22,6 +22,7 @@
import java.lang.reflect.UndeclaredThrowableException;
import java.nio.charset.Charset;
import java.nio.file.Files;
+import java.nio.file.attribute.FileTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
@@ -107,10 +108,7 @@
*/
private boolean useJvmChmod = true;
- /**
- * @since 4.2.0
- */
- private Date lastModifiedDate;
+ private FileTime lastModifiedTime;
/**
* @since 4.2.0
@@ -1208,16 +1206,36 @@ public void setIgnorePermissions( final boolean ignorePermissions )
this.ignorePermissions = ignorePermissions;
}
+ /**
+ * @deprecated Use {@link #setLastModifiedTime(FileTime)} instead.
+ */
@Override
+ @Deprecated
public void setLastModifiedDate( Date lastModifiedDate )
{
- this.lastModifiedDate = lastModifiedDate;
+ this.lastModifiedTime = lastModifiedDate != null ? FileTime.fromMillis( lastModifiedDate.getTime() ) : null;
}
+ /**
+ * @deprecated Use {@link #getLastModifiedTime()} instead.
+ */
@Override
+ @Deprecated
public Date getLastModifiedDate()
{
- return lastModifiedDate;
+ return lastModifiedTime != null ? new Date( lastModifiedTime.toMillis() ) : null;
+ }
+
+ @Override
+ public void setLastModifiedTime( FileTime lastModifiedTime )
+ {
+ this.lastModifiedTime = lastModifiedTime;
+ }
+
+ @Override
+ public FileTime getLastModifiedTime()
+ {
+ return lastModifiedTime;
}
@Override
@@ -1279,11 +1297,21 @@ public String getOverrideGroupName()
return overrideGroupName;
}
+ /**
+ * @deprecated Use {@link #configureReproducibleBuild(FileTime)} instead.
+ */
@Override
+ @Deprecated
public void configureReproducible( Date lastModifiedDate )
+ {
+ configureReproducibleBuild( FileTime.fromMillis( lastModifiedDate.getTime() ) );
+ }
+
+ @Override
+ public void configureReproducibleBuild( FileTime lastModifiedTime )
{
// 1. force last modified date
- setLastModifiedDate( normalizeLastModifiedDate( lastModifiedDate ) );
+ setLastModifiedTime( normalizeLastModifiedTime ( lastModifiedTime ) );
// 2. sort filenames in each directory when scanning filesystem
setFilenameComparator( new Comparator<String>()
@@ -1309,14 +1337,18 @@ public int compare( String s1, String s2 )
/**
* Normalize last modified time value to get reproducible archive entries, based on
- * archive binary format (tar uses UTC timestamp but zip uses local time then requires
- * tweaks to make the value reproducible whatever the current timezone is).
+ * archive binary format.
+ *
+ * <p>tar uses UTC timestamp, but zip uses local time then requires
+ * tweaks to make the value reproducible whatever the current timezone is.
+ *
+ * @param lastModifiedTime The last modification time
+ * @return The normalized last modification time
*
- * @param lastModifiedDate
- * @return
+ * @see #configureReproducibleBuild(FileTime)
*/
- protected Date normalizeLastModifiedDate( Date lastModifiedDate )
+ protected FileTime normalizeLastModifiedTime( FileTime lastModifiedTime )
{
- return lastModifiedDate;
+ return lastModifiedTime;
}
}
=====================================
src/main/java/org/codehaus/plexus/archiver/AbstractUnArchiver.java
=====================================
@@ -25,6 +25,7 @@
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
+import java.util.Locale;
import org.codehaus.plexus.archiver.util.ArchiveEntryUtils;
import org.codehaus.plexus.components.io.attributes.SymlinkUtils;
@@ -412,7 +413,7 @@ protected boolean shouldExtractEntry( File targetDirectory, File targetFileName,
boolean fileOnDiskIsNewerThanEntry = targetFileName.lastModified() >= entryDate.getTime();
boolean differentCasing = !entryName.equals( relativeCanonicalDestPath );
- String casingMessage = String.format( "Archive entry '%s' and existing file '%s' names differ only by case."
+ String casingMessage = String.format( Locale.ENGLISH, "Archive entry '%s' and existing file '%s' names differ only by case."
+ " This may lead to an unexpected outcome on case-insensitive filesystems.", entryName, canonicalDestPath );
// (1)
=====================================
src/main/java/org/codehaus/plexus/archiver/Archiver.java
=====================================
@@ -19,11 +19,13 @@
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
+import java.nio.file.attribute.FileTime;
import java.util.Comparator;
import java.util.Date;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
+
import javax.annotation.Nonnull;
import org.codehaus.plexus.components.io.resources.PlexusIoResource;
import org.codehaus.plexus.components.io.resources.PlexusIoResourceCollection;
@@ -390,14 +392,38 @@ ResourceIterator getResources()
*
* @param lastModifiedDate
* @since 4.2.0
+ * @deprecated Use {@link #setLastModifiedTime(FileTime)} instead
*/
+ @Deprecated
void setLastModifiedDate( final Date lastModifiedDate );
/**
* @since 4.2.0
+ * @deprecated Use {@link #getLastModifiedTime()} instead
*/
+ @Deprecated
Date getLastModifiedDate();
+ /**
+ * Sets the last modification time of the entries (if non null).
+ *
+ * @param lastModifiedTime to set in the archive entries
+ *
+ * @see #getLastModifiedTime()
+ * @since 4.3.0
+ */
+ void setLastModifiedTime( final FileTime lastModifiedTime );
+
+ /**
+ * Returns the last modification time of the archiver.
+ *
+ * @return The last modification time of the archiver, null if not specified
+ *
+ * @see #setLastModifiedTime(FileTime)
+ * @since 4.3.0
+ */
+ FileTime getLastModifiedTime();
+
/**
* Set filename comparator, used to sort file entries when scanning directories since File.list() does not
* guarantee any order.
@@ -446,6 +472,17 @@ ResourceIterator getResources()
*/
String getOverrideGroupName();
+ /**
+ * This method is obsolete and will just call {@link #configureReproducibleBuild(FileTime)}
+ * with the Date transformed into FileTime.
+ *
+ * @param lastModifiedDate the date to use for archive entries last modified time
+ * @since 4.2.0
+ * @deprecated Use {@link #configureReproducibleBuild(FileTime)} instead.
+ */
+ @Deprecated
+ void configureReproducible( Date lastModifiedDate );
+
/**
* Configure the archiver to create archives in a reproducible way (see
* <a href="https://reproducible-builds.org/">Reproducible Builds</a>).
@@ -455,9 +492,11 @@ ResourceIterator getResources()
* <li>defined entries timestamp</li>
* <li>and reproducible entries Unix mode.</li>
* </ul>
- *
- * @param lastModifiedDate the date to use for archive entries last modified time
- * @since 4.2.0
+ *
+ * @param lastModifiedTime The last modification time of the entries
+ *
+ * @see <a href="https://reproducible-builds.org/">Reproducible Builds</a>
+ * @since 4.3.0
*/
- void configureReproducible( Date lastModifiedDate );
+ void configureReproducibleBuild( FileTime lastModifiedTime );
}
=====================================
src/main/java/org/codehaus/plexus/archiver/diags/DelgatingArchiver.java
=====================================
@@ -18,6 +18,7 @@
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
+import java.nio.file.attribute.FileTime;
import java.util.Comparator;
import java.util.Date;
import java.util.Map;
@@ -333,18 +334,38 @@ public void setIgnorePermissions( boolean ignorePermissions )
target.setIgnorePermissions( ignorePermissions );
}
+ /**
+ * @deprecated Use {@link #setLastModifiedTime(FileTime)} instead.
+ */
@Override
+ @Deprecated
public void setLastModifiedDate( final Date lastModifiedDate )
{
target.setLastModifiedDate( lastModifiedDate );
}
+ /**
+ * @deprecated Use {@link #getLastModifiedTime()} instead.
+ */
@Override
+ @Deprecated
public Date getLastModifiedDate()
{
return target.getLastModifiedDate();
}
+ @Override
+ public void setLastModifiedTime( final FileTime lastModifiedTime )
+ {
+ target.setLastModifiedTime( lastModifiedTime );
+ }
+
+ @Override
+ public FileTime getLastModifiedTime()
+ {
+ return target.getLastModifiedTime();
+ }
+
@Override
public void setFilenameComparator( final Comparator<String> filenameComparator )
{
@@ -399,10 +420,20 @@ public String getOverrideGroupName()
return target.getOverrideGroupName();
}
+ /**
+ * @deprecated Use {@link #configureReproducibleBuild(FileTime)} instead.
+ */
@Override
+ @Deprecated
public void configureReproducible( Date lastModifiedDate )
{
target.configureReproducible( lastModifiedDate );
}
+ @Override
+ public void configureReproducibleBuild( FileTime lastModifiedTime )
+ {
+ target.configureReproducibleBuild( lastModifiedTime );
+ }
+
}
=====================================
src/main/java/org/codehaus/plexus/archiver/diags/NoOpArchiver.java
=====================================
@@ -18,6 +18,7 @@
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
+import java.nio.file.attribute.FileTime;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
@@ -348,18 +349,38 @@ public void setIgnorePermissions( boolean ignorePermissions )
this.ignorePermissions = ignorePermissions;
}
+ /**
+ * @deprecated Use {@link #setLastModifiedTime(FileTime)} instead.
+ */
@Override
+ @Deprecated
public void setLastModifiedDate( final Date lastModifiedDate )
{
}
+ /**
+ * @deprecated Use {@link #getLastModifiedTime()} instead.
+ */
@Override
+ @Deprecated
public Date getLastModifiedDate()
{
return null;
}
+ @Override
+ public void setLastModifiedTime( final FileTime lastModifiedTime )
+ {
+
+ }
+
+ @Override
+ public FileTime getLastModifiedTime()
+ {
+ return null;
+ }
+
@Override
public void setFilenameComparator( final Comparator<String> filenameComparator )
{
@@ -414,10 +435,20 @@ public String getOverrideGroupName()
return null;
}
+ /**
+ * @deprecated Use {@link #configureReproducibleBuild(FileTime)} instead.
+ */
@Override
+ @Deprecated
public void configureReproducible( Date lastModifiedDate )
{
}
+ @Override
+ public void configureReproducibleBuild( FileTime lastModifiedTime )
+ {
+
+ }
+
}
=====================================
src/main/java/org/codehaus/plexus/archiver/diags/TrackingArchiver.java
=====================================
@@ -18,16 +18,19 @@
*/
package org.codehaus.plexus.archiver.diags;
+import javax.annotation.Nonnull;
+
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
+import java.nio.file.attribute.FileTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import javax.annotation.Nonnull;
+
import org.codehaus.plexus.archiver.ArchiveEntry;
import org.codehaus.plexus.archiver.ArchivedFileSet;
import org.codehaus.plexus.archiver.Archiver;
@@ -54,7 +57,7 @@
private boolean ignorePermissions;
- private Date lastModified;
+ private FileTime lastModifiedTime;
private Comparator<String> filenameComparator;
@@ -406,18 +409,37 @@ public void setIgnorePermissions( final boolean ignorePermissions )
this.ignorePermissions = ignorePermissions;
}
+ /**
+ * @deprecated Use {@link #setLastModifiedTime(FileTime)} instead.
+ */
@Override
+ @Deprecated
public void setLastModifiedDate( final Date lastModifiedDate )
{
- this.lastModified = lastModifiedDate;
+ this.lastModifiedTime = lastModifiedDate != null ? FileTime.fromMillis( lastModifiedDate.getTime() ) : null;
}
+ /**
+ * @deprecated Use {@link #getLastModifiedTime()} instead.
+ */
@Override
+ @Deprecated
public Date getLastModifiedDate()
{
- return lastModified;
+ return lastModifiedTime != null ? new Date( lastModifiedTime.toMillis() ) : null;
}
+ @Override
+ public void setLastModifiedTime( final FileTime lastModifiedTime )
+ {
+ this.lastModifiedTime = lastModifiedTime;
+ }
+
+ @Override
+ public FileTime getLastModifiedTime()
+ {
+ return lastModifiedTime;
+ }
@Override
public void setFilenameComparator( final Comparator<String> filenameComparator )
@@ -425,6 +447,11 @@ public void setFilenameComparator( final Comparator<String> filenameComparator )
this.filenameComparator = filenameComparator;
}
+ public Comparator<String> getFilenameComparator()
+ {
+ return filenameComparator;
+ }
+
@Override
public void setOverrideUid( int uid )
{
@@ -469,8 +496,17 @@ public String getOverrideGroupName()
return null;
}
+ /**
+ * @deprecated Use {@link #configureReproducibleBuild(FileTime)} instead.
+ */
@Override
+ @Deprecated
public void configureReproducible( Date lastModifiedDate )
{
}
+
+ @Override
+ public void configureReproducibleBuild( FileTime lastModifiedTime )
+ {
+ }
}
=====================================
src/main/java/org/codehaus/plexus/archiver/dir/DirectoryArchiver.java
=====================================
@@ -17,6 +17,8 @@
import java.io.File;
import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.attribute.FileTime;
import java.util.ArrayList;
import java.util.List;
import org.codehaus.plexus.archiver.AbstractArchiver;
@@ -37,7 +39,7 @@
extends AbstractArchiver
{
- private final List<Runnable> directoryChmods = new ArrayList<Runnable>();
+ private final List<Runnable> directoryChmods = new ArrayList<>();
public void resetArchiver()
throws IOException
@@ -101,10 +103,7 @@ public void execute()
}
}
- for ( Runnable directoryChmod : directoryChmods )
- {
- directoryChmod.run();
- }
+ directoryChmods.forEach( Runnable::run );
directoryChmods.clear();
}
catch ( final IOException ioe )
@@ -167,15 +166,15 @@ else if ( !outFile.mkdirs() )
throw new ArchiverException( "Unable to create directory or parent directory of " + outFile );
}
- directoryChmods.add( new Runnable()
- {
-
- @Override
- public void run()
+ directoryChmods.add( () -> {
+ try
{
setFileModes( entry, outFile, inLastModified );
}
-
+ catch ( IOException e )
+ {
+ throw new ArchiverException( "Failed setting file attributes", e );
+ }
} );
}
@@ -194,21 +193,23 @@ private static void makeParentDirectories( File file ) {
}
private void setFileModes( ArchiveEntry entry, File outFile, long inLastModified )
+ throws IOException
{
if ( !isIgnorePermissions() )
{
ArchiveEntryUtils.chmod( outFile, entry.getMode() );
}
- if ( getLastModifiedDate() == null )
+ if ( getLastModifiedTime() == null )
{
- outFile.setLastModified( inLastModified == PlexusIoResource.UNKNOWN_MODIFICATION_DATE
- ? System.currentTimeMillis()
- : inLastModified );
+ FileTime fromMillis = FileTime.fromMillis( inLastModified == PlexusIoResource.UNKNOWN_MODIFICATION_DATE
+ ? System.currentTimeMillis()
+ : inLastModified );
+ Files.setLastModifiedTime( outFile.toPath(), fromMillis );
}
else
{
- outFile.setLastModified( getLastModifiedDate().getTime() );
+ Files.setLastModifiedTime( outFile.toPath(), getLastModifiedTime() );
}
}
=====================================
src/main/java/org/codehaus/plexus/archiver/jar/JarArchiver.java
=====================================
@@ -27,6 +27,7 @@
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@@ -37,7 +38,6 @@
import java.util.SortedMap;
import java.util.StringTokenizer;
import java.util.TreeMap;
-import java.util.Vector;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
@@ -139,12 +139,12 @@
* <p/>
* Will not be filled unless the user has asked for an index.
*/
- private Vector<String> rootEntries;
+ private List<String> rootEntries;
/**
* Path containing jars that shall be indexed in addition to this archive.
*/
- private ArrayList<String> indexJars;
+ private List<String> indexJars;
/**
* Creates a minimal default manifest with {@code Manifest-Version: 1.0} only.
@@ -159,7 +159,7 @@ public JarArchiver()
super();
archiveType = "jar";
setEncoding( "UTF8" );
- rootEntries = new Vector<String>();
+ rootEntries = new ArrayList<>();
}
/**
@@ -299,7 +299,7 @@ public void addConfiguredIndexJars( File indexJar )
{
if ( indexJars == null )
{
- indexJars = new ArrayList<String>();
+ indexJars = new ArrayList<>();
}
indexJars.add( indexJar.getAbsolutePath() );
}
@@ -373,13 +373,14 @@ private void writeManifest( ConcurrentJarCreator zOut, Manifest manifest )
}
zipDir( null, zOut, "META-INF/", DEFAULT_DIR_MODE, getEncoding() );
+
// time to write the manifest
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ByteArrayOutputStream baos = new ByteArrayOutputStream( 128 );
manifest.write( baos );
+ InputStreamSupplier in = () -> new ByteArrayInputStream( baos.toByteArray() );
- ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
- super.zipFile( createInputStreamSupplier( bais ), zOut, MANIFEST_NAME, System.currentTimeMillis(), null,
- DEFAULT_FILE_MODE, null, false );
+ super.zipFile( in, zOut, MANIFEST_NAME, System.currentTimeMillis(), null, DEFAULT_FILE_MODE, null,
+ false );
super.initZipOutputStream( zOut );
}
@@ -408,9 +409,9 @@ protected void finalizeZipOutputStream( ConcurrentJarCreator zOut )
private void createIndexList( ConcurrentJarCreator zOut )
throws IOException, ArchiverException
{
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ByteArrayOutputStream baos = new ByteArrayOutputStream( 128 );
// encoding must be UTF8 as specified in the specs.
- PrintWriter writer = new PrintWriter( new OutputStreamWriter( baos, "UTF8" ) );
+ PrintWriter writer = new PrintWriter( new OutputStreamWriter( baos, StandardCharsets.UTF_8 ) );
// version-info blankline
writer.println( "JarIndex-Version: 1.0" );
@@ -440,7 +441,7 @@ private void createIndexList( ConcurrentJarCreator zOut )
filteredDirs.remove( META_INF_NAME + '/' );
}
}
- writeIndexLikeList( new ArrayList<String>( filteredDirs ), rootEntries, writer );
+ writeIndexLikeList( new ArrayList<>( filteredDirs ), rootEntries, writer );
writer.println();
if ( indexJars != null )
@@ -464,8 +465,8 @@ private void createIndexList( ConcurrentJarCreator zOut )
String name = findJarName( indexJar, cpEntries );
if ( name != null )
{
- ArrayList<String> dirs = new ArrayList<String>();
- ArrayList<String> files = new ArrayList<String>();
+ List<String> dirs = new ArrayList<>();
+ List<String> files = new ArrayList<>();
grabFilesAndDirs( indexJar, dirs, files );
if ( dirs.size() + files.size() > 0 )
{
@@ -479,9 +480,9 @@ private void createIndexList( ConcurrentJarCreator zOut )
writer.flush();
- ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
+ InputStreamSupplier in = () -> new ByteArrayInputStream( baos.toByteArray() );
- super.zipFile( createInputStreamSupplier( bais ), zOut, INDEX_NAME, System.currentTimeMillis(), null,
+ super.zipFile( in, zOut, INDEX_NAME, System.currentTimeMillis(), null,
DEFAULT_FILE_MODE, null, true );
}
@@ -511,9 +512,9 @@ else if ( INDEX_NAME.equalsIgnoreCase( vPath ) && index )
}
else
{
- if ( index && ( !vPath.contains( "/" ) ) )
+ if ( index && !vPath.contains( "/" ) )
{
- rootEntries.addElement( vPath );
+ rootEntries.add( vPath );
}
super.zipFile( is, zOut, vPath, lastModified, fromArchive, mode, symlinkDestination, addInParallel );
}
@@ -624,7 +625,7 @@ protected void cleanUp()
filesetManifest = null;
originalManifest = null;
}
- rootEntries.removeAllElements();
+ rootEntries.clear();
}
/**
@@ -722,21 +723,9 @@ protected static String findJarName( String fileName, String[] classpath )
return new File( fileName ).getName();
}
fileName = fileName.replace( File.separatorChar, '/' );
- SortedMap<String, String> matches = new TreeMap<String, String>( new Comparator<String>()
- {
- // longest match comes first
- @Override
- public int compare( String o1, String o2 )
- {
- if ( ( o1 != null ) && ( o2 != null ) )
- {
- return o2.length() - o1.length();
- }
- return 0;
- }
-
- } );
+ // longest match comes first
+ SortedMap<String, String> matches = new TreeMap<>( Comparator.comparingInt( String::length ).reversed() );
for ( String aClasspath : classpath )
{
@@ -825,4 +814,22 @@ else if ( !name.contains( "/" ) )
}
}
+ /**
+ * Override the behavior of the Zip Archiver to match the output of the JAR tool.
+ *
+ * @param zipEntry to set the last modified time
+ * @param lastModifiedTime to set in the zip entry only if {@link #getLastModifiedTime()} returns null
+ */
+ @Override
+ protected void setZipEntryTime( ZipArchiveEntry zipEntry, long lastModifiedTime )
+ {
+ if ( getLastModifiedTime() != null )
+ {
+ lastModifiedTime = getLastModifiedTime().toMillis();
+ }
+
+ // The JAR tool does not round up, so we keep that behavior here (JDK-8277755).
+ zipEntry.setTime( lastModifiedTime );
+ }
+
}
=====================================
src/main/java/org/codehaus/plexus/archiver/jar/JarToolModularJarArchiver.java
=====================================
@@ -16,17 +16,30 @@
*/
package org.codehaus.plexus.archiver.jar;
-import org.apache.commons.compress.parallel.InputStreamSupplier;
-import org.codehaus.plexus.archiver.ArchiverException;
-import org.codehaus.plexus.archiver.zip.ConcurrentJarCreator;
-
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
+import java.lang.reflect.Method;
import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardCopyOption;
+import java.nio.file.attribute.FileTime;
import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Enumeration;
import java.util.List;
+import java.util.Locale;
+import java.util.TimeZone;
import java.util.regex.Pattern;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+import java.util.zip.ZipOutputStream;
+
+import org.apache.commons.compress.parallel.InputStreamSupplier;
+import org.apache.commons.io.output.NullPrintStream;
+import org.codehaus.plexus.archiver.ArchiverException;
+import org.codehaus.plexus.archiver.zip.ConcurrentJarCreator;
+import org.codehaus.plexus.util.IOUtil;
/**
* A {@link ModularJarArchiver} implementation that uses
@@ -58,6 +71,8 @@
private boolean moduleDescriptorFound;
+ private boolean hasJarDateOption;
+
public JarToolModularJarArchiver()
{
try
@@ -111,18 +126,30 @@ protected void postCreateArchive()
getLogger().debug( "Using the jar tool to " +
"update the archive to modular JAR." );
- Integer result = (Integer) jarTool.getClass()
- .getMethod( "run",
- PrintStream.class, PrintStream.class, String[].class )
- .invoke( jarTool,
- System.out, System.err,
- getJarToolArguments() );
+ final Method jarRun = jarTool.getClass()
+ .getMethod( "run", PrintStream.class, PrintStream.class, String[].class );
+
+ if ( getLastModifiedTime() != null )
+ {
+ hasJarDateOption = isJarDateOptionSupported( jarRun );
+ getLogger().debug( "jar tool --date option is supported: " + hasJarDateOption );
+ }
+
+ Integer result = (Integer) jarRun.invoke( jarTool, System.out, System.err, getJarToolArguments() );
if ( result != null && result != 0 )
{
throw new ArchiverException( "Could not create modular JAR file. " +
"The JDK jar tool exited with " + result );
}
+
+ if ( !hasJarDateOption && getLastModifiedTime() != null )
+ {
+ getLogger().debug( "Fix last modified time zip entries." );
+ // --date option not supported, fallback to rewrite the JAR file
+ // https://github.com/codehaus-plexus/plexus-archiver/issues/164
+ fixLastModifiedTimeZipEntries();
+ }
}
catch ( IOException | ReflectiveOperationException | SecurityException e )
{
@@ -131,6 +158,36 @@ protected void postCreateArchive()
}
}
+ /**
+ * Fallback to rewrite the JAR file with the correct timestamp if the {@code --date} option is not available.
+ */
+ private void fixLastModifiedTimeZipEntries()
+ throws IOException
+ {
+ long timeMillis = getLastModifiedTime().toMillis();
+ Path destFile = getDestFile().toPath();
+ Path tmpZip = Files.createTempFile( destFile.getParent(), null, null );
+ try ( ZipFile zipFile = new ZipFile( getDestFile() );
+ ZipOutputStream out = new ZipOutputStream( Files.newOutputStream( tmpZip ) ) )
+ {
+ Enumeration<? extends ZipEntry> entries = zipFile.entries();
+ while ( entries.hasMoreElements() )
+ {
+ ZipEntry entry = entries.nextElement();
+ // Not using setLastModifiedTime(FileTime) as it sets the extended timestamp
+ // which is not compatible with the jar tool output.
+ entry.setTime( timeMillis );
+ out.putNextEntry( entry );
+ if ( !entry.isDirectory() )
+ {
+ IOUtil.copy( zipFile.getInputStream( entry ), out );
+ }
+ out.closeEntry();
+ }
+ }
+ Files.move( tmpZip, destFile, StandardCopyOption.REPLACE_EXISTING );
+ }
+
/**
* Returns {@code true} if {@code path}
* is a module descriptor.
@@ -201,6 +258,14 @@ private String[] getJarToolArguments()
args.add( "--no-compress" );
}
+ if ( hasJarDateOption )
+ {
+ // The --date option already normalize the time, so revert to the local time
+ FileTime localTime = revertToLocalTime( getLastModifiedTime() );
+ args.add( "--date" );
+ args.add( localTime.toString() );
+ }
+
args.add( "-C" );
args.add( tempEmptyDir.getAbsolutePath() );
args.add( "." );
@@ -208,4 +273,36 @@ private String[] getJarToolArguments()
return args.toArray( new String[0] );
}
+ private static FileTime revertToLocalTime( FileTime time )
+ {
+ long restoreToLocalTime = time.toMillis();
+ Calendar cal = Calendar.getInstance( TimeZone.getDefault(), Locale.ROOT );
+ cal.setTimeInMillis( restoreToLocalTime );
+ restoreToLocalTime = restoreToLocalTime + ( cal.get( Calendar.ZONE_OFFSET ) + cal.get( Calendar.DST_OFFSET ) );
+ return FileTime.fromMillis( restoreToLocalTime );
+ }
+
+ /**
+ * Check support for {@code --date} option introduced since Java 17.0.3 (JDK-8279925).
+ *
+ * @return true if the JAR tool supports the {@code --date} option
+ */
+ private boolean isJarDateOptionSupported( Method runMethod )
+ {
+ try
+ {
+ // Test the output code validating the --date option.
+ String[] args = { "--date", "2099-12-31T23:59:59Z", "--version" };
+
+ PrintStream nullPrintStream = NullPrintStream.NULL_PRINT_STREAM;
+ Integer result = (Integer) runMethod.invoke( jarTool, nullPrintStream, nullPrintStream, args );
+
+ return result != null && result.intValue() == 0;
+ }
+ catch ( ReflectiveOperationException | SecurityException e )
+ {
+ return false;
+ }
+ }
+
}
=====================================
src/main/java/org/codehaus/plexus/archiver/jar/Manifest.java
=====================================
@@ -510,7 +510,7 @@ public Iterator<String> iterator()
*/
public Attribute getAttribute( String attributeName )
{
- return attributes.get( attributeName.toLowerCase() );
+ return attributes.get( attributeName.toLowerCase( Locale.ENGLISH ) );
}
/**
=====================================
src/main/java/org/codehaus/plexus/archiver/tar/TarArchiver.java
=====================================
@@ -283,7 +283,7 @@ else if ( longFileMode.isFailMode() )
te = new TarArchiveEntry( vPath );
}
- if ( getLastModifiedDate() == null )
+ if ( getLastModifiedTime() == null )
{
long teLastModified = entry.getResource().getLastModified();
te.setModTime( teLastModified == PlexusIoResource.UNKNOWN_MODIFICATION_DATE
@@ -292,7 +292,7 @@ else if ( longFileMode.isFailMode() )
}
else
{
- te.setModTime( getLastModifiedDate() );
+ te.setModTime( getLastModifiedTime().toMillis() );
}
if ( entry.getType() == ArchiveEntry.SYMLINK )
=====================================
src/main/java/org/codehaus/plexus/archiver/util/Streams.java
=====================================
@@ -17,6 +17,7 @@
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
+import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
@@ -32,6 +33,8 @@
public class Streams
{
+ public static final InputStream EMPTY_INPUTSTREAM = new ByteArrayInputStream( new byte[0] );
+
public static BufferedInputStream bufferedInputStream( InputStream is )
{
return is instanceof BufferedInputStream
=====================================
src/main/java/org/codehaus/plexus/archiver/zip/AbstractZipArchiver.java
=====================================
@@ -22,15 +22,18 @@
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
-import java.io.InputStream;
import java.io.OutputStream;
+import java.io.UncheckedIOException;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
+import java.nio.file.attribute.FileTime;
import java.util.Calendar;
-import java.util.Date;
import java.util.Deque;
import java.util.Hashtable;
+import java.util.Locale;
+import java.util.TimeZone;
import java.util.concurrent.ExecutionException;
import java.util.zip.CRC32;
@@ -39,7 +42,6 @@
import org.apache.commons.compress.archivers.zip.ZipEncoding;
import org.apache.commons.compress.archivers.zip.ZipEncodingHelper;
import org.apache.commons.compress.parallel.InputStreamSupplier;
-import org.apache.commons.compress.utils.Charsets;
import org.codehaus.plexus.archiver.AbstractArchiver;
import org.codehaus.plexus.archiver.ArchiveEntry;
import org.codehaus.plexus.archiver.Archiver;
@@ -48,6 +50,7 @@
import org.codehaus.plexus.archiver.UnixStat;
import org.codehaus.plexus.archiver.exceptions.EmptyArchiveException;
import org.codehaus.plexus.archiver.util.ResourceUtils;
+import org.codehaus.plexus.archiver.util.Streams;
import org.codehaus.plexus.components.io.functions.SymlinkDestinationSupplier;
import org.codehaus.plexus.components.io.resources.PlexusIoResource;
import org.codehaus.plexus.util.FileUtils;
@@ -94,6 +97,7 @@
/**
* @deprecated Use {@link Archiver#setDuplicateBehavior(String)} instead.
*/
+ @Deprecated
protected final String duplicate = Archiver.DUPLICATES_SKIP;
/**
@@ -328,11 +332,11 @@ private ZipArchiveOutputStream.UnicodeExtraFieldPolicy getUnicodeExtraFieldPolic
effectiveEncoding = Charset.defaultCharset().name();
}
- boolean utf8 = Charsets.UTF_8.name().equalsIgnoreCase( effectiveEncoding );
+ boolean utf8 = StandardCharsets.UTF_8.name().equalsIgnoreCase( effectiveEncoding );
if ( !utf8 )
{
- for ( String alias : Charsets.UTF_8.aliases() )
+ for ( String alias : StandardCharsets.UTF_8.aliases() )
{
if ( alias.equalsIgnoreCase( effectiveEncoding ) )
{
@@ -461,17 +465,16 @@ protected void zipFile( InputStreamSupplier in, ConcurrentJarCreator zOut, Strin
if ( !skipWriting )
{
ZipArchiveEntry ze = new ZipArchiveEntry( vPath );
- setTime( ze, lastModified );
+ setZipEntryTime( ze, lastModified );
ze.setMethod( doCompress ? ZipArchiveEntry.DEFLATED : ZipArchiveEntry.STORED );
ze.setUnixMode( UnixStat.FILE_FLAG | mode );
- InputStream payload;
if ( ze.isUnixSymlink() )
{
final byte[] bytes = encodeArchiveEntry( symlinkDestination, getEncoding() );
- payload = new ByteArrayInputStream( bytes );
- zOut.addArchiveEntry( ze, createInputStreamSupplier( payload ), true );
+ InputStreamSupplier payload = () -> new ByteArrayInputStream( bytes );
+ zOut.addArchiveEntry( ze, payload, true );
}
else
{
@@ -504,22 +507,15 @@ protected void zipFile( final ArchiveEntry entry, ConcurrentJarCreator zOut, Str
final boolean b = entry.getResource() instanceof SymlinkDestinationSupplier;
String symlinkTarget = b ? ( (SymlinkDestinationSupplier) entry.getResource() ).getSymlinkDestination() : null;
- InputStreamSupplier in = new InputStreamSupplier()
- {
-
- @Override
- public InputStream get()
+ InputStreamSupplier in = () -> {
+ try
{
- try
- {
- return entry.getInputStream();
- }
- catch ( IOException e )
- {
- throw new RuntimeException( e );
- }
+ return entry.getInputStream();
+ }
+ catch ( IOException e )
+ {
+ throw new UncheckedIOException( e );
}
-
};
try
{
@@ -532,35 +528,26 @@ public InputStream get()
}
}
- private void setTime( java.util.zip.ZipEntry zipEntry, long lastModified )
+ /**
+ * Set the ZipEntry dostime using the date if specified otherwise the original time.
+ *
+ * <p>Zip archives store file modification times with a granularity of two seconds, so the times will either be
+ * rounded up or down. If you round down, the archive will always seem out-of-date when you rerun the task, so the
+ * default is to round up. Rounding up may lead to a different type of problems like JSPs inside a web archive that
+ * seem to be slightly more recent than precompiled pages, rendering precompilation useless.
+ * plexus-archiver chooses to round up.
+ *
+ * @param zipEntry to set the last modified time
+ * @param lastModifiedTime to set in the zip entry only if {@link #getLastModifiedTime()} returns null
+ */
+ protected void setZipEntryTime( ZipArchiveEntry zipEntry, long lastModifiedTime )
{
- if ( getLastModifiedDate() != null )
+ if ( getLastModifiedTime() != null )
{
- lastModified = getLastModifiedDate().getTime();
+ lastModifiedTime = getLastModifiedTime().toMillis();
}
- // Zip archives store file modification times with a
- // granularity of two seconds, so the times will either be rounded
- // up or down. If you round down, the archive will always seem
- // out-of-date when you rerun the task, so the default is to round
- // up. Rounding up may lead to a different type of problems like
- // JSPs inside a web archive that seem to be slightly more recent
- // than precompiled pages, rendering precompilation useless.
- // plexus-archiver chooses to round up.
- zipEntry.setTime( lastModified + 1999 );
-
- /* Consider adding extended file stamp support.....
-
- X5455_ExtendedTimestamp ts = new X5455_ExtendedTimestamp();
- ts.setModifyJavaTime(new Date(lastModified));
- if (zipEntry.getExtra() != null){
- // Uh-oh. What do we do now.
- throw new IllegalStateException("DIdnt expect to see xtradata here ?");
-
- } else {
- zipEntry.setExtra(ts.getLocalFileDataData());
- }
- */
+ zipEntry.setTime( lastModifiedTime + 1999 );
}
protected void zipDir( PlexusIoResource dir, ConcurrentJarCreator zOut, String vPath, int mode,
@@ -599,12 +586,12 @@ protected void zipDir( PlexusIoResource dir, ConcurrentJarCreator zOut, String v
if ( dir != null && dir.isExisting() )
{
- setTime( ze, dir.getLastModified() );
+ setZipEntryTime( ze, dir.getLastModified() );
}
else
{
// ZIPs store time with a granularity of 2 seconds, round up
- setTime( ze, System.currentTimeMillis() );
+ setZipEntryTime( ze, System.currentTimeMillis() );
}
if ( !isSymlink )
{
@@ -617,14 +604,14 @@ protected void zipDir( PlexusIoResource dir, ConcurrentJarCreator zOut, String v
if ( !isSymlink )
{
- zOut.addArchiveEntry( ze, createInputStreamSupplier( new ByteArrayInputStream( "".getBytes() ) ), true );
+ zOut.addArchiveEntry( ze, () -> Streams.EMPTY_INPUTSTREAM, true );
}
else
{
String symlinkDestination = ( (SymlinkDestinationSupplier) dir ).getSymlinkDestination();
final byte[] bytes = encodeArchiveEntry( symlinkDestination, encodingToUse );
ze.setMethod( ZipArchiveEntry.DEFLATED );
- zOut.addArchiveEntry( ze, createInputStreamSupplier( new ByteArrayInputStream( bytes ) ), true );
+ zOut.addArchiveEntry( ze, () -> new ByteArrayInputStream( bytes ), true );
}
}
}
@@ -640,20 +627,6 @@ private byte[] encodeArchiveEntry( String payload, String encoding )
return encodedPayloadBytes;
}
- protected InputStreamSupplier createInputStreamSupplier( final InputStream inputStream )
- {
- return new InputStreamSupplier()
- {
-
- @Override
- public InputStream get()
- {
- return inputStream;
- }
-
- };
- }
-
/**
* Create an empty zip file
*
@@ -838,12 +811,12 @@ protected String getArchiveType()
}
@Override
- protected Date normalizeLastModifiedDate( Date lastModifiedDate )
+ protected FileTime normalizeLastModifiedTime( FileTime lastModifiedTime )
{
// timestamp of zip entries at zip storage level ignores timezone: managed in ZipEntry.setTime,
// that turns javaToDosTime: need to revert the operation here to get reproducible
// zip entry time
- return new Date( dosToJavaTime( lastModifiedDate.getTime() ) );
+ return FileTime.fromMillis( dosToJavaTime( lastModifiedTime.toMillis() ) );
}
/**
@@ -854,7 +827,7 @@ protected Date normalizeLastModifiedDate( Date lastModifiedDate )
*/
private static long dosToJavaTime( long dosTime )
{
- Calendar cal = Calendar.getInstance();
+ Calendar cal = Calendar.getInstance( TimeZone.getDefault(), Locale.ROOT );
cal.setTimeInMillis( dosTime );
return dosTime - ( cal.get( Calendar.ZONE_OFFSET ) + cal.get( Calendar.DST_OFFSET ) );
}
=====================================
src/main/java/org/codehaus/plexus/archiver/zip/ConcurrentJarCreator.java
=====================================
@@ -21,6 +21,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.SequenceInputStream;
+import java.io.UncheckedIOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.zip.Deflater;
@@ -30,12 +31,12 @@
import org.apache.commons.compress.archivers.zip.StreamCompressor;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntryRequest;
-import org.apache.commons.compress.archivers.zip.ZipArchiveEntryRequestSupplier;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import org.apache.commons.compress.parallel.InputStreamSupplier;
import org.apache.commons.compress.parallel.ScatterGatherBackingStore;
import org.apache.commons.compress.parallel.ScatterGatherBackingStoreSupplier;
-import org.codehaus.plexus.util.IOUtil;
+import org.apache.commons.compress.utils.IOUtils;
+import org.codehaus.plexus.archiver.util.Streams;
import static org.apache.commons.compress.archivers.zip.ZipArchiveEntryRequest.createZipArchiveEntryRequest;
@@ -67,6 +68,7 @@
this.threshold = threshold;
}
+ @Override
public ScatterGatherBackingStore get()
throws IOException
{
@@ -152,46 +154,28 @@ public void addArchiveEntry( final ZipArchiveEntry zipArchiveEntry, final InputS
{
throw new IllegalArgumentException( "Method must be set on the supplied zipArchiveEntry" );
}
- if ( "META-INF".equals( zipArchiveEntry.getName() ) || "META-INF/".equals( zipArchiveEntry.getName() ) )
+ final String zipEntryName = zipArchiveEntry.getName();
+ if ( "META-INF".equals( zipEntryName ) || "META-INF/".equals( zipEntryName ) )
{
- InputStream payload = source.get();
// TODO This should be enforced because META-INF non-directory does not make any sense?!
if ( zipArchiveEntry.isDirectory() )
{
zipArchiveEntry.setMethod( ZipEntry.STORED );
}
- metaInfDir.addArchiveEntry( createZipArchiveEntryRequest( zipArchiveEntry,
- createInputStreamSupplier( payload ) ) );
-
- payload.close();
+ metaInfDir.addArchiveEntry( createZipArchiveEntryRequest( zipArchiveEntry, source ) );
}
- else if ( "META-INF/MANIFEST.MF".equals( zipArchiveEntry.getName() ) )
+ else if ( "META-INF/MANIFEST.MF".equals( zipEntryName ) )
{
- InputStream payload = source.get();
- // TODO This should be enforced because META-INF/MANIFEST as non-file does not make any sense?!
- if ( zipArchiveEntry.isDirectory() )
- {
- zipArchiveEntry.setMethod( ZipEntry.STORED );
- }
- manifest.addArchiveEntry( createZipArchiveEntryRequest( zipArchiveEntry,
- createInputStreamSupplier( payload ) ) );
-
- payload.close();
+ manifest.addArchiveEntry( createZipArchiveEntryRequest( zipArchiveEntry, source ) );
}
else if ( zipArchiveEntry.isDirectory() && !zipArchiveEntry.isUnixSymlink() )
{
- final ByteArrayInputStream payload = new ByteArrayInputStream( new byte[]
- {
- } );
-
- directories.addArchiveEntry( createZipArchiveEntryRequest( zipArchiveEntry, createInputStreamSupplier(
- payload ) ) );
-
- payload.close();
+ directories.addArchiveEntry( createZipArchiveEntryRequest( zipArchiveEntry,
+ () -> Streams.EMPTY_INPUTSTREAM ) );
}
else if ( addInParallel )
{
- parallelScatterZipCreator.addArchiveEntry( createEntrySupplier( zipArchiveEntry, source ) );
+ parallelScatterZipCreator.addArchiveEntry( () -> createEntry( zipArchiveEntry, source ) );
}
else
{
@@ -199,20 +183,6 @@ else if ( addInParallel )
}
}
- private InputStreamSupplier createInputStreamSupplier( final InputStream payload )
- {
- return new InputStreamSupplier()
- {
-
- @Override
- public InputStream get()
- {
- return payload;
- }
-
- };
- }
-
public void writeTo( ZipArchiveOutputStream targetStream ) throws IOException, ExecutionException,
InterruptedException
{
@@ -240,48 +210,24 @@ public String getStatisticsMessage()
return parallelScatterZipCreator.getStatisticsMessage() + " Zip Close: " + zipCloseElapsed + "ms";
}
- private ZipArchiveEntryRequestSupplier createEntrySupplier( final ZipArchiveEntry zipArchiveEntry,
- final InputStreamSupplier inputStreamSupplier )
- {
-
- return new ZipArchiveEntryRequestSupplier()
- {
-
- @Override
- public ZipArchiveEntryRequest get()
- {
- try
- {
- return createEntry( zipArchiveEntry, inputStreamSupplier );
- }
- catch ( IOException e )
- {
- throw new RuntimeException( e );
- }
- }
-
- };
- }
-
private ZipArchiveEntryRequest createEntry( final ZipArchiveEntry zipArchiveEntry,
- final InputStreamSupplier inputStreamSupplier ) throws IOException
+ final InputStreamSupplier inputStreamSupplier )
{
// if we re-compress the zip files there is no need to look at the input stream
-
if ( compressAddedZips )
{
return createZipArchiveEntryRequest( zipArchiveEntry, inputStreamSupplier );
}
- // otherwise we should inspect the first four bites to see if the input stream is zip file or not
-
InputStream is = inputStreamSupplier.get();
+ // otherwise we should inspect the first four bytes to see if the input stream is zip file or not
byte[] header = new byte[4];
try
{
int read = is.read( header );
int compressionMethod = zipArchiveEntry.getMethod();
- if ( isZipHeader( header ) ) {
+ if ( isZipHeader( header ) )
+ {
compressionMethod = ZipEntry.STORED;
}
@@ -291,8 +237,8 @@ private ZipArchiveEntryRequest createEntry( final ZipArchiveEntry zipArchiveEntr
}
catch ( IOException e )
{
- IOUtil.close( is );
- throw e;
+ IOUtils.closeQuietly( is );
+ throw new UncheckedIOException( e );
}
}
@@ -303,18 +249,7 @@ private boolean isZipHeader( byte[] header )
private InputStreamSupplier prependBytesToStream( final byte[] bytes, final int len, final InputStream stream )
{
- return new InputStreamSupplier() {
-
- @Override
- public InputStream get()
- {
- return len > 0
- ? new SequenceInputStream( new ByteArrayInputStream( bytes, 0, len ), stream )
- : stream;
- }
-
- };
-
+ return () -> len > 0 ? new SequenceInputStream( new ByteArrayInputStream( bytes, 0, len ), stream ) : stream;
}
}
=====================================
src/main/java/org/codehaus/plexus/archiver/zip/ZipResource.java
=====================================
@@ -29,7 +29,7 @@ public class ZipResource extends AbstractPlexusIoResource
public ZipResource( ZipFile zipFile, ZipArchiveEntry entry, InputStreamTransformer streamTransformer )
{
- super( entry.getName(), getLastModofied( entry ),
+ super( entry.getName(), getLastModified( entry ),
entry.isDirectory() ? PlexusIoResource.UNKNOWN_RESOURCE_SIZE : entry.getSize(), !entry.isDirectory(),
entry.isDirectory(), true );
@@ -38,10 +38,10 @@ public ZipResource( ZipFile zipFile, ZipArchiveEntry entry, InputStreamTransform
this.streamTransformer = streamTransformer;
}
- private static long getLastModofied( ZipArchiveEntry entry )
+ private static long getLastModified( ZipArchiveEntry entry )
{
- long l = entry.getLastModifiedDate().getTime();
- return l == -1 ? PlexusIoResource.UNKNOWN_MODIFICATION_DATE : l;
+ long time = entry.getTime();
+ return time == -1 ? PlexusIoResource.UNKNOWN_MODIFICATION_DATE : time;
}
@Override
=====================================
src/test/java/org/codehaus/plexus/archiver/DuplicateFilesTest.java
=====================================
@@ -3,14 +3,13 @@
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileReader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.Enumeration;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
+import org.codehaus.plexus.DefaultPlexusContainer;
import org.codehaus.plexus.PlexusTestCase;
import org.codehaus.plexus.archiver.tar.TarArchiver;
import org.codehaus.plexus.archiver.tar.TarLongFileMode;
@@ -34,7 +33,8 @@ public void setUp()
throws Exception
{
super.setUp();
- getContainer().getLoggerManager().setThreshold( Logger.LEVEL_DEBUG );
+ DefaultPlexusContainer container = (DefaultPlexusContainer) getContainer();
+ container.getLoggerManager().setThreshold( Logger.LEVEL_DEBUG );
}
public void testZipArchiver()
=====================================
src/test/java/org/codehaus/plexus/archiver/jar/BaseJarArchiverTest.java
=====================================
@@ -16,23 +16,24 @@
*/
package org.codehaus.plexus.archiver.jar;
-import org.codehaus.plexus.archiver.ArchiverException;
-import org.codehaus.plexus.util.IOUtil;
-import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
import java.io.File;
-import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
+import java.util.Calendar;
import java.util.Enumeration;
+import java.util.Locale;
+import java.util.TimeZone;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
+import org.codehaus.plexus.archiver.ArchiverException;
+import org.codehaus.plexus.util.IOUtil;
+import org.junit.Test;
public abstract class BaseJarArchiverTest
{
@@ -73,6 +74,13 @@ public void testCreateJar()
}
}
+ protected static long normalizeLastModifiedTime( long dosTime )
+ {
+ Calendar cal = Calendar.getInstance( TimeZone.getDefault(), Locale.ROOT );
+ cal.setTimeInMillis( dosTime );
+ return dosTime - ( cal.get( Calendar.ZONE_OFFSET ) + cal.get( Calendar.DST_OFFSET ) );
+ }
+
protected abstract JarArchiver getJarArchiver();
}
=====================================
src/test/java/org/codehaus/plexus/archiver/jar/JarArchiverTest.java
=====================================
@@ -1,10 +1,20 @@
package org.codehaus.plexus.archiver.jar;
+import static org.junit.Assert.assertEquals;
+
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.attribute.FileTime;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Enumeration;
import java.util.Random;
+import java.util.TimeZone;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
import org.codehaus.plexus.archiver.ArchiverException;
import org.junit.Test;
@@ -76,6 +86,67 @@ public void testVeryLargeJar()
archiver.createArchive();
}
+ @Test
+ public void testReproducibleBuild()
+ throws IOException, ManifestException, ParseException
+ {
+ String[] tzList = { "America/Managua", "America/New_York", "America/Buenos_Aires", "America/Sao_Paulo",
+ "America/Los_Angeles", "Africa/Cairo", "Africa/Lagos", "Africa/Nairobi", "Europe/Lisbon", "Europe/Madrid",
+ "Europe/Moscow", "Europe/Oslo", "Australia/Sydney", "Asia/Tokyo", "Asia/Singapore", "Asia/Qatar",
+ "Asia/Seoul", "Atlantic/Bermuda", "UTC", "GMT", "Etc/GMT-14" };
+ for ( String tzId : tzList )
+ {
+ // Every single run with different Time Zone should set the same modification time.
+ createReproducibleBuild( tzId );
+ }
+ }
+
+ private void createReproducibleBuild( String timeZoneId )
+ throws IOException, ManifestException, ParseException
+ {
+ final TimeZone defaultTz = TimeZone.getDefault();
+ TimeZone.setDefault( TimeZone.getTimeZone( timeZoneId ) );
+ try
+ {
+ String tzName = timeZoneId.substring( timeZoneId.lastIndexOf( '/' ) + 1 );
+ Path jarFile = Files.createTempFile( "JarArchiverTest-" + tzName + "-", ".jar" );
+ jarFile.toFile().deleteOnExit();
+
+ Manifest manifest = new Manifest();
+ Manifest.Attribute attribute = new Manifest.Attribute( "Main-Class", "com.example.app.Main" );
+ manifest.addConfiguredAttribute( attribute );
+
+ JarArchiver archiver = getJarArchiver();
+ archiver.setDestFile( jarFile.toFile() );
+ archiver.addConfiguredManifest( manifest );
+ archiver.addDirectory( new File( "src/test/resources/java-classes" ) );
+
+ SimpleDateFormat isoFormat = new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ssXXX" );
+ long parsedTime = isoFormat.parse( "2038-01-19T03:14:08Z" ).getTime();
+ FileTime lastModTime = FileTime.fromMillis( parsedTime );
+
+ archiver.configureReproducibleBuild( lastModTime );
+ archiver.createArchive();
+
+ // zip 2 seconds precision, normalized to UTC
+ long expectedTime = normalizeLastModifiedTime( parsedTime - ( parsedTime % 2000 ) );
+ try ( ZipFile zip = new ZipFile( jarFile.toFile() ) )
+ {
+ Enumeration<? extends ZipEntry> entries = zip.entries();
+ while ( entries.hasMoreElements() )
+ {
+ ZipEntry entry = entries.nextElement();
+ long time = entry.getTime();
+ assertEquals( "last modification time does not match", expectedTime, time );
+ }
+ }
+ }
+ finally
+ {
+ TimeZone.setDefault( defaultTz );
+ }
+ }
+
@Override
protected JarArchiver getJarArchiver()
{
=====================================
src/test/java/org/codehaus/plexus/archiver/jar/JarToolModularJarArchiverTest.java
=====================================
@@ -16,9 +16,16 @@
*/
package org.codehaus.plexus.archiver.jar;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assume.assumeFalse;
+import static org.junit.Assume.assumeTrue;
+
import java.io.File;
import java.io.InputStream;
import java.lang.reflect.Method;
+import java.nio.file.attribute.FileTime;
+import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashSet;
@@ -30,10 +37,6 @@
import org.junit.Before;
import org.junit.Test;
-import static org.junit.Assert.*;
-import static org.junit.Assume.assumeFalse;
-import static org.junit.Assume.assumeTrue;
-
public class JarToolModularJarArchiverTest
extends BaseJarArchiverTest
{
@@ -252,25 +255,57 @@ public void testModularMultiReleaseJar()
{
assumeTrue( modulesAreSupported() );
+ // Add two module-info.class, one on the root and one on the multi-release dir.
+ archiver.addFile( new File( "src/test/resources/java-module-descriptor/module-info.class" ),
+ "META-INF/versions/9/module-info.class" );
archiver.addFile( new File( "src/test/resources/java-module-descriptor/module-info.class" ),
- "META-INF/versions/9/module-info.class" );
+ "module-info.class" );
+
Manifest manifest = new Manifest();
+ manifest.addConfiguredAttribute( new Manifest.Attribute( "Main-Class", "com.example.app.Main2" ) );
manifest.addConfiguredAttribute( new Manifest.Attribute( "Multi-Release", "true" ) );
archiver.addConfiguredManifest( manifest );
+
archiver.setModuleVersion( "1.0.0" );
+ // This attribute overwrites the one from the manifest.
archiver.setModuleMainClass( "com.example.app.Main" );
+ SimpleDateFormat isoFormat = new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ssXXX" );
+ long dateTimeMillis = isoFormat.parse( "2020-02-29T23:59:59Z" ).getTime();
+ FileTime lastModTime = FileTime.fromMillis( dateTimeMillis );
+
+ archiver.configureReproducibleBuild( lastModTime );
archiver.createArchive();
+ // Round-down two seconds precision
+ long roundedDown = lastModTime.toMillis() - ( lastModTime.toMillis() % 2000 );
+ // Normalize to UTC
+ long expectedLastModifiedTime = normalizeLastModifiedTime( roundedDown );
+
// verify that the resulting modular jar has the proper version and main class set
try ( ZipFile resultingArchive = new ZipFile( archiver.getDestFile() ) )
{
- ZipEntry moduleDescriptorEntry =
- resultingArchive.getEntry( "META-INF/versions/9/module-info.class" );
+ ZipEntry moduleDescriptorEntry = resultingArchive.getEntry( "META-INF/versions/9/module-info.class" );
InputStream resultingModuleDescriptor = resultingArchive.getInputStream( moduleDescriptorEntry );
+ assertModuleDescriptor( resultingModuleDescriptor, "1.0.0", "com.example.app.Main", "com.example.app",
+ "com.example.resources" );
- assertModuleDescriptor( resultingModuleDescriptor,
- "1.0.0", "com.example.app.Main", "com.example.app", "com.example.resources" );
+ ZipEntry rootModuleDescriptorEntry = resultingArchive.getEntry( "module-info.class" );
+ InputStream rootResultingModuleDescriptor = resultingArchive.getInputStream( rootModuleDescriptorEntry );
+ assertModuleDescriptor( rootResultingModuleDescriptor, "1.0.0", "com.example.app.Main", "com.example.app",
+ "com.example.resources" );
+
+ // verify every entry has the correct last modified time
+ Enumeration<? extends ZipEntry> entries = resultingArchive.entries();
+ while ( entries.hasMoreElements() )
+ {
+ ZipEntry element = entries.nextElement();
+ assertEquals( "Last Modified Time does not match with expected", expectedLastModifiedTime,
+ element.getTime() );
+ FileTime expectedFileTime = FileTime.fromMillis( expectedLastModifiedTime );
+ assertEquals( "Last Modified Time does not match with expected", expectedFileTime,
+ element.getLastModifiedTime() );
+ }
}
}
=====================================
src/test/java/org/codehaus/plexus/archiver/zip/ArchiveFileComparator.java
=====================================
@@ -122,7 +122,7 @@ private static void assertEquals( ZipFile file1, ZipArchiveEntry entry1,
{
Assert.assertEquals( entry1.isDirectory(), entry2.isDirectory() );
Assert.assertEquals( entry1.isUnixSymlink(), entry2.isUnixSymlink() );
- long timeDelta = entry1.getLastModifiedDate().getTime() - entry2.getLastModifiedDate().getTime();
+ long timeDelta = entry1.getTime() - entry2.getTime();
Assert.assertTrue( Math.abs( timeDelta ) <= 1000 );
final InputStream is1 = file1.getInputStream( entry1 );
=====================================
src/test/java/org/codehaus/plexus/archiver/zip/ConcurrentJarCreatorTest.java
=====================================
@@ -1,15 +1,14 @@
package org.codehaus.plexus.archiver.zip;
import java.io.File;
-import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.io.UncheckedIOException;
import java.nio.file.Files;
import org.apache.commons.compress.archivers.zip.UnixStat;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
-import org.apache.commons.compress.parallel.InputStreamSupplier;
import org.apache.commons.compress.utils.IOUtils;
import org.codehaus.plexus.util.DirectoryScanner;
import org.junit.Ignore;
@@ -77,21 +76,15 @@ private void doAddAll( String base, ConcurrentJarCreator mos ) throws IOExceptio
final File file = new File( base, fileName );
ZipArchiveEntry za = createZipArchiveEntry( file, fileName );
- mos.addArchiveEntry( za, new InputStreamSupplier()
- {
-
- public InputStream get()
+ mos.addArchiveEntry( za, () -> {
+ try
{
- try
- {
- return file.isFile() ? Files.newInputStream( file.toPath() ) : null;
- }
- catch ( IOException e )
- {
- throw new RuntimeException( e );
- }
+ return file.isFile() ? Files.newInputStream( file.toPath() ) : null;
+ }
+ catch ( IOException e )
+ {
+ throw new UncheckedIOException( e );
}
-
}, true );
}
=====================================
src/test/java/org/codehaus/plexus/archiver/zip/ZipArchiverTest.java
=====================================
@@ -26,13 +26,12 @@
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.Writer;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
+import java.nio.file.Path;
import java.nio.file.attribute.FileTime;
import java.text.DateFormat;
import java.text.ParseException;
@@ -78,6 +77,7 @@
import org.codehaus.plexus.util.FileUtils;
import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.Os;
+import org.junit.Test;
/**
* @author Emmanuel Venisse
@@ -633,27 +633,34 @@ public void testSymlinkArchivedFileSet()
* Zip archives store file modification times with a granularity of two seconds.
* Verify that ZipArchiver rounds up the last modified time.
*/
+ @Test
public void testLastModifiedTimeRounding()
throws Exception
{
- File oddSecondsTimestampFile = File.createTempFile( "odd-seconds-timestamp", null );
- oddSecondsTimestampFile.deleteOnExit();
+ Path oddSecondsTimestampFile = Files.createTempFile( "odd-seconds-timestamp", null );
+ oddSecondsTimestampFile.toFile().deleteOnExit();
// The milliseconds part is set to zero as not all filesystem support timestamp more granular than second.
- Files.setLastModifiedTime( oddSecondsTimestampFile.toPath(), FileTime.fromMillis( 1534189011_000L ) );
- File evenSecondsTimestampFile = File.createTempFile( "even-seconds-timestamp", null );
- evenSecondsTimestampFile.deleteOnExit();
- Files.setLastModifiedTime( evenSecondsTimestampFile.toPath(), FileTime.fromMillis( 1534189012_000L ) );
+ Files.setLastModifiedTime( oddSecondsTimestampFile, FileTime.fromMillis( 1534189011_000L ) );
+ Path evenSecondsTimestampFile = Files.createTempFile( "even-seconds-timestamp", null );
+ evenSecondsTimestampFile.toFile().deleteOnExit();
+ Files.setLastModifiedTime( evenSecondsTimestampFile, FileTime.fromMillis( 1534189012_000L ) );
File destFile = getTestFile( "target/output/last-modified-time.zip" );
ZipArchiver archiver = getZipArchiver( destFile );
- archiver.addFile( oddSecondsTimestampFile, "odd-seconds" );
- archiver.addFile( evenSecondsTimestampFile, "even-seconds" );
+ archiver.addFile( oddSecondsTimestampFile.toFile(), "odd-seconds" );
+ archiver.addFile( evenSecondsTimestampFile.toFile(), "even-seconds" );
archiver.createArchive();
// verify that the last modified time of the entry is equal or newer than the original file
- ZipFile resultingZipFile = new ZipFile( destFile );
- assertEquals( 1534189012_000L, resultingZipFile.getEntry( "odd-seconds" ).getTime() );
- assertEquals( 1534189012_000L, resultingZipFile.getEntry( "even-seconds" ).getTime() );
+ try ( ZipFile resultingZipFile = new ZipFile( destFile ) )
+ {
+ assertEquals( 1534189012_000L, resultingZipFile.getEntry( "odd-seconds" ).getTime() );
+ assertEquals( 1534189012_000L, resultingZipFile.getEntry( "even-seconds" ).getTime() );
+
+ FileTime expected = FileTime.fromMillis( 1534189012_000L );
+ assertEquals( expected, resultingZipFile.getEntry( "odd-seconds" ).getLastModifiedTime() );
+ assertEquals( expected, resultingZipFile.getEntry( "even-seconds" ).getLastModifiedTime() );
+ }
}
/*
@@ -901,7 +908,7 @@ public void testFixedEntryModificationTime()
final File zipFile = getTestFile( "target/output/zip-with-fixed-entry-modification-times.zip" );
final ZipArchiver archiver = getZipArchiver( zipFile );
- archiver.setLastModifiedDate( new Date( almostMinDosTime ) );
+ archiver.setLastModifiedTime( FileTime.fromMillis( almostMinDosTime ) );
archiver.addDirectory( new File( "src/test/resources/zip-timestamp" ) );
archiver.createArchive();
View it on GitLab: https://salsa.debian.org/java-team/plexus-archiver/-/commit/fab62d2492f565a295c35edf292558ce9a594d34
--
View it on GitLab: https://salsa.debian.org/java-team/plexus-archiver/-/commit/fab62d2492f565a295c35edf292558ce9a594d34
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/20220929/2d08b521/attachment.htm>
More information about the pkg-java-commits
mailing list