자바 프로그램에서 자바를 동적으로 설정합니다.library.path

2631 단어 1.Java
최근에 프로젝트를 하는 과정에서 제3자의jar 패키지와 동적 링크 라이브러리(dll)를 사용해야 하는데 그 중에서jar 패키지는 직접 도입할 수 있다. 문제는 개발할 때 dll는System32에 놓을 수 있다는 것이다.
그러나 프로젝트가 끝난 후build일 때 이런 방식은 통하지 않기 때문에 필요한 dll 파일을 인용하는 다른 방법을 고려해야 합니다.
VM 매개 변수에서 -Djava를 통과하는 것을 알고 있습니다.library.path 후 마운트 경로를 자신의lib 디렉터리에 지정하면 프로그램이 정상적으로 시작됩니다.
그러나 이런 방식은 분명히 유연하지 못해서main 함수에서 시작해야 하고 가상 기기의 매개 변수를 수동으로 지정해야 하기 때문에 제한된다.
프로젝트의 루트 디렉터리에 dll 폴더를 만들고 사용할 dll 파일을 이 디렉터리에 놓고
System 클래스의 setProperty 함수를 통해 코드에서 자바를 동적으로 변경합니다.library.path 값입니다.
다음과 같습니다.
System.setProperty("java.library.path","%ProjectPath%/dll");
문제는 이런 방식이 통하지 않는다는 점입니다. "no JIntellitype in java.library.path"를 잘못 보고할 수 있습니다.
원인을 찾습니다.
코드에서 설정이 작동하지 않는 것은 주로java 때문이다.library.path는 jvm가 시작될 때만 한 번 읽을 수 있으며, 다른 경우 수정이 적용되지 않습니다.다음 버그를 참조하십시오.http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4280189
이유는 ClassLoader의 구현과 관련이 있습니다.
jdk의 원본 코드를 보면 다음과 같습니다.
 if (sys_paths == null) {
     usr_paths = initializePath("java.library.path");
     sys_paths = initializePath("sun.boot.library.path");
 }

시스템에서 java를 캐시했습니다.library.path의 값이며, 처음 불러올 때의 값입니다.
다음 수정 방법을 언급한 사람이 있는데,
if(sys_paths == null) {
    sys_paths= initializePath("sun.boot.library.path");
}
    usr_paths= initializePath("java.library.path");

문제가 있으면 누군가가 문제를 해결할 수 있다. 구글에서 안토니를 발견할 수 있다miguel은 한 문장에서 자바의 반사 메커니즘을 사용하여 ClassLoader 클래스의 usr 를 완성했다paths 변수의 동적 수정,
public static void addLibraryDir(String libraryPath) throws IOException {
		try {
			Field field = ClassLoader.class.getDeclaredField("usr_paths");
			field.setAccessible(true);
			String[] paths = (String[]) field.get(null);
			for (int i = 0; i < paths.length; i++) {
				if (libraryPath.equals(paths[i])) {
					return;
				}
			}

			String[] tmp = new String[paths.length + 1];
			System.arraycopy(paths, 0, tmp, 0, paths.length);
			tmp[paths.length] = libraryPath;
			field.set(null, tmp);
		} catch (IllegalAccessException e) {
			throw new IOException(
					"Failedto get permissions to set library path");
		} catch (NoSuchFieldException e) {
			throw new IOException(
					"Failedto get field handle to set library path");
		}
	}

문장도 이러한 실현의 한계성을 동시에 지적했고 jvm의 실현과 강한 관련이 있다. jvm가 사용하지 않는 변수 usr 를 실현하면paths에서 java를 저장합니다.library.path의 값입니다. 이 방법은 사용할 수 없습니다.그러나 원본 코드만 알면 작은 변화가 이루어질 수 있을 것이다.
 
위의 방법을 호출해서 dll 파일 디렉터리를java에 추가합니다.library.path 경로 아래에서 System을 사용합니다.loadLibrary("glpk 4 55")는 dll 파일을 로드합니다.
 
over~

좋은 웹페이지 즐겨찾기