You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by mt...@apache.org on 2009/09/21 14:23:44 UTC

svn commit: r817224 - in /commons/sandbox/runtime/trunk/src/main: java/org/apache/commons/runtime/ java/org/apache/commons/runtime/util/ native/os/unix/ native/os/win32/

Author: mturk
Date: Mon Sep 21 12:23:42 2009
New Revision: 817224

URL: http://svn.apache.org/viewvc?rev=817224&view=rev
Log:
Add native library loader

Added:
    commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Library.java   (with props)
    commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Loader.java   (with props)
Modified:
    commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Main.java
    commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/SystemId.java
    commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/util/Utils.java
    commons/sandbox/runtime/trunk/src/main/native/os/unix/main.c
    commons/sandbox/runtime/trunk/src/main/native/os/win32/main.c

Added: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Library.java
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Library.java?rev=817224&view=auto
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Library.java (added)
+++ commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Library.java Mon Sep 21 12:23:42 2009
@@ -0,0 +1,166 @@
+/* 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.commons.runtime;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.IOException;
+
+import org.apache.commons.runtime.exception.*;
+import org.apache.commons.runtime.util.Utils;
+
+/**
+ * Loads the native libraries.
+ * <p>
+ * This class wraps the {@code System.load} and {@code System.loadLibrary}
+ * calls.
+ * </p>
+ *
+ * @since Runtime 1.0
+ *
+ */
+public final class Library
+{
+    private static String packageName;
+    private Library()
+    {
+        // No instance.
+    }
+
+    static {
+        packageName = Library.class.getPackage().getName();
+    }
+
+    /**
+     * Return the decorated shared object name.
+     * It prepends the {@code name} with {@code lib} on
+     * windows platform
+     */
+    private static String getSoName(String name)
+    {
+        String so;
+        if (!SystemId.getSysname().equals("windows"))
+            so = "lib" + name;
+        else
+            so = name;
+        return so + "." + SystemId.getSoExtension();
+    }
+
+    private static String getResName(String name)
+    {
+        String res = packageName + ".platform." + SystemId.getSysname() + ".";
+        return res.replace('.', '/') + name;
+    }
+
+    private static File extractResource(InputStream is, String name)
+        throws IllegalArgumentException, IOException
+    {
+        File f = new File(Loader.getPath(), System.mapLibraryName(name));
+        try {
+            byte [] buf = new byte[4096];
+            FileOutputStream os = new FileOutputStream(f);
+            while (true) {
+                int rd = is.read(buf);
+                if (rd > 0) {
+                    os.write(buf, 0, rd);
+                }
+                else
+                    break;
+            }
+            os.close();
+            /* TODO: For windows add this to cleanup subproc
+             */
+            f.deleteOnExit();
+            return f;
+        } catch (Exception ex) {
+            return null;
+        }
+    }
+
+    /**
+     * Load the library specified by the {@code libname} parameter.
+     * <p>
+     * Loading a library is a platform dependent operation. First the
+     * {@code System.loadLibrary(libname)} is tried.
+     * </p>
+     * @param libname the name of the library
+     * @return {@code true} if the library was successfully loaded;
+     *          {@code false} othervise.
+     */
+    public static boolean load(String libname)
+    {
+
+        if (Loader.has(libname)) {
+            /* Already loaded by a previous call
+             */
+            return true;
+        }
+        /* Step 1.
+         * Try to load from acr.boot.path
+         */
+        String boot = System.getProperty("acr.boot.path");
+        if (boot != null) {
+            try {
+                File f = new File(boot, getSoName(libname));
+                System.load(f.getPath());
+                return true;
+            } catch (Throwable ex) {
+                // Cannot load from acr.boot.path
+                // Continue...
+            }
+        }
+        /* Step 2.
+         * Try standard System.loadLibrary
+         */
+        try {
+            System.loadLibrary(libname);
+            return true;
+        } catch (UnsatisfiedLinkError ue) {
+            // Ignore
+        }
+        /* Step 3.
+         * Try to load from classpath
+         */
+        String resname;
+        InputStream is = null;
+        resname = getResName(getSoName(libname));
+        try {
+            is = Library.class.getClassLoader().getResourceAsStream(resname);
+        } catch (Exception ex) {
+            // Ignore
+        }
+        if (is != null) {
+            /* We have found a libname.
+             */
+            try {
+                File f = extractResource(is, libname);
+                if (f != null) {
+                    System.load(f.getPath());
+                    Loader.add(libname, f);
+                    return true;
+                }
+            } catch (Exception ex) {
+            }
+        }
+        /* No luck :(
+         * Return false to the caller.
+         */
+        return false;
+    }
+
+}

Propchange: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Library.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Loader.java
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Loader.java?rev=817224&view=auto
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Loader.java (added)
+++ commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Loader.java Mon Sep 21 12:23:42 2009
@@ -0,0 +1,109 @@
+/* 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.commons.runtime;
+
+import org.apache.commons.runtime.util.Utils;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.HashMap;
+
+/**
+ * Loader keeps track of loaded native libraries.
+ *
+ * @since Runtime 1.0
+ *
+ */
+public final class Loader
+{
+
+    private static HashMap<String, File> libs;
+    private static File   path = null;
+
+    private Loader()
+    {
+        // Static class. No instance.
+    }
+    static {
+        libs = new HashMap<String, File>();
+    }
+
+    /**
+     * Get the path to temporary location for extracting the
+     * libraries from resource.
+     */
+    public static File getPath()
+    {
+        synchronized(Loader.class) {
+            if (path == null) {
+                try {
+                    path = Utils.createTempDirectory("loader-");
+                    /* TODO: For windows add this to cleanup subproc
+                     */
+                    path.deleteOnExit();
+                } catch (IOException io) {
+                    // Cannot create temp dir
+                    return null;
+                }
+                try {
+                    String load = System.getProperty("java.library.path");
+                    if (load == null)
+                        load = path.getPath();
+                    else
+                        load = path.getPath() + File.pathSeparator + load;
+                    System.setProperty("java.library.path", load);
+                } catch (Exception ex) {
+                    // SecurityException ?
+                }
+            }
+            return path;
+        }
+    }
+
+    /**
+     * Add the {@code libname} referenced by {@code file} to the list
+     * of loaded libraries.
+     *
+     * @param libname The name of the library
+     */
+    public static void add(String libname, File file)
+    {
+        libs.put(libname, file);
+    }
+
+    /**
+     * Check if the {@code libname} was already loaded.
+     *
+     * @return {@code true} if the library was already loaded.
+     */
+    public static boolean has(String libname)
+    {
+        return libs.containsKey(libname);
+    }
+
+    /**
+     * Check if the any of the native libraries was loaded.
+     *
+     * @return {@code true} if the one of the native libraries was
+     *         loaded.
+     */
+    public static boolean isEmpty()
+    {
+        return libs.isEmpty();
+    }
+
+}

Propchange: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Loader.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Main.java
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Main.java?rev=817224&r1=817223&r2=817224&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Main.java (original)
+++ commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Main.java Mon Sep 21 12:23:42 2009
@@ -43,11 +43,11 @@
     public static void main(String args[])
     {
         try {
-            System.loadLibrary("acr");
+            Library.load("acr");
             boolean inited = Native.initialize();
             if (inited) {
                 System.out.println("Initialized Apache Commons Runtime : " +
-                    Version.MAJOR   + "."  + Version.MINOR     + "."  + 
+                    Version.MAJOR   + "."  + Version.MINOR     + "."  +
                     Version.PATCH   + " (" + Version.BUILDMARK + ") " + "for " +
                     Os.getSysname() + "/"  + Os.getMachine());
             }

Modified: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/SystemId.java
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/SystemId.java?rev=817224&r1=817223&r2=817224&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/SystemId.java (original)
+++ commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/SystemId.java Mon Sep 21 12:23:42 2009
@@ -187,6 +187,8 @@
         else {
             ext = "so";
         }
+        /* TODO: Check if this matches the System.mapLibraryName()
+         */
         return ext;
     }
 

Modified: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/util/Utils.java
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/util/Utils.java?rev=817224&r1=817223&r2=817224&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/util/Utils.java (original)
+++ commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/util/Utils.java Mon Sep 21 12:23:42 2009
@@ -159,9 +159,9 @@
      * This directory is specified by the system property
      * {@code java.io.tmpdir}.
      * </p>
-     * @params prefix The prefix string to be used in generating directory name.
+     * @param prefix The prefix string to be used in generating directory name.
      *                Must be at least three characters long.
-     * @returns An abstract pathname denoting newly-created empty directory.
+     * @return An abstract pathname denoting newly-created empty directory.
      */
     public static File createTempDirectory(String prefix)
         throws IllegalArgumentException, IOException
@@ -203,9 +203,9 @@
      * but allows deletion of non-empty directories.
      * </p>
      *
-     * @params dir The directory abstract pathname.
-     * @returns {@code true} if the directory is successfully deleted;
-     *          {@code false} otherwise.
+     * @param dir The directory abstract pathname.
+     * @return {@code true} if the directory is successfully deleted;
+     *         {@code false} otherwise.
      */
     public static boolean deleteDirectory(File dir)
     {

Modified: commons/sandbox/runtime/trunk/src/main/native/os/unix/main.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/unix/main.c?rev=817224&r1=817223&r2=817224&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/unix/main.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/unix/main.c Mon Sep 21 12:23:42 2009
@@ -97,6 +97,10 @@
     void   *epp;
 
     UNREFERENCED(reserved);
+#if defined(DEBUG)
+    fprintf(stdout, "JNI_Onload()\n");
+    fflush(stdout);
+#endif
     if ((*vm)->GetEnv(vm, &epp, JNI_VERSION_1_4))
         return JNI_ERR;
     if (ACR_Initialize(vm)) {

Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/main.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/main.c?rev=817224&r1=817223&r2=817224&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/win32/main.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/win32/main.c Mon Sep 21 12:23:42 2009
@@ -371,6 +371,10 @@
     void   *epp;
 
     UNREFERENCED(reserved);
+#if defined(DEBUG)
+    fprintf(stdout, "JNI_Onload()\n");
+    fflush(stdout);
+#endif
     if ((*vm)->GetEnv(vm, &epp, JNI_VERSION_1_4)) {
         return JNI_ERR;
     }