xref: /AOO41X/main/jurt/com/sun/star/lib/util/NativeLibraryLoader.java (revision cc99fae5970dc3853e78bcff9dd0f29ad299fb82)
12be43276SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
32be43276SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
42be43276SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
52be43276SAndrew Rist  * distributed with this work for additional information
62be43276SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
72be43276SAndrew Rist  * to you under the Apache License, Version 2.0 (the
82be43276SAndrew Rist  * "License"); you may not use this file except in compliance
92be43276SAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
112be43276SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
132be43276SAndrew Rist  * Unless required by applicable law or agreed to in writing,
142be43276SAndrew Rist  * software distributed under the License is distributed on an
152be43276SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
162be43276SAndrew Rist  * KIND, either express or implied.  See the License for the
172be43276SAndrew Rist  * specific language governing permissions and limitations
182be43276SAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
202be43276SAndrew Rist  *************************************************************/
212be43276SAndrew Rist 
222be43276SAndrew Rist 
23cdf0e10cSrcweir package com.sun.star.lib.util;
24cdf0e10cSrcweir 
25cdf0e10cSrcweir import java.io.File;
26cdf0e10cSrcweir import java.net.URL;
27cdf0e10cSrcweir import java.net.URLClassLoader;
28cdf0e10cSrcweir 
29cdf0e10cSrcweir /** Helper functions to locate and load native files.
30cdf0e10cSrcweir 
31cdf0e10cSrcweir     The methods in this class are designed to find the requested resources in as
32cdf0e10cSrcweir     many cases as possible.  They search various places, roughly from most
33cdf0e10cSrcweir     specific to most general.  This works well if a component is known to bring
34cdf0e10cSrcweir     with it a certain resource, and that resource has to be found.  However, it
35cdf0e10cSrcweir     might not work very well in cases where you want to check whether a
36cdf0e10cSrcweir     component brings with it a certain resource or not: a similarly named
37cdf0e10cSrcweir     resource from another component might be found by the eager search
38cdf0e10cSrcweir     algorithm.
39cdf0e10cSrcweir  */
40cdf0e10cSrcweir public final class NativeLibraryLoader {
41cdf0e10cSrcweir     /** Load a system library, using a given class loader to locate the library.
42cdf0e10cSrcweir 
43cdf0e10cSrcweir         This is similar to System.loadLibrary.
44cdf0e10cSrcweir 
45cdf0e10cSrcweir         @param loader a class loader; may be null
46cdf0e10cSrcweir 
47cdf0e10cSrcweir         @param libname the library name; how this name is mapped to a system
48cdf0e10cSrcweir         library name is system dependent
49cdf0e10cSrcweir      */
loadLibrary(ClassLoader loader, String libname)50cdf0e10cSrcweir     public static void loadLibrary(ClassLoader loader, String libname) {
51*cc99fae5SJürgen Schmidt         String syslibname = System.mapLibraryName(libname);
52*cc99fae5SJürgen Schmidt 
53cdf0e10cSrcweir         File path = getResource(loader, System.mapLibraryName(libname));
54cdf0e10cSrcweir         if (path == null) {
55*cc99fae5SJürgen Schmidt             // check special jni lib extension on Mac
56*cc99fae5SJürgen Schmidt             if (syslibname.contains("dylib")) {
57*cc99fae5SJürgen Schmidt                 syslibname = syslibname.replace("dylib", "jnilib");
58*cc99fae5SJürgen Schmidt             }
59*cc99fae5SJürgen Schmidt             path = getResource(loader, syslibname);
60*cc99fae5SJürgen Schmidt         }
61*cc99fae5SJürgen Schmidt 
62*cc99fae5SJürgen Schmidt         if (path == null) {
63cdf0e10cSrcweir             // If the library cannot be found as a class loader resource, try
64cdf0e10cSrcweir             // the global System.loadLibrary as a last resort:
65cdf0e10cSrcweir             System.loadLibrary(libname);
66cdf0e10cSrcweir         } else {
67cdf0e10cSrcweir             System.load(path.getAbsolutePath());
68cdf0e10cSrcweir         }
69cdf0e10cSrcweir     }
70cdf0e10cSrcweir 
71cdf0e10cSrcweir     /** Locate a system resource, using a given class loader.
72cdf0e10cSrcweir 
73cdf0e10cSrcweir         This is similar to ClassLoader.getResource, but only works for local
74cdf0e10cSrcweir         resources (local files), and adds additional functionality for
75cdf0e10cSrcweir         URLClassLoaders.
76cdf0e10cSrcweir 
77cdf0e10cSrcweir         @param loader a class loader; may be null
78cdf0e10cSrcweir 
79cdf0e10cSrcweir         @param name a resource name (that is, the name of a file)
80cdf0e10cSrcweir 
81cdf0e10cSrcweir         @return a File locating the resource, or null if the resource was not
82cdf0e10cSrcweir         found
83cdf0e10cSrcweir      */
getResource(ClassLoader loader, String name)84cdf0e10cSrcweir     public static File getResource(ClassLoader loader, String name) {
85cdf0e10cSrcweir         if (loader != null) {
86cdf0e10cSrcweir             File path = UrlToFileMapper.mapUrlToFile(loader.getResource(name));
87cdf0e10cSrcweir             if (path != null) {
88cdf0e10cSrcweir                 return path;
89cdf0e10cSrcweir             }
90cdf0e10cSrcweir         }
91cdf0e10cSrcweir         // URLClassLoaders work on lists of URLs, which are typically URLs
92cdf0e10cSrcweir         // locating JAR files (scheme://auth/dir1/dir2/some.jar).  The following
93cdf0e10cSrcweir         // code looks for resource name beside the JAR file
94cdf0e10cSrcweir         // (scheme://auth/dir1/dir2/name) and one directory up
95cdf0e10cSrcweir         // (scheme://auth/dir1/name).  The second step is important in a typical
96cdf0e10cSrcweir         // OOo installation, where the JAR files are in the program/classes
97cdf0e10cSrcweir         // directory while the shared libraries are in the program directory.
98cdf0e10cSrcweir         if (loader instanceof URLClassLoader) {
99cdf0e10cSrcweir             URL[] urls = ((URLClassLoader) loader).getURLs();
100cdf0e10cSrcweir             for (int i = 0; i < urls.length; ++i) {
101cdf0e10cSrcweir                 File path = UrlToFileMapper.mapUrlToFile(urls[i]);
102cdf0e10cSrcweir                 if (path != null) {
103cdf0e10cSrcweir                     File dir = path.isDirectory() ? path : path.getParentFile();
104cdf0e10cSrcweir                     if (dir != null) {
105cdf0e10cSrcweir                         path = new File(dir, name);
106cdf0e10cSrcweir                         if (path.exists()) {
107cdf0e10cSrcweir                             return path;
108cdf0e10cSrcweir                         }
109cdf0e10cSrcweir                         dir = dir.getParentFile();
110cdf0e10cSrcweir                         if (dir != null) {
111cdf0e10cSrcweir                             path = new File(dir, name);
112cdf0e10cSrcweir                             if (path.exists()) {
113cdf0e10cSrcweir                                 return path;
114cdf0e10cSrcweir                             }
115cdf0e10cSrcweir                         }
116cdf0e10cSrcweir                     }
117cdf0e10cSrcweir                 }
118cdf0e10cSrcweir             }
119cdf0e10cSrcweir         }
120cdf0e10cSrcweir         return null;
121cdf0e10cSrcweir     }
122cdf0e10cSrcweir 
NativeLibraryLoader()123cdf0e10cSrcweir     private NativeLibraryLoader() {} // do not instantiate
124cdf0e10cSrcweir }
125