sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1811420 - in /sis/branches/JDK8: application/sis-console/src/main/artifact/lib/ application/sis-console/src/main/artifact/lib/darwin/ application/sis-console/src/main/artifact/lib/linux/ application/sis-console/src/main/artifact/lib/window...
Date Sat, 07 Oct 2017 12:51:01 GMT
Author: desruisseaux
Date: Sat Oct  7 12:51:00 2017
New Revision: 1811420

URL: http://svn.apache.org/viewvc?rev=1811420&view=rev
Log:
Store native libraries in a "linux", "darwin" or "windows" sub-directory at the same level
than the SIS JAR file.

Added:
    sis/branches/JDK8/application/sis-console/src/main/artifact/lib/darwin/
    sis/branches/JDK8/application/sis-console/src/main/artifact/lib/darwin/content.txt   (with
props)
    sis/branches/JDK8/application/sis-console/src/main/artifact/lib/linux/
    sis/branches/JDK8/application/sis-console/src/main/artifact/lib/linux/content.txt   (with
props)
    sis/branches/JDK8/application/sis-console/src/main/artifact/lib/windows/
    sis/branches/JDK8/application/sis-console/src/main/artifact/lib/windows/content.txt  
(with props)
Modified:
    sis/branches/JDK8/application/sis-console/src/main/artifact/lib/README
    sis/branches/JDK8/core/sis-build-helper/src/main/java/org/apache/sis/internal/maven/Assembler.java
    sis/branches/JDK8/core/sis-build-helper/src/main/java/org/apache/sis/internal/maven/BundleCreator.java
    sis/branches/JDK8/core/sis-build-helper/src/main/java/org/apache/sis/internal/maven/Filenames.java
    sis/branches/JDK8/core/sis-build-helper/src/main/java/org/apache/sis/internal/maven/PackInput.java
    sis/branches/JDK8/core/sis-build-helper/src/main/java/org/apache/sis/internal/maven/PackOutput.java
    sis/branches/JDK8/core/sis-build-helper/src/main/java/org/apache/sis/internal/maven/Packer.java
    sis/branches/JDK8/core/sis-build-helper/src/main/java/org/apache/sis/internal/unopkg/UnoPkg.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/system/OS.java

Modified: sis/branches/JDK8/application/sis-console/src/main/artifact/lib/README
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/application/sis-console/src/main/artifact/lib/README?rev=1811420&r1=1811419&r2=1811420&view=diff
==============================================================================
--- sis/branches/JDK8/application/sis-console/src/main/artifact/lib/README [UTF-8] (original)
+++ sis/branches/JDK8/application/sis-console/src/main/artifact/lib/README [UTF-8] Sat Oct
 7 12:51:00 2017
@@ -1,4 +1,12 @@
 This directory contains the sis.jar file together with optional dependencies.
 Recognized optional dependencies are:
 
+  - Derby database
   - UCAR netCDF library
+  - ESRI Geometry API
+  - Java Topology Suite
+
+The "linux", "darwin" and "windows" sub-directories contain bridges to Proj.4
+and other libraries through Java Native Interfaces (JNI). They do not contain
+the actual libraries however; Apache SIS uses the libraries installed on host
+computer by packages manager, if any. Those libraries are optional.

Added: sis/branches/JDK8/application/sis-console/src/main/artifact/lib/darwin/content.txt
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/application/sis-console/src/main/artifact/lib/darwin/content.txt?rev=1811420&view=auto
==============================================================================
--- sis/branches/JDK8/application/sis-console/src/main/artifact/lib/darwin/content.txt (added)
+++ sis/branches/JDK8/application/sis-console/src/main/artifact/lib/darwin/content.txt [UTF-8]
Sat Oct  7 12:51:00 2017
@@ -0,0 +1,2 @@
+Placeholder for MacOS "*.so" files to be copied by the
+org.apache.sis.core:sis-build-helper:dist Maven plugin.

Propchange: sis/branches/JDK8/application/sis-console/src/main/artifact/lib/darwin/content.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK8/application/sis-console/src/main/artifact/lib/darwin/content.txt
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Added: sis/branches/JDK8/application/sis-console/src/main/artifact/lib/linux/content.txt
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/application/sis-console/src/main/artifact/lib/linux/content.txt?rev=1811420&view=auto
==============================================================================
--- sis/branches/JDK8/application/sis-console/src/main/artifact/lib/linux/content.txt (added)
+++ sis/branches/JDK8/application/sis-console/src/main/artifact/lib/linux/content.txt [UTF-8]
Sat Oct  7 12:51:00 2017
@@ -0,0 +1,2 @@
+Placeholder for Linux "*.so" files to be copied by the
+org.apache.sis.core:sis-build-helper:dist Maven plugin.

Propchange: sis/branches/JDK8/application/sis-console/src/main/artifact/lib/linux/content.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK8/application/sis-console/src/main/artifact/lib/linux/content.txt
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Added: sis/branches/JDK8/application/sis-console/src/main/artifact/lib/windows/content.txt
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/application/sis-console/src/main/artifact/lib/windows/content.txt?rev=1811420&view=auto
==============================================================================
--- sis/branches/JDK8/application/sis-console/src/main/artifact/lib/windows/content.txt (added)
+++ sis/branches/JDK8/application/sis-console/src/main/artifact/lib/windows/content.txt [UTF-8]
Sat Oct  7 12:51:00 2017
@@ -0,0 +1,2 @@
+Placeholder for Windows "*.dll" files to be copied by the
+org.apache.sis.core:sis-build-helper:dist Maven plugin.

Propchange: sis/branches/JDK8/application/sis-console/src/main/artifact/lib/windows/content.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK8/application/sis-console/src/main/artifact/lib/windows/content.txt
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Modified: sis/branches/JDK8/core/sis-build-helper/src/main/java/org/apache/sis/internal/maven/Assembler.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-build-helper/src/main/java/org/apache/sis/internal/maven/Assembler.java?rev=1811420&r1=1811419&r2=1811420&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-build-helper/src/main/java/org/apache/sis/internal/maven/Assembler.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-build-helper/src/main/java/org/apache/sis/internal/maven/Assembler.java
[UTF-8] Sat Oct  7 12:51:00 2017
@@ -21,6 +21,8 @@ import java.io.IOException;
 import java.io.FilenameFilter;
 import java.io.FileInputStream;
 import java.io.FilterOutputStream;
+import java.util.LinkedHashMap;
+import java.util.Map;
 import org.apache.maven.plugin.AbstractMojo;
 import org.apache.maven.plugin.MojoExecutionException;
 import org.apache.maven.plugins.annotations.Mojo;
@@ -37,7 +39,7 @@ import static org.apache.sis.internal.ma
 /**
  * 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>.
- * This mojo can be invoked from the command line in the {@code sis-console} module as below:
+ * 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>
  *
@@ -52,7 +54,7 @@ import static org.apache.sis.internal.ma
  * @since   0.4
  * @module
  */
-@Mojo(name = "dist", defaultPhase = LifecyclePhase.INSTALL, requiresDependencyResolution
= ResolutionScope.COMPILE)
+@Mojo(name = "dist", defaultPhase = LifecyclePhase.INSTALL, requiresDependencyResolution
= ResolutionScope.COMPILE_PLUS_RUNTIME)
 public final class Assembler extends AbstractMojo implements FilenameFilter {
     /**
      * Project information (name, version, URL).
@@ -94,6 +96,7 @@ public final class Assembler extends Abs
         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)) {
@@ -104,20 +107,28 @@ public final class Assembler extends Abs
                  * 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);
-                final ZipArchiveEntry entry = new ZipArchiveEntry(
-                        artifactBase + '/' + LIB_DIRECTORY + '/' + FATJAR_FILE + PACK_EXTENSION);
+                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);
                 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 {
+                    /** 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);
+                }
             }
         } catch (IOException e) {
             throw new MojoExecutionException(e.getLocalizedMessage(), e);
@@ -143,6 +154,7 @@ public final class Assembler extends Abs
         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);
@@ -166,6 +178,6 @@ public final class Assembler extends Abs
      */
     @Override
     public boolean accept(final File directory, final String filename) {
-        return !filename.isEmpty() && filename.charAt(0) != '.';
+        return !filename.isEmpty() && filename.charAt(0) != '.' && !filename.equals(CONTENT_FILE);
     }
 }

Modified: sis/branches/JDK8/core/sis-build-helper/src/main/java/org/apache/sis/internal/maven/BundleCreator.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-build-helper/src/main/java/org/apache/sis/internal/maven/BundleCreator.java?rev=1811420&r1=1811419&r2=1811420&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-build-helper/src/main/java/org/apache/sis/internal/maven/BundleCreator.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-build-helper/src/main/java/org/apache/sis/internal/maven/BundleCreator.java
[UTF-8] Sat Oct  7 12:51:00 2017
@@ -85,7 +85,7 @@ public final class BundleCreator extends
         }
         final String version = project.getVersion();
         try {
-            final Packer packer = new Packer(project.getName(), version, files(project),
targetDirectory);
+            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);

Modified: sis/branches/JDK8/core/sis-build-helper/src/main/java/org/apache/sis/internal/maven/Filenames.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-build-helper/src/main/java/org/apache/sis/internal/maven/Filenames.java?rev=1811420&r1=1811419&r2=1811420&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-build-helper/src/main/java/org/apache/sis/internal/maven/Filenames.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-build-helper/src/main/java/org/apache/sis/internal/maven/Filenames.java
[UTF-8] Sat Oct  7 12:51:00 2017
@@ -48,7 +48,8 @@ final class Filenames {
 
     /**
      * The name of the file inside {@value #BINARIES_DIRECTORY} where to list SIS JAR files
and their
-     * dependencies on platforms that do not support hard links.
+     * dependencies on platforms that do not support hard links. Also the file to ignore
when copying
+     * entries in a ZIP file.
      */
     static final String CONTENT_FILE = "content.txt";
 

Modified: sis/branches/JDK8/core/sis-build-helper/src/main/java/org/apache/sis/internal/maven/PackInput.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-build-helper/src/main/java/org/apache/sis/internal/maven/PackInput.java?rev=1811420&r1=1811419&r2=1811420&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-build-helper/src/main/java/org/apache/sis/internal/maven/PackInput.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-build-helper/src/main/java/org/apache/sis/internal/maven/PackInput.java
[UTF-8] Sat Oct  7 12:51:00 2017
@@ -16,6 +16,7 @@
  */
 package org.apache.sis.internal.maven;
 
+import java.util.Map;
 import java.util.Enumeration;
 import java.util.jar.*;
 import java.io.File;
@@ -29,7 +30,7 @@ import java.io.InputStream;
  * Those files will be open in read-only mode.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.3
+ * @version 0.8
  * @since   0.3
  * @module
  */
@@ -51,6 +52,12 @@ final class PackInput implements Closeab
     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");
@@ -63,12 +70,19 @@ final class PackInput implements Closeab
     /**
      * The main class obtained from the manifest, or {@code null} if none.
      */
-    public final String mainClass;
+    final String mainClass;
 
     /**
      * The splash screen image obtained from the manifest, or {@code null} if none.
      */
-    public final String splashScreen;
+    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.
@@ -83,10 +97,12 @@ final class PackInput implements Closeab
     /**
      * Opens the given JAR file in read-only mode.
      *
-     * @param  file  the file to open.
+     * @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) throws IOException {
+    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) {
@@ -106,7 +122,7 @@ final class PackInput implements Closeab
      *
      * @return the next entry, or {@code null} if the iteration is finished.
      */
-    JarEntry nextEntry() {
+    JarEntry nextEntry() throws IOException {
         if (entries == null) {
             entries = file.entries();
         }
@@ -118,6 +134,14 @@ final class PackInput implements Closeab
                     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;
@@ -138,6 +162,26 @@ final class PackInput implements Closeab
     }
 
     /**
+     * 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.

Modified: sis/branches/JDK8/core/sis-build-helper/src/main/java/org/apache/sis/internal/maven/PackOutput.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-build-helper/src/main/java/org/apache/sis/internal/maven/PackOutput.java?rev=1811420&r1=1811419&r2=1811420&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-build-helper/src/main/java/org/apache/sis/internal/maven/PackOutput.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-build-helper/src/main/java/org/apache/sis/internal/maven/PackOutput.java
[UTF-8] Sat Oct  7 12:51:00 2017
@@ -215,7 +215,7 @@ final class PackOutput implements Closea
         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.
+            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();
@@ -253,7 +253,7 @@ final class PackOutput implements Closea
      * @param  buffer  temporary buffer to reuse at each method call.
      * @throws IOException if an error occurred during the copy.
      */
-    void copy(final InputStream in, final byte[] buffer) throws IOException {
+    private void copy(final InputStream in, final byte[] buffer) throws IOException {
         int n;
         while ((n = in.read(buffer)) >= 0) {
             outputStream.write(buffer, 0, n);

Modified: sis/branches/JDK8/core/sis-build-helper/src/main/java/org/apache/sis/internal/maven/Packer.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-build-helper/src/main/java/org/apache/sis/internal/maven/Packer.java?rev=1811420&r1=1811419&r2=1811420&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-build-helper/src/main/java/org/apache/sis/internal/maven/Packer.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-build-helper/src/main/java/org/apache/sis/internal/maven/Packer.java
[UTF-8] Sat Oct  7 12:51:00 2017
@@ -53,18 +53,29 @@ final class Packer {
     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) {
+    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;
     }
 
     /**
@@ -77,7 +88,7 @@ final class Packer {
             if (!file.isFile() || !file.canRead()) {
                 throw new IllegalArgumentException("Not a file or can not read: " + file);
             }
-            if (inputJARs.put(file, new PackInput(file)) != null) {
+            if (inputJARs.put(file, new PackInput(file, nativeFiles)) != null) {
                 throw new IllegalArgumentException("Duplicated JAR: " + file);
             }
         }

Modified: sis/branches/JDK8/core/sis-build-helper/src/main/java/org/apache/sis/internal/unopkg/UnoPkg.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-build-helper/src/main/java/org/apache/sis/internal/unopkg/UnoPkg.java?rev=1811420&r1=1811419&r2=1811420&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-build-helper/src/main/java/org/apache/sis/internal/unopkg/UnoPkg.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-build-helper/src/main/java/org/apache/sis/internal/unopkg/UnoPkg.java
[UTF-8] Sat Oct  7 12:51:00 2017
@@ -44,7 +44,7 @@ import static java.util.jar.Pack200.Pack
  * @since   0.8
  * @module
  */
-@Mojo(name = "unopkg", defaultPhase = LifecyclePhase.PACKAGE, requiresDependencyResolution
= ResolutionScope.COMPILE)
+@Mojo(name = "unopkg", defaultPhase = LifecyclePhase.PACKAGE, requiresDependencyResolution
= ResolutionScope.COMPILE_PLUS_RUNTIME)
 public final class UnoPkg extends AbstractMojo implements FilenameFilter {
     /**
      * The subdirectory (relative to {@link #baseDirectory}) where the UNO files are expected.

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/system/OS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/system/OS.java?rev=1811420&r1=1811419&r2=1811420&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/system/OS.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/system/OS.java
[UTF-8] Sat Oct  7 12:51:00 2017
@@ -17,6 +17,7 @@
 package org.apache.sis.internal.system;
 
 import java.net.URL;
+import java.net.URI;
 import java.net.URISyntaxException;
 import java.io.File;
 import java.io.InputStream;
@@ -122,7 +123,7 @@ public enum OS {
      */
     public static void load(final Class<?> caller, final String name) {
         try {
-            System.load(current().nativeLibrary(caller.getClassLoader(), name));
+            System.load(current().nativeLibrary(caller, name));
         } catch (IOException | SecurityException e) {
             throw (UnsatisfiedLinkError) new UnsatisfiedLinkError(e.getMessage()).initCause(e);
         }
@@ -133,7 +134,7 @@ public enum OS {
      * If the resources can not be accessed by an absolute path, then this method
      * copies the resource in a temporary file.
      *
-     * @param  loader  the loader of the JAR file where to look for native resources.
+     * @param  caller  a class in the JAR file where to look for native resources.
      * @param  name    the native library name without {@code ".so"} or {@code ".dll"} extension.
      * @return absolute path to the library (may be a temporary file).
      * @throws IOException if an error occurred while copying the library to a temporary
file.
@@ -142,11 +143,40 @@ public enum OS {
      *
      * @see System#load(String)
      */
-    private String nativeLibrary(final ClassLoader loader, final String name) throws IOException
{
+    private String nativeLibrary(final Class<?> caller, final String name) throws IOException
{
         if (libdir != null) {
             final String ext = unix ? ".so" : ".dll";
-            final String path = "native/" + libdir + '/' + name + ext;
-            final URL res = loader.getResource(path);
+            final String path = libdir + '/' + name + ext;
+            final ClassLoader loader = caller.getClassLoader();
+            /*
+             * First, verify if the "linux", "darwin" or "windows" directory exists at the
same level
+             * than the JAR file containing the caller class. If it exists, then we will
use it. This
+             * check avoid the need to copy the ".so" or ".dll" file in a temporary location.
 If the
+             * directory does not exist, then we do NOT create it in order to reduce the
risk to mess
+             * with user's installation.
+             *
+             * Example of URL for a JAR entry: jar:file:/home/…/sis-gdal.jar!/org/apache/…/PJ.class
+             */
+            URL res = loader.getResource(caller.getName().replace('.', '/').concat(".class"));
+            if (res != null && "jar".equals(res.getProtocol())) {
+                String file = res.getPath();
+                final int s = file.indexOf('!');
+                if (s >= 0) try {
+                    File location = new File(new URI(file.substring(0, s)));
+                    location = new File(location.getParentFile(), path);
+                    if (location.canExecute()) {
+                        return location.getAbsolutePath();
+                    }
+                } catch (IllegalArgumentException | URISyntaxException e) {
+                    Logging.recoverableException(Logging.getLogger(Loggers.SYSTEM), OS.class,
"nativeLibrary", e);
+                }
+            }
+            /*
+             * If we didn't found an existing "linux", "darwin" or "windows" directory with
native library,
+             * copy the library in a temporary file. That file will be deleted on JVM exists,
so a new file
+             * will be copied each time the application is executed.
+             */
+            res = loader.getResource("native/".concat(path));
             if (res != null) {
                 try {
                     return new File(res.toURI()).getAbsolutePath();



Mime
View raw message