All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.lkqm.hcnet.JnaPathUtils Maven / Gradle / Ivy

There is a newer version: 0.0.5
Show newest version
package com.github.lkqm.hcnet;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import sun.awt.OSInfo;

/**
 * Jna加载本地库相关工具类。
 */
public class JnaPathUtils {

    public static final String JNA_PATH_PROPERTY_NAME = "jna.library.path";


    /**
     * 检查并设置本地库加载目录系统变量(jna.library.path), 仅开发环境下。
     */
    public static boolean initJnaLibraryPathDev() {
        return initJnaLibraryPath(null, false);
    }

    /**
     * 检查并设置本地库加载目录系统变量(jna.library.path),
     * 

* 设置的路径, 资源目录下: natives/{type}, 其中type在不同操作系统下对应值不一样(so, dll, dylib) */ public static boolean initJnaLibraryPath(Class target) { return initJnaLibraryPath(target, true); } /** * 检查并设置本地库加载目录系统变量(jna.library.path), *

* 设置的路径, 资源目录下: natives/{type}, 其中type在不同操作系统下对应值不一样(so, dll, dylib) */ public static boolean initJnaLibraryPath(Class target, boolean effectiveJar) { boolean modifiedPath = false; String jnaLibPath = System.getProperty(JNA_PATH_PROPERTY_NAME); boolean isJnaLibEmpty = (jnaLibPath == null || jnaLibPath.trim().length() == 0); if (isJnaLibEmpty) { Map libDirMap = new HashMap<>(); libDirMap.put(OSInfo.OSType.WINDOWS, "natives/dll"); libDirMap.put(OSInfo.OSType.LINUX, "natives/so"); libDirMap.put(OSInfo.OSType.MACOSX, "natives/dylib"); String libDir = libDirMap.get(OSInfo.getOSType()); if (libDir == null) { throw new RuntimeException("Unsupported operator system: " + OSInfo.getOSType().name()); } if (!isRunJar()) { URL uri = JnaPathUtils.class.getClassLoader().getResource(libDir); if (uri == null) { throw new IllegalStateException("Not found relation library: " + libDir); } jnaLibPath = uri.getPath(); System.setProperty(JNA_PATH_PROPERTY_NAME, jnaLibPath); modifiedPath = true; } else if (effectiveJar) { jnaLibPath = getJarDirectoryPath(target) + File.separator + libDir; System.setProperty(JNA_PATH_PROPERTY_NAME, jnaLibPath); modifiedPath = true; } } return modifiedPath; } /** * 是否以可执行jar方式启动 */ public static boolean isRunJar() { URL resource = JnaPathUtils.class.getResource("/"); if (resource == null) { resource = JnaPathUtils.class.getResource(""); } if (resource == null) { return false; } String protocol = resource.getProtocol(); return "jar".equals(protocol); } /** * 获取执行jar所在目录 */ public static String getJarDirectoryPath(Class target) { URL url = getLocation(target); File file = urlToFile(url); return file.getParent(); } /** * Gets the base location of the given class. *

* If the class is directly on the file system (e.g., "/path/to/my/package/MyClass.class") then it will return the * base directory (e.g., "file:/path/to"). *

*

* If the class is within a JAR file (e.g., "/path/to/my-jar.jar!/my/package/MyClass.class") then it will return the * path to the JAR (e.g., "file:/path/to/my-jar.jar"). *

* * @param c The class whose location is desired. */ private static URL getLocation(final Class c) { if (c == null) { return null; // could not load the class } // try the easy way first try { final URL codeSourceLocation = c.getProtectionDomain().getCodeSource().getLocation(); if (codeSourceLocation != null) { return codeSourceLocation; } } catch (final SecurityException e) { // NB: Cannot access protection domain. } catch (final NullPointerException e) { // NB: Protection domain or code source is null. } // NB: The easy way failed, so we try the hard way. We ask for the class // itself as a resource, then strip the class's path from the URL string, // leaving the base path. // get the class's raw resource path final URL classResource = c.getResource(c.getSimpleName() + ".class"); if (classResource == null) { return null; // cannot find class resource } final String url = classResource.toString(); final String suffix = c.getCanonicalName().replace('.', '/') + ".class"; if (!url.endsWith(suffix)) { return null; // weird URL } // strip the class's path from the URL string final String base = url.substring(0, url.length() - suffix.length()); String path = base; // remove the "jar:" prefix and "!/" suffix, if present if (path.startsWith("jar:")) { path = path.substring(4, path.length() - 2); } try { return new URL(path); } catch (final MalformedURLException e) { e.printStackTrace(); return null; } } /** * Converts the given {@link URL} to its corresponding {@link File}. *

* This method is similar to calling {@code new File(url.toURI())} except that it also handles "jar:file:" URLs, * returning the path to the JAR file. *

* * @param url The URL to convert. * @throws IllegalArgumentException if the URL does not correspond to a file. */ private static File urlToFile(final URL url) { return url == null ? null : urlToFile(url.toString()); } /** * Converts the given URL string to its corresponding {@link File}. * * @param url The URL to convert. * @throws IllegalArgumentException if the URL does not correspond to a file. */ private static File urlToFile(final String url) { String path = url; if (path.startsWith("jar:")) { // remove "jar:" prefix and "!/" suffix final int index = path.indexOf("!/"); path = path.substring(4, index); } try { if (OSInfo.getOSType() == OSInfo.OSType.WINDOWS && path.matches("file:[A-Za-z]:.*")) { path = "file:/" + path.substring(5); } return new File(new URL(path).toURI()); } catch (final MalformedURLException e) { // NB: URL is not completely well-formed. } catch (final URISyntaxException e) { // NB: URL is not completely well-formed. } if (path.startsWith("file:")) { // pass through the URL as-is, minus "file:" prefix path = path.substring(5); return new File(path); } throw new IllegalArgumentException("Invalid URL: " + url); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy