This is an automated email from the ASF dual-hosted git repository.
desruisseaux pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git
The following commit(s) were added to refs/heads/geoapi-4.0 by this push:
new d4884c9 Apache SIS distribution file should not use PACK200 anymore.
That format has been deprecated for removal in Java 11. This commit is part of
https://issues.apache.org/jira/browse/SIS-430.
d4884c9 is described below
commit d4884c90123341be2fc26cb8ba568847297fae78
Author: Martin Desruisseaux <[email protected]>
AuthorDate: Sun Nov 4 21:28:58 2018 +0100
Apache SIS distribution file should not use PACK200 anymore. That format
has been deprecated for removal in Java 11.
This commit is part of https://issues.apache.org/jira/browse/SIS-430.
---
application/sis-console/pom.xml | 2 +-
application/sis-console/src/main/artifact/README | 6 +-
application/sis-console/src/main/artifact/bin/sis | 10 -
.../org/apache/sis/internal/maven/Assembler.java | 192 ++++++++----
.../apache/sis/internal/maven/BundleCreator.java | 114 -------
.../org/apache/sis/internal/maven/Filenames.java | 42 +--
.../apache/sis/internal/maven/JarCollector.java | 20 +-
.../org/apache/sis/internal/maven/PackInput.java | 227 --------------
.../org/apache/sis/internal/maven/PackOutput.java | 338 ---------------------
.../java/org/apache/sis/internal/maven/Packer.java | 123 --------
.../apache/sis/internal/maven/package-info.java | 10 +-
11 files changed, 182 insertions(+), 902 deletions(-)
diff --git a/application/sis-console/pom.xml b/application/sis-console/pom.xml
index 19fce93..71cb211 100644
--- a/application/sis-console/pom.xml
+++ b/application/sis-console/pom.xml
@@ -87,7 +87,7 @@
</plugins>
</build>
- <!-- Create the binary distribution file, including PACK200 bundle. -->
+ <!-- Create the binary distribution file. -->
<profiles>
<profile>
<id>apache-release</id>
diff --git a/application/sis-console/src/main/artifact/README
b/application/sis-console/src/main/artifact/README
index 727b920..ce5f727 100644
--- a/application/sis-console/src/main/artifact/README
+++ b/application/sis-console/src/main/artifact/README
@@ -27,11 +27,7 @@ There is not yet 'sis.bat' file for Windows.
The following steps need to be done manually:
1) Unzip 'apache-sis-1.0-bin.zip' in any directory.
-2) In the 'apache-sis-1.0/lib' directory, execute:
-
- unpack200 --remove-pack-file sis.pack.gz sis.jar
-
-3) Invoke 'java -jar lib/sis.jar' on the command line.
+2) Invoke 'java -jar lib/sis.jar' on the command line.
Configuration (Unix only)
diff --git a/application/sis-console/src/main/artifact/bin/sis
b/application/sis-console/src/main/artifact/bin/sis
index 929ceb7..ed98e33 100755
--- a/application/sis-console/src/main/artifact/bin/sis
+++ b/application/sis-console/src/main/artifact/bin/sis
@@ -20,16 +20,6 @@ BASE_DIR="`dirname $0`/.."
SIS_DATA="${SIS_DATA:-$BASE_DIR/data}"
export SIS_DATA
-# Unpack the JAR file when first needed.
-if [ ! -f $BASE_DIR/lib/sis.jar ]
-then
- if ! unpack200 --remove-pack-file $BASE_DIR/lib/sis.pack.gz
$BASE_DIR/lib/sis.jar
- then
- echo Can not install Apache SIS.
- exit 1
- fi
-fi
-
# Execute SIS with any optional JAR that the user may put in the 'lib'
directory.
java -classpath "$BASE_DIR/lib/*" \
-Djava.util.logging.config.file="$BASE_DIR/conf/logging.properties" \
diff --git
a/core/sis-build-helper/src/main/java/org/apache/sis/internal/maven/Assembler.java
b/core/sis-build-helper/src/main/java/org/apache/sis/internal/maven/Assembler.java
index e04587b..bb5a0d0 100644
---
a/core/sis-build-helper/src/main/java/org/apache/sis/internal/maven/Assembler.java
+++
b/core/sis-build-helper/src/main/java/org/apache/sis/internal/maven/Assembler.java
@@ -20,9 +20,16 @@ import java.io.File;
import java.io.IOException;
import java.io.FilenameFilter;
import java.io.FileInputStream;
-import java.io.FilterOutputStream;
-import java.util.LinkedHashMap;
+import java.io.InputStream;
import java.util.Map;
+import java.util.Set;
+import java.util.Enumeration;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.zip.ZipFile;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+import org.apache.maven.artifact.Artifact;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Mojo;
@@ -37,20 +44,27 @@ import static org.apache.sis.internal.maven.Filenames.*;
/**
- * Creates a ZIP files containing the content of the
<code>application/sis-console/src/main/artifact</code>
- * directory together with the Pack200 file created by
<code>BundleCreator</code>.
+ * Creates a ZIP file containing the Apache SIS binary distribution.
+ * The created file contains:
+ *
+ * <ul>
+ * <li>the content of the
<code>application/sis-console/src/main/artifact</code> directory;</li>
+ * <li>the JAR files of all modules and their dependencies, without their
native resources;</li>
+ * <li>the native resources in a separated {@code lib/} directory.</li>
+ * </ul>
+ *
* This MOJO can be invoked from the command line in the {@code sis-console}
module as below:
*
* <blockquote><code>mvn package
org.apache.sis.core:sis-build-helper:dist</code></blockquote>
*
* <p><b>Current limitation:</b>
* The current implementation uses some hard-coded paths and filenames.
- * See the <cite>Distribution file and Pack200 bundle</cite> section in
+ * See the <cite>Distribution file</cite> section in
* <a href="http://sis.apache.org/build.html">Build from source</a> page
* for more information.</p>
*
* @author Martin Desruisseaux (Geomatys)
- * @version 0.8
+ * @version 1.0
* @since 0.4
* @module
*/
@@ -93,42 +107,33 @@ public final class Assembler extends AbstractMojo
implements FilenameFilter {
if (!sourceDirectory.isDirectory()) {
throw new MojoExecutionException("Directory not found: " +
sourceDirectory);
}
- final File targetDirectory = new File(rootDirectory, TARGET_DIRECTORY);
- final String version = project.getVersion();
- final String artifactBase = FINALNAME_PREFIX + version;
- final Map<String,byte[]> nativeFiles = new LinkedHashMap<>();
- try {
- final File targetFile = new
File(distributionDirectory(targetDirectory), artifactBase + ".zip");
- try (ZipArchiveOutputStream zip = new
ZipArchiveOutputStream(targetFile)) {
- zip.setLevel(9);
- appendRecursively(sourceDirectory, artifactBase, zip, new
byte[8192]);
- /*
- * At this point, all the
"application/sis-console/src/main/artifact" and sub-directories
- * have been zipped. Now generate the Pack200 file and zip it
directly (without creating
- * a temporary "sis.pack.gz" file).
- */
- final Packer packer = new Packer(project.getName(), version,
BundleCreator.files(project), targetDirectory, nativeFiles);
- ZipArchiveEntry entry = new ZipArchiveEntry(artifactBase + '/'
+ LIB_DIRECTORY + '/' + FATJAR_FILE + PACK_EXTENSION);
- entry.setMethod(ZipArchiveEntry.STORED);
+ final String artifactBase = FINALNAME_PREFIX + project.getVersion();
+ final File targetFile = distributionFile(rootDirectory, artifactBase +
".zip");
+ try (ZipArchiveOutputStream zip = new
ZipArchiveOutputStream(targetFile)) {
+ zip.setLevel(9);
+ appendRecursively(sourceDirectory, artifactBase, zip);
+ /*
+ * At this point, all the
"application/sis-console/src/main/artifact" and sub-directories
+ * have been zipped. Now append the JAR files for each module and
their dependencies.
+ */
+ final Map<String,byte[]> nativeFiles = new LinkedHashMap<>();
+ for (final File file : files(project)) {
+ ZipArchiveEntry entry = new ZipArchiveEntry(artifactBase + '/'
+ LIB_DIRECTORY + '/' + file.getName());
zip.putArchiveEntry(entry);
- packer.preparePack200(FATJAR_FILE + ".jar").pack(new
FilterOutputStream(zip) {
- /** Closes the archive entry, not the ZIP file. */
- @Override public void close() throws IOException {
- zip.closeArchiveEntry();
- }
- });
- /*
- * At this point we finished creating all entries in the ZIP
file, except native resources.
- * Copy them now.
- */
- for (final Map.Entry<String,byte[]> nf :
nativeFiles.entrySet()) {
- entry = new ZipArchiveEntry(artifactBase + '/' +
LIB_DIRECTORY + '/' + nf.getKey());
- entry.setUnixMode(0555); // Readable and executable
for all, but not writable.
- zip.putArchiveEntry(entry);
- zip.write(nf.getValue());
- zip.closeArchiveEntry();
- nf.setValue(null);
- }
+ appendJAR(file, zip, nativeFiles);
+ zip.closeArchiveEntry();
+ }
+ /*
+ * At this point we finished creating all entries in the ZIP file,
except native resources.
+ * Copy them now.
+ */
+ for (final Map.Entry<String,byte[]> nf : nativeFiles.entrySet()) {
+ ZipArchiveEntry entry = new ZipArchiveEntry(artifactBase + '/'
+ LIB_DIRECTORY + '/' + nf.getKey());
+ entry.setUnixMode(0555); // Readable and executable for
all, but not writable.
+ zip.putArchiveEntry(entry);
+ zip.write(nf.getValue());
+ zip.closeArchiveEntry();
+ nf.setValue(null);
}
} catch (IOException e) {
throw new MojoExecutionException(e.getLocalizedMessage(), e);
@@ -136,14 +141,31 @@ public final class Assembler extends AbstractMojo
implements FilenameFilter {
}
/**
+ * Returns all files to include for the given Maven project.
+ */
+ private static Set<File> files(final MavenProject project) throws
MojoExecutionException {
+ final Set<File> files = new LinkedHashSet<>();
+ files.add(project.getArtifact().getFile());
+ for (final Artifact dep : project.getArtifacts()) {
+ final String scope = dep.getScope();
+ if (Artifact.SCOPE_COMPILE.equalsIgnoreCase(scope) ||
+ Artifact.SCOPE_RUNTIME.equalsIgnoreCase(scope))
+ {
+ files.add(dep.getFile());
+ }
+ }
+ if (files.remove(null)) {
+ throw new MojoExecutionException("Invocation of this MOJO shall be
done together with a \"package\" Maven phase.");
+ }
+ return files;
+ }
+
+ /**
* Adds the given file in the ZIP file. If the given file is a directory,
then this method
* recursively adds all files contained in this directory. This method is
invoked for zipping
- * the "application/sis-console/src/main/artifact" directory and
sub-directories before to zip
- * the Pack200 file.
+ * the "application/sis-console/src/main/artifact" directory and
sub-directories before to zip.
*/
- private void appendRecursively(final File file, String relativeFile, final
ZipArchiveOutputStream out,
- final byte[] buffer) throws IOException
- {
+ private void appendRecursively(final File file, String relativeFile, final
ZipArchiveOutputStream out) throws IOException {
if (file.isDirectory()) {
relativeFile += '/';
}
@@ -154,17 +176,13 @@ public final class Assembler extends AbstractMojo
implements FilenameFilter {
out.putArchiveEntry(entry);
if (!entry.isDirectory()) {
try (FileInputStream in = new FileInputStream(file)) {
- // TODO: use InputStream.transferTo(OutputStream) with JDK9.
- int n;
- while ((n = in.read(buffer)) >= 0) {
- out.write(buffer, 0, n);
- }
+ in.transferTo(out);
}
}
out.closeArchiveEntry();
if (entry.isDirectory()) {
for (final String filename : file.list(this)) {
- appendRecursively(new File(file, filename),
relativeFile.concat(filename), out, buffer);
+ appendRecursively(new File(file, filename),
relativeFile.concat(filename), out);
}
}
}
@@ -180,4 +198,74 @@ public final class Assembler extends AbstractMojo
implements FilenameFilter {
public boolean accept(final File directory, final String filename) {
return !filename.isEmpty() && filename.charAt(0) != '.' &&
!filename.equals(CONTENT_FILE);
}
+
+ /**
+ * Returns {@code true} if the given JAR file contains at least one
resource in the
+ * {@value Filenames#NATIVE_DIRECTORY} directory. Those files will need to
be rewritten
+ * in order to exclude those resources.
+ */
+ private static boolean hasNativeResources(final ZipFile in) {
+ final Enumeration<? extends ZipEntry> entries = in.entries();
+ while (entries.hasMoreElements()) {
+ if (entries.nextElement().getName().startsWith(NATIVE_DIRECTORY)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Copies a JAR file in the given ZIP file, except the native resources
which are stored in the given map.
+ *
+ * @param file the JAR file to copy.
+ * @param bundle destination where to copy the JAR file.
+ * @param nativeFiles where to store the native resources.
+ */
+ private void appendJAR(final File file, final ZipArchiveOutputStream
bundle, final Map<String,byte[]> nativeFiles)
+ throws IOException
+ {
+ try (ZipFile in = new ZipFile(file)) {
+ if (hasNativeResources(in)) {
+ final ZipOutputStream out = new ZipOutputStream(bundle);
+ out.setLevel(9);
+ final Enumeration<? extends ZipEntry> entries = in.entries();
+ while (entries.hasMoreElements()) {
+ final ZipEntry entry = entries.nextElement();
+ final String name = entry.getName();
+ try (InputStream eis = in.getInputStream(entry)) {
+ if (!name.startsWith(NATIVE_DIRECTORY)) {
+ out.putNextEntry(new ZipEntry(name));
+ eis.transferTo(out); //
Copy the entry verbatim.
+ out.closeEntry();
+ } else if (!entry.isDirectory()) {
+ final long size = entry.getSize(); //
For memorizing the entry without copying it now.
+ if (size <= 0 || size > Integer.MAX_VALUE) {
+ throw new IOException(String.format("Errors
while copying %s:%n"
+ + "Unsupported size for \"%s\" entry:
%d", file, name, size));
+ }
+ final byte[] content = new byte[(int) size];
+ final int actual = eis.read(content);
+ if (actual != size) {
+ throw new IOException(String.format("Errors
while copying %s:%n"
+ + "Expected %d bytes in \"%s\" but
found %d", file, size, name, actual));
+ }
+ if
(nativeFiles.put(name.substring(NATIVE_DIRECTORY.length()), content) != null) {
+ throw new IOException(String.format("Errors
while copying %s:%n"
+ + "Duplicated entry: %s", file, name));
+ }
+ }
+ }
+ }
+ out.finish();
+ return;
+ }
+ }
+ /*
+ * If the JAR file has no native resources to exclude, we can copy the
JAR file verbatim.
+ * This is faster than inflating and deflating again the JAR file.
+ */
+ try (FileInputStream in = new FileInputStream(file)) {
+ in.transferTo(bundle);
+ }
+ }
}
diff --git
a/core/sis-build-helper/src/main/java/org/apache/sis/internal/maven/BundleCreator.java
b/core/sis-build-helper/src/main/java/org/apache/sis/internal/maven/BundleCreator.java
deleted file mode 100644
index c89af37..0000000
---
a/core/sis-build-helper/src/main/java/org/apache/sis/internal/maven/BundleCreator.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * 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.sis.internal.maven;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.LinkedHashSet;
-import java.util.Set;
-import org.apache.maven.artifact.Artifact;
-import org.apache.maven.plugin.AbstractMojo;
-import org.apache.maven.plugin.MojoExecutionException;
-import org.apache.maven.plugins.annotations.Mojo;
-import org.apache.maven.plugins.annotations.Parameter;
-import org.apache.maven.plugins.annotations.LifecyclePhase;
-import org.apache.maven.plugins.annotations.ResolutionScope;
-import org.apache.maven.project.MavenProject;
-
-import static org.apache.sis.internal.maven.Filenames.*;
-
-
-/**
- * Merges the binaries produced by <code>JarCollector</code> and compress them
using Pack200.
- * This mojo can be invoked from the command line as below:
- *
- * <blockquote><code>mvn org.apache.sis.core:sis-build-helper:pack
--non-recursive</code></blockquote>
- *
- * Do not forget the <code>--non-recursive</code> option, otherwise the Mojo
will be executed many time.
- *
- * <p><b>Current limitation:</b>
- * The current implementation uses some hard-coded paths and filenames.
- * See the <cite>Distribution file and Pack200 bundle</cite> section in
- * <a href="http://sis.apache.org/build.html">Build from source</a> page
- * for more information.</p>
- *
- * @author Martin Desruisseaux (Geomatys)
- * @version 0.8
- * @since 0.3
- * @module
- */
-@Mojo(name = "pack", defaultPhase = LifecyclePhase.INSTALL,
requiresDependencyResolution = ResolutionScope.COMPILE)
-public final class BundleCreator extends AbstractMojo {
- /**
- * Project information (name, version, URL).
- */
- @Parameter(property="project", required=true, readonly=true)
- private MavenProject project;
-
- /**
- * The root directory (without the "<code>target/binaries</code>"
sub-directory) where JARs
- * are to be copied. It should be the directory of the root
<code>pom.xml</code>.
- */
- @Parameter(property="session.executionRootDirectory", required=true)
- private String rootDirectory;
-
- /**
- * Invoked by reflection for creating the MOJO.
- */
- public BundleCreator() {
- }
-
- /**
- * Creates the Pack200 file from the JAR files collected in the
"<code>target/binaries</code>" directory.
- *
- * @throws MojoExecutionException if the plugin execution failed.
- */
- @Override
- public void execute() throws MojoExecutionException {
- final File targetDirectory = new File(rootDirectory, TARGET_DIRECTORY);
- if (!targetDirectory.isDirectory()) {
- throw new MojoExecutionException("Directory not found: " +
targetDirectory);
- }
- final String version = project.getVersion();
- try {
- final Packer packer = new Packer(project.getName(), version,
files(project), targetDirectory, null);
- packer.preparePack200(FINALNAME_PREFIX + version + ".jar").pack();
- } catch (IOException e) {
- throw new MojoExecutionException(e.getLocalizedMessage(), e);
- }
- }
-
- /**
- * Returns all files to include for the given Maven project.
- */
- static Set<File> files(final MavenProject project) throws
MojoExecutionException {
- final Set<File> files = new LinkedHashSet<>();
- files.add(project.getArtifact().getFile());
- for (final Artifact dep : project.getArtifacts()) {
- final String scope = dep.getScope();
- if (Artifact.SCOPE_COMPILE.equalsIgnoreCase(scope) ||
- Artifact.SCOPE_RUNTIME.equalsIgnoreCase(scope))
- {
- files.add(dep.getFile());
- }
- }
- if (files.remove(null)) {
- throw new MojoExecutionException("Invocation of this MOJO shall be
done together with a \"package\" Maven phase.");
- }
- return files;
- }
-}
diff --git
a/core/sis-build-helper/src/main/java/org/apache/sis/internal/maven/Filenames.java
b/core/sis-build-helper/src/main/java/org/apache/sis/internal/maven/Filenames.java
index 6779f7c..3a68cec 100644
---
a/core/sis-build-helper/src/main/java/org/apache/sis/internal/maven/Filenames.java
+++
b/core/sis-build-helper/src/main/java/org/apache/sis/internal/maven/Filenames.java
@@ -17,18 +17,18 @@
package org.apache.sis.internal.maven;
import java.io.File;
-import java.io.IOException;
+import org.apache.maven.plugin.MojoExecutionException;
/**
* Hard-coded file and directory names used by this package.
*
* <p><b>Reminder:</b>
- * If the above constants are modified, please remind to edit the
<cite>Distribution file
- * and Pack200 bundle</cite> section in the
<code>src/site/apt/index.apt</code> file.</p>
+ * If the above constants are modified, please remind to edit the
<cite>Distribution file</cite>
+ * section in the <code>site/content/build.mdtext</code> file.</p>
*
* @author Martin Desruisseaux (Geomatys)
- * @version 0.4
+ * @version 1.0
* @since 0.4
* @module
*/
@@ -51,13 +51,19 @@ final class Filenames {
* dependencies on platforms that do not support hard links. Also the file
to ignore when copying
* entries in a ZIP file.
*/
+ static final String OTHER_DEPENDENCIES_FILE = "other_dependencies.txt";
+
+ /**
+ * The file to ignore when copying entries in a ZIP file.
+ * Those files appear in the {@value #ARTIFACT_PATH} directory.
+ */
static final String CONTENT_FILE = "content.txt";
/**
* The sub-directory inside {@value #TARGET_DIRECTORY} containing pack
files.
* This directory will be automatically created if it does not already
exist.
*/
- static final String DISTRIBUTION_DIRECTORY = "distribution";
+ private static final String DISTRIBUTION_DIRECTORY = "distribution";
/**
* The path to the directory (relative to the project directory) to zip
for creating the distribution ZIP file.
@@ -65,17 +71,17 @@ final class Filenames {
static final String ARTIFACT_PATH = "src/main/artifact";
/**
- * The name of the sub-directory inside {@value #ARTIFACT_PATH} where the
Pack200 file will be located.
+ * The name of the sub-directory inside {@value #ARTIFACT_PATH} where the
JAR files will be located.
* Note that we will not write in the real directory, but only in the
directory structure which is
* reproduced in the ZIP file.
*/
static final String LIB_DIRECTORY = "lib";
/**
- * The name (without extension) of the big JAR file which will contains
everything.
- * This file will be located in the {@value #LIB_DIRECTORY} directory.
+ * The prefix of native resources in JAR files. All those resources will
be excluded from
+ * the JAR copied in the zip file and stored in a {@code nativeFiles} map
instead.
*/
- static final String FATJAR_FILE = "sis";
+ static final String NATIVE_DIRECTORY = "native/";
/**
* The prefix of the final filename. This is hard coded for now.
@@ -83,28 +89,24 @@ final class Filenames {
static final String FINALNAME_PREFIX = "apache-sis-";
/**
- * The extension for Pack200 files.
- */
- static final String PACK_EXTENSION = ".pack.gz";
-
- /**
* Do not allow instantiation of this class.
*/
private Filenames() {
}
/**
- * Returns the distribution directory, creating it if needed.
+ * Returns the distribution file, creating its directory if needed.
*
- * @param targetDirectory the {@code target} directory.
+ * @param rootDirectory the project root directory.
+ * @param filename name of the file to create.
*/
- static File distributionDirectory(final File targetDirectory) throws
IOException {
- final File outDirectory = new File(targetDirectory,
DISTRIBUTION_DIRECTORY);
+ static File distributionFile(final String rootDirectory, final String
filename) throws MojoExecutionException {
+ final File outDirectory = new File(new File(rootDirectory,
TARGET_DIRECTORY), DISTRIBUTION_DIRECTORY);
if (!outDirectory.isDirectory()) {
if (!outDirectory.mkdir()) {
- throw new IOException("Can't create the \"" +
DISTRIBUTION_DIRECTORY + "\" directory.");
+ throw new MojoExecutionException("Can't create the \"" +
DISTRIBUTION_DIRECTORY + "\" directory.");
}
}
- return outDirectory;
+ return new File(outDirectory, filename);
}
}
diff --git
a/core/sis-build-helper/src/main/java/org/apache/sis/internal/maven/JarCollector.java
b/core/sis-build-helper/src/main/java/org/apache/sis/internal/maven/JarCollector.java
index 1e3b80f..141d0a1 100644
---
a/core/sis-build-helper/src/main/java/org/apache/sis/internal/maven/JarCollector.java
+++
b/core/sis-build-helper/src/main/java/org/apache/sis/internal/maven/JarCollector.java
@@ -44,10 +44,10 @@ import static org.apache.sis.internal.maven.Filenames.*;
* Collects <code>.jar</code> files in a single "{@code target/binaries}"
directory.
* Dependencies are collected as well, except if already presents. This mojo
uses hard links
* on platforms that support them. If hard links are not supported, then this
mojo will instead
- * creates a "{@code target/binaries/content.txt}" file listing the
dependencies.
+ * creates a "{@code target/binaries/other_dependencies.txt}" file listing the
dependencies.
*
* @author Martin Desruisseaux (Geomatys)
- * @version 0.7
+ * @version 1.0
* @since 0.3
* @module
*/
@@ -223,8 +223,8 @@ public final class JarCollector extends AbstractMojo
implements FileFilter {
/**
* Creates a link from the given source file to the given target file.
- * On JDK6 or on platform that do not support links, this method rather
- * updates the <code>content.txt</code> file.
+ * On platforms that do not support links, this method rather updates
+ * the {@value Filenames#OTHER_DEPENDENCIES_FILE} file.
*
* @param file the source file to read.
* @param copy the destination file to create.
@@ -237,17 +237,17 @@ public final class JarCollector extends AbstractMojo
implements FileFilter {
return;
} catch (UnsupportedOperationException | FileSystemException e) {
/*
- * If hard links are not supported, edit the "content.txt" file
instead.
+ * If hard links are not supported, edit the
"other_dependencies.txt" file instead.
* Note that a hard link may be unsupported because the source and
target
* are on different Windows drives or mount points, in which case
we get
* a FileSystemException instead than
UnsupportedOperationException.
*/
}
/*
- * If we can not use hard links, creates or updates a
"target/content.txt" file instead.
+ * If we can not use hard links, creates or updates a
"target/other_dependencies.txt" file instead.
* This file will contains the list of all dependencies, without
duplicated values.
*/
- final File dependenciesFile = new File(copy.getParentFile(),
CONTENT_FILE);
+ final File dependenciesFile = new File(copy.getParentFile(),
OTHER_DEPENDENCIES_FILE);
final Set<String> dependencies = loadDependencyList(dependenciesFile);
if (dependencies.add(file.getPath())) {
// Save the dependencies list only if it has been modified.
@@ -261,9 +261,9 @@ public final class JarCollector extends AbstractMojo
implements FileFilter {
}
/**
- * Loads the {@value #CONTENT_FILE} from the given directory, if it exists.
- * Otherwise returns an empty but modifiable set. This method is invoked on
- * platforms that do not support hard links.
+ * Loads the {@value #OTHER_DEPENDENCIES_FILE} from the given directory,
if it exists.
+ * Otherwise returns an empty but modifiable set. This method is invoked
on platforms
+ * that do not support hard links.
*/
private static Set<String> loadDependencyList(final File dependenciesFile)
throws IOException {
final Set<String> dependencies = new LinkedHashSet<>();
diff --git
a/core/sis-build-helper/src/main/java/org/apache/sis/internal/maven/PackInput.java
b/core/sis-build-helper/src/main/java/org/apache/sis/internal/maven/PackInput.java
deleted file mode 100644
index 3073038..0000000
---
a/core/sis-build-helper/src/main/java/org/apache/sis/internal/maven/PackInput.java
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * 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.sis.internal.maven;
-
-import java.util.Map;
-import java.util.Enumeration;
-import java.util.jar.*;
-import java.io.File;
-import java.io.Closeable;
-import java.io.IOException;
-import java.io.InputStream;
-
-
-/**
- * A JAR file to be used for input by {@link Packer}.
- * Those files will be open in read-only mode.
- *
- * @author Martin Desruisseaux (Geomatys)
- * @version 0.8
- * @since 0.3
- * @module
- */
-final class PackInput implements Closeable {
- /**
- * The {@code value} directory.
- */
- private static final String META_INF = "META-INF/";
-
- /**
- * Files from the {@code META-INF} directory to include.
- * Every files not in this list will be excluded.
- */
- private static final String[] INCLUDES = {"registryFile.jai"};
-
- /**
- * The {@code value} directory.
- */
- static final String SERVICES = META_INF + "services/";
-
- /**
- * The prefix of native resources in JAR files. All those resources will
be excluded from
- * the PACK200 file and stored in {@link #nativeFiles} instead (unless the
map is null).
- */
- private static final String NATIVE = "native/";
-
- /**
- * The attribute name in {@code MANIFEST.MF} files for splash screen.
- */
- static final Attributes.Name SPLASH_SCREEN = new
Attributes.Name("SplashScreen-Image");
-
- /**
- * The JAR file.
- */
- private JarFile file;
-
- /**
- * The main class obtained from the manifest, or {@code null} if none.
- */
- final String mainClass;
-
- /**
- * The splash screen image obtained from the manifest, or {@code null} if
none.
- */
- final String splashScreen;
-
- /**
- * The map where to store native files found during iteration over the JAR
entries.
- * Keys are filename without the {@value #NATIVE} prefix. Values are the
actual data.
- * If null, then no native files filtering is done.
- */
- private final Map<String,byte[]> nativeFiles;
-
- /**
- * An enumeration over the entries. We are going to iterate only once.
- */
- private Enumeration<JarEntry> entries;
-
- /**
- * The current entry under iteration.
- */
- private JarEntry entry;
-
- /**
- * Opens the given JAR file in read-only mode.
- *
- * @param file the file to open.
- * @param nativeFiles if non-null, where to store native files found
during iteration over the JAR entries.
- * @throws IOException if the file can't be open.
- */
- PackInput(final File file, final Map<String,byte[]> nativeFiles) throws
IOException {
- this.nativeFiles = nativeFiles;
- this.file = new JarFile(file);
- final Manifest manifest = this.file.getManifest();
- if (manifest != null) {
- final Attributes attributes = manifest.getMainAttributes();
- if (attributes != null) {
- mainClass = attributes.getValue(Attributes.Name.MAIN_CLASS);
- splashScreen = attributes.getValue(SPLASH_SCREEN);
- return;
- }
- }
- mainClass = null;
- splashScreen = null;
- }
-
- /**
- * Returns the entries in the input JAR file.
- *
- * @return the next entry, or {@code null} if the iteration is finished.
- */
- JarEntry nextEntry() throws IOException {
- if (entries == null) {
- entries = file.entries();
- }
- while (entries.hasMoreElements()) {
- entry = entries.nextElement();
- final String name = entry.getName();
- if (name.startsWith(META_INF) && !name.startsWith(SERVICES)) {
- if (!include(name.substring(META_INF.length()))) {
- continue;
- }
- }
- if (nativeFiles != null && name.startsWith(NATIVE)) {
- if (!entry.isDirectory()) {
- if (nativeFiles.put(name.substring(NATIVE.length()),
load()) != null) {
- throw new IOException("Duplicated entry: " + name);
- }
- }
- continue;
- }
- entry.setMethod(JarEntry.DEFLATED);
- entry.setCompressedSize(-1); // Change in
method has changed the compression size.
- return entry;
- }
- return entry = null;
- }
-
- /**
- * Returns {@code true} if the given name is part of the {@link #INCLUDES}
list.
- */
- private static boolean include(final String name) {
- for (final String include : INCLUDES) {
- if (name.equals(include)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Loads in memory the content of current JAR entry.
- * This method should be invoked only for entries of reasonable size.
- */
- private byte[] load() throws IOException {
- final long size = entry.getSize();
- if (size <= 0 || size > Integer.MAX_VALUE) {
- throw new IOException("Unsupported size for \"" + entry.getName()
+ "\": " + size);
- }
- final byte[] content = new byte[(int) size];
- final int actual;
- try (InputStream in = getInputStream()) {
- actual = in.read(content);
- }
- if (actual != size) {
- throw new IOException("Expected " + size + " bytes in \"" +
entry.getName() + "\" but found " + actual);
- }
- return content;
- }
-
- /**
- * Returns the input stream for the current entry.
- *
- * @param entry The entry for which to get an input stream.
- */
- InputStream getInputStream() throws IOException {
- return file.getInputStream(entry);
- }
-
- /**
- * Returns the input stream for the entry of the given name. This method
must be invoked
- * before the first call to {@link #nextEntry}. Each entry can be
requested only once.
- *
- * @param name the name of the entry
- * @return the input stream for the requested entry, or {@code null} if
none.
- * @throws IOException if the entry can not be read.
- * @throws IllegalStateException Programming error (pre-condition
violated).
- */
- InputStream getInputStream(final String name) throws IOException {
- if (entries != null) {
- throw new IllegalStateException("Too late for this method.");
- }
- final JarEntry candidate = file.getJarEntry(name);
- if (candidate == null) {
- return null;
- }
- return file.getInputStream(candidate);
- }
-
- /**
- * Closes this input.
- *
- * @throws IOException if an error occurred while closing the file.
- */
- @Override
- public void close() throws IOException {
- if (file != null) {
- file.close();
- }
- file = null;
- entry = null;
- entries = null;
- }
-}
diff --git
a/core/sis-build-helper/src/main/java/org/apache/sis/internal/maven/PackOutput.java
b/core/sis-build-helper/src/main/java/org/apache/sis/internal/maven/PackOutput.java
deleted file mode 100644
index 6043a98..0000000
---
a/core/sis-build-helper/src/main/java/org/apache/sis/internal/maven/PackOutput.java
+++ /dev/null
@@ -1,338 +0,0 @@
-/*
- * 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.sis.internal.maven;
-
-import java.util.Map;
-import java.util.Set;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Enumeration;
-import java.util.jar.*;
-import java.io.File;
-import java.io.Closeable;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.FileOutputStream;
-import java.util.zip.GZIPOutputStream;
-
-import static java.util.jar.Pack200.Packer.*;
-import static org.apache.sis.internal.maven.Filenames.*;
-
-
-/**
- * A JAR file to be created for output by {@link Packer}.
- *
- * @author Martin Desruisseaux (Geomatys)
- * @version 0.4
- * @since 0.3
- * @module
- */
-final class PackOutput implements Closeable {
- /**
- * The extension of class files in a JAR file.
- */
- private static final String CLASS = ".class";
-
- /**
- * The output file path.
- */
- private final File outputJAR;
-
- /**
- * The stream where to write the JAR.
- * Created only when {@link #open(File)} is invoked.
- */
- private JarOutputStream outputStream;
-
- /**
- * The manifest attribute value, or {@code null} if none. We will set this
field to the
- * value of the last {@link PackInput} to be used by this {@code
PackOutput}. This is on
- * the assumption that the last input is the main one.
- */
- private String mainClass, splashScreen;
-
- /**
- * The JAR to be used as inputs. The elements in this map will be removed
by the
- * {@link #write()} method as we are done copying the content of JAR files.
- */
- private final Map<File,PackInput> inputJARs;
-
- /**
- * The entries which were already written in the output JAR file.
- * There is two kind of entries which need this check:
- *
- * <ul>
- * <li>Directories, which may be duplicated in different JAR files.</li>
- * <li>{@code META-INF/services} files which were merged in a single
file.</li>
- * </ul>
- *
- * @see #isMergeAllowed(String)
- */
- private final Set<String> entriesDone = new HashSet<>();
-
- /**
- * Returns {@code true} if entries of the given name are allowed to be
concatenated
- * when they appear in more than one input JAR files.
- *
- * @see #entriesDone
- */
- private static boolean isMergeAllowed(final String name) {
- return name.startsWith(PackInput.SERVICES);
- }
-
- /**
- * Creates an output jar.
- *
- * @param inputJARs the input JAR filenames together with their {@code
PackInput} helpers.
- * @param outputJAR the output JAR filename.
- */
- PackOutput(final Map<File,PackInput> inputJARs, final File outputJAR) {
- this.inputJARs = inputJARs;
- this.outputJAR = outputJAR;
- for (final PackInput in : inputJARs.values()) {
- if (in.mainClass != null) {
- mainClass = in.mainClass;
- }
- if (in.splashScreen != null) {
- splashScreen = in.splashScreen;
- }
- }
- }
-
- /**
- * Opens the given JAR file for writing and creates its manifest.
- *
- * @param projectName the project name, or {@code null} if none.
- * @param version the project version, or {@code null} if none.
- * @throws IOException if the file can't be open.
- */
- void open(final String projectName, final String version) throws
IOException {
- final Manifest manifest = new Manifest();
- Attributes attributes = manifest.getMainAttributes();
- attributes.put(Attributes.Name.MANIFEST_VERSION, "1.0");
- if (projectName != null) {
- attributes.put(Attributes.Name.SPECIFICATION_TITLE,
projectName);
- attributes.put(Attributes.Name.SPECIFICATION_VENDOR,
projectName);
- attributes.put(Attributes.Name.IMPLEMENTATION_TITLE,
projectName);
- attributes.put(Attributes.Name.IMPLEMENTATION_VENDOR,
projectName);
- }
- if (version != null) {
- attributes.put(Attributes.Name.SPECIFICATION_VERSION, version);
- attributes.put(Attributes.Name.IMPLEMENTATION_VERSION, version);
- }
- if (mainClass != null) {
- attributes.put(Attributes.Name.MAIN_CLASS, mainClass);
- }
- if (splashScreen != null) {
- attributes.put(PackInput.SPLASH_SCREEN, splashScreen);
- }
- /*
- * Add the package-level manifest of every dependencies.
- */
- for (final File input : inputJARs.keySet()) {
- if (!input.getName().startsWith("sis-")) {
- String packageName = null;
- try (JarFile jar = new JarFile(input, false)) {
- final Enumeration<JarEntry> entries = jar.entries();
- while (entries.hasMoreElements()) {
- final JarEntry entry = entries.nextElement();
- final String classname = entry.getName();
- if (classname.endsWith(CLASS)) {
- int length = classname.length() - CLASS.length();
- if (packageName == null) {
- packageName = classname.substring(0, length);
- } else {
- length = Math.min(packageName.length(),
length);
- int i; for (i=0; i<length; i++) {
- if (packageName.charAt(i) !=
classname.charAt(i)) {
- break;
- }
- }
- i = packageName.lastIndexOf('/', i) + 1;
- packageName = packageName.substring(0, i);
- }
- }
- }
- if (packageName != null && packageName.length() != 0) {
- packageName = packageName.substring(0,
packageName.length()-1).replace('/', '.');
- final Attributes src =
jar.getManifest().getMainAttributes();
- attributes = new Attributes();
- if (copy(src, attributes,
Attributes.Name.SPECIFICATION_TITLE) |
- copy(src, attributes,
Attributes.Name.SPECIFICATION_VENDOR) |
- copy(src, attributes,
Attributes.Name.SPECIFICATION_VERSION) |
- copy(src, attributes,
Attributes.Name.IMPLEMENTATION_TITLE) |
- copy(src, attributes,
Attributes.Name.IMPLEMENTATION_VENDOR) |
- copy(src, attributes,
Attributes.Name.IMPLEMENTATION_VERSION))
- {
- manifest.getEntries().put(packageName, attributes);
- }
- }
- }
- }
- }
- /*
- * Open the output stream for the big JAR file.
- */
- outputStream = new JarOutputStream(new FileOutputStream(outputJAR),
manifest);
- outputStream.setLevel(1); // Use a cheap compression level since this
JAR file is temporary.
- }
-
- /**
- * Copies the value of the given attribute from a source {@code
Attributes} to a target
- * {@code Attributes} object. This is used for copying the package-level
attributes.
- *
- * @return {@code true} if the attribute has been copied.
- */
- private static boolean copy(final Attributes src, final Attributes dst,
final Attributes.Name name) {
- String value = (String) src.get(name);
- if (value != null && ((value = value.trim()).length()) != 0) {
- dst.put(name, value);
- return true;
- }
- return false;
- }
-
- /**
- * Iterates through the individual jars and merge them in single, bigger
JAR file.
- * This method closes the input JAR files as they are done.
- */
- final void writeContent() throws IOException {
- final byte[] buffer = new byte[64 * 1024];
- for (final Iterator<Map.Entry<File,PackInput>> it =
inputJARs.entrySet().iterator(); it.hasNext();) {
- final Map.Entry<File,PackInput> inputJAR = it.next();
- it.remove(); // Needs to be
removed before the inner loop below.
- try (PackInput input = inputJAR.getValue()) {
- for (JarEntry entry; (entry = input.nextEntry()) != null;) {
- final String name = entry.getName();
- boolean isMergeAllowed = false;
- if (entry.isDirectory() || (isMergeAllowed =
isMergeAllowed(name))) {
- if (!entriesDone.add(name)) {
- continue;
- }
- }
- outputStream.putNextEntry(entry);
- copy(input.getInputStream(), buffer);
- /*
- * From that points, the entry has been copied to the
target JAR. Now look in
- * following input JARs to see if there is some
META-INF/services files to merge.
- */
- if (isMergeAllowed) {
- for (final Map.Entry<File,PackInput> continuing :
inputJARs.entrySet()) {
- final InputStream in =
continuing.getValue().getInputStream(name);
- if (in != null) {
- copy(in, buffer);
- }
- }
- }
- outputStream.closeEntry();
- }
- }
- }
- }
-
- /**
- * Copies fully the given input stream to the given destination.
- * The given input stream is closed after the copy.
- *
- * @param in the input stream from which to get the the content to
copy.
- * @param buffer temporary buffer to reuse at each method call.
- * @throws IOException if an error occurred during the copy.
- */
- private void copy(final InputStream in, final byte[] buffer) throws
IOException {
- int n;
- while ((n = in.read(buffer)) >= 0) {
- outputStream.write(buffer, 0, n);
- }
- in.close();
- }
-
- /**
- * Closes this output.
- *
- * @throws IOException if an error occurred while closing the file.
- */
- @Override
- public void close() throws IOException {
- for (final PackInput input : inputJARs.values()) {
- /*
- * The code in this loop is never executed in normal execution,
since the map shall be empty after
- * successful completion of 'writeContent()'. However the map may
be non-empty if the above method
- * threw an exception, in which case this 'close()' method will be
invoked in a 'finally' block.
- */
- input.close();
- }
- inputJARs.clear();
- if (outputStream != null) {
- outputStream.close();
- }
- outputStream = null;
- }
-
- /**
- * Creates a Pack200 file from the output JAR, then delete the JAR.
- *
- * @throws IOException if an error occurred while packing the JAR.
- */
- void pack() throws IOException {
- if (outputStream != null) {
- throw new IllegalStateException("JAR output stream not closed.");
- }
- final File inputFile = outputJAR;
- String filename = inputFile.getName();
- final int ext = filename.lastIndexOf('.');
- if (ext > 0) {
- filename = filename.substring(0, ext);
- }
- filename += PACK_EXTENSION;
- final File outputFile = new File(inputFile.getParent(), filename);
- if (outputFile.equals(inputFile)) {
- throw new IOException("Input file is already packed: " +
inputFile);
- }
- pack(new FileOutputStream(outputFile));
- }
-
- /**
- * Creates a Pack200 file from the output JAR, then delete the JAR.
- *
- * @param out where to write the Pack200. This stream will be closed by
this method.
- * @throws IOException if an error occurred while packing the JAR.
- */
- void pack(final OutputStream out) throws IOException {
- if (outputStream != null) {
- throw new IllegalStateException("JAR output stream not closed.");
- }
- final File inputFile = outputJAR;
- final Pack200.Packer packer = Pack200.newPacker();
- final Map<String,String> p = packer.properties();
- p.put(EFFORT, String.valueOf(9)); // Maximum compression
level.
- p.put(SEGMENT_LIMIT, "-1"); // use largest-possible
archive segments (>10% better compression).
- p.put(KEEP_FILE_ORDER, FALSE); // Reorder files for
better compression.
- p.put(MODIFICATION_TIME, LATEST); // Smear modification
times to a single value.
- p.put(DEFLATE_HINT, TRUE); // Ignore all JAR
deflation requests.
- p.put(UNKNOWN_ATTRIBUTE, ERROR); // Throw an error if an
attribute is unrecognized
- p.put(CODE_ATTRIBUTE_PFX+"LocalVariableTable", STRIP); //
discard debug attributes.
- try (JarFile jarFile = new JarFile(inputFile)) {
- try (OutputStream deflater = new GZIPOutputStream(out)) {
- packer.pack(jarFile, deflater);
- }
- }
- if (!inputFile.delete()) {
- throw new IOException("Can't delete temporary file: " + inputFile);
- }
- }
-}
diff --git
a/core/sis-build-helper/src/main/java/org/apache/sis/internal/maven/Packer.java
b/core/sis-build-helper/src/main/java/org/apache/sis/internal/maven/Packer.java
deleted file mode 100644
index a8288f3..0000000
---
a/core/sis-build-helper/src/main/java/org/apache/sis/internal/maven/Packer.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * 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.sis.internal.maven;
-
-import java.util.Map;
-import java.util.Set;
-import java.util.LinkedHashMap;
-import java.io.File;
-import java.io.IOException;
-
-import static org.apache.sis.internal.maven.Filenames.*;
-
-
-/**
- * Creates a PACK200 files from the JAR in the {@code target/binaries}
directory.
- * This tools needs the JAR files to be either copied or linked in the {@code
target/binaries} directory,
- * or listed in the {@code target/binaries/content.txt} file.
- *
- * @author Martin Desruisseaux (Geomatys)
- * @version 0.8
- * @since 0.3
- * @module
- */
-final class Packer {
- /**
- * The project name and version to declare in the manifest file, or {@code
null} if none.
- */
- private final String projectName, version;
-
- /**
- * JAR files of the main project together with its dependencies.
- */
- private final Set<File> files;
-
- /**
- * The Maven target directory. Shall contain the {@code "binaries"}
sub-directory,
- * which shall contain all JAR files collected by {@code sis-build-helper}
plugin.
- */
- private final File targetDirectory;
-
- /**
- * The map where to store native files found during iteration over the JAR
entries.
- * Keys are filename without the {@value #NATIVE} prefix. Values are the
actual data.
- * If null, then no native files filtering is done.
- */
- private final Map<String,byte[]> nativeFiles;
-
- /**
- * Creates a packer.
- *
- * @param projectName the project name to declare in the manifest
file, or {@code null} if none.
- * @param version the project version to declare in the manifest
file, or {@code null} if none.
- * @param files the JAR files of the main project together
with its dependencies.
- * @param targetDirectory the Maven target directory.
- * @param nativeFiles if non-null, where to store native files found
during iteration over the JAR entries.
- */
- Packer(final String projectName, final String version, final Set<File>
files, final File targetDirectory,
- final Map<String,byte[]> nativeFiles)
- {
- this.projectName = projectName;
- this.version = version;
- this.files = files;
- this.targetDirectory = targetDirectory;
- this.nativeFiles = nativeFiles;
- }
-
- /**
- * Returns the list of input JAR files, together with a helper class for
copying the data in the Pack200 file.
- * All input JAR files are opened by this method. They will need to be
closed by {@link PackInput#close()}.
- */
- private Map<File,PackInput> getInputJARs() throws IOException {
- final Map<File,PackInput> inputJARs = new LinkedHashMap<>(files.size()
* 4/3);
- for (final File file : files) {
- if (!file.isFile() || !file.canRead()) {
- throw new IllegalArgumentException("Not a file or can not
read: " + file);
- }
- if (inputJARs.put(file, new PackInput(file, nativeFiles)) != null)
{
- throw new IllegalArgumentException("Duplicated JAR: " + file);
- }
- }
- return inputJARs;
- }
-
- /**
- * Prepares the Pack 200 file which will contain every JAR files in the
{@code target/binaries} directory.
- * The given {@code outputJAR} name is the name of the JAR file to create
before to be packed.
- * This filename shall end with the "{@code .jar}" suffix.
- *
- * <p>Callers needs to invoke one of the {@code PackOutput.pack(…)}
methods on the returned object.</p>
- *
- * @param outputJAR the name of the JAR file to create before the
Pack200 creation.
- * @throws IOException if an error occurred while collecting the target
directory content.
- */
- PackOutput preparePack200(final String outputJAR) throws IOException {
- /*
- * Creates the output directory. We do that first in order to avoid the
- * costly opening of all JAR files if we can't create this directory.
- */
- final File outDirectory = distributionDirectory(targetDirectory);
- final PackOutput output = new PackOutput(getInputJARs(), new
File(outDirectory, outputJAR));
- try {
- output.open(projectName, version);
- output.writeContent();
- } finally {
- output.close();
- }
- return output;
- }
-}
diff --git
a/core/sis-build-helper/src/main/java/org/apache/sis/internal/maven/package-info.java
b/core/sis-build-helper/src/main/java/org/apache/sis/internal/maven/package-info.java
index 89d48e5..8c5af5a 100644
---
a/core/sis-build-helper/src/main/java/org/apache/sis/internal/maven/package-info.java
+++
b/core/sis-build-helper/src/main/java/org/apache/sis/internal/maven/package-info.java
@@ -18,10 +18,16 @@
/**
* Maven plugins (others than {@link
org.apache.sis.util.resources.ResourceCompilerMojo}) used
- * for building Apache SIS. See the Maven-generated module description for
more information.
+ * for building Apache SIS.
+ *
+ * <ul>
+ * <li>{@link org.apache.sis.internal.maven.JarCollector} collects all JAR
files and their dependencies
+ * in a single {@code target/binaries} directory, using hard links instead
than copying the files.</li>
+ * <li>{@link org.apache.sis.internal.maven.Assembler} builds the Apache SIS
distribution file.</li>
+ * </ul>
*
* @author Martin Desruisseaux (IRD, Geomatys)
- * @version 0.8
+ * @version 1.0
* @since 0.3
* @module
*/