From 1d9d88c648de74002e29d7b309280da365fe18ee Mon Sep 17 00:00:00 2001 From: hirukawa_ryo Date: Sun, 12 Jul 2020 11:16:23 +0000 Subject: [PATCH] =?UTF-8?q?*=20exewrap=201.6.2=20=E3=82=AB=E3=82=B9?= =?UTF-8?q?=E3=82=BF=E3=83=A0=E3=82=AF=E3=83=A9=E3=82=B9=E3=83=AD=E3=83=BC?= =?UTF-8?q?=E3=83=80=E3=83=BCLoader=E3=81=8CURLClassLoader=E3=82=92?= =?UTF-8?q?=E7=B6=99=E6=89=BF=E3=81=99=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB?= =?UTF-8?q?=E5=A4=89=E6=9B=B4=E3=81=97=E3=80=81Loader=E3=81=8C=E5=A4=96?= =?UTF-8?q?=E9=83=A8=E3=83=A9=E3=82=A4=E3=83=96=E3=83=A9=E3=83=AA=EF=BC=88?= =?UTF-8?q?JAR=EF=BC=89=E3=81=8B=E3=82=89=E3=81=AE=E3=82=AF=E3=83=A9?= =?UTF-8?q?=E3=82=B9=E3=83=AD=E3=83=BC=E3=83=89=E3=82=82=E6=8B=85=E5=BD=93?= =?UTF-8?q?=E3=81=99=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB=E5=A4=89=E6=9B=B4?= =?UTF-8?q?=E3=81=97=E3=81=BE=E3=81=97=E3=81=9F=E3=80=82=20=E5=BE=93?= =?UTF-8?q?=E6=9D=A5=E3=81=AFLoader=E3=81=AFEXE=E5=86=85=E3=83=AA=E3=82=BD?= =?UTF-8?q?=E3=83=BC=E3=82=B9=E3=81=8B=E3=82=89=E3=81=AE=E3=82=AF=E3=83=A9?= =?UTF-8?q?=E3=82=B9=E3=83=AD=E3=83=BC=E3=83=89=E3=81=AE=E3=81=BF=E3=82=92?= =?UTF-8?q?=E6=8B=85=E5=BD=93=E3=81=97=E3=80=81=E5=A4=96=E9=83=A8=E3=83=A9?= =?UTF-8?q?=E3=82=A4=E3=83=96=E3=83=A9=E3=83=AA=EF=BC=88JAR=EF=BC=89?= =?UTF-8?q?=E3=81=8B=E3=82=89=E3=81=AE=E3=82=AF=E3=83=A9=E3=82=B9=E3=83=AD?= =?UTF-8?q?=E3=83=BC=E3=83=89=E3=81=AF=E8=A6=AA=E3=82=AF=E3=83=A9=E3=82=B9?= =?UTF-8?q?=E3=83=AD=E3=83=BC=E3=83=80=E3=83=BC=EF=BC=88AppClassLoader?= =?UTF-8?q?=EF=BC=89=E3=81=AB=E4=BB=BB=E3=81=9B=E3=81=A6=E3=81=84=E3=81=BE?= =?UTF-8?q?=E3=81=97=E3=81=9F=E3=80=82=20=E3=82=AF=E3=83=A9=E3=82=B9?= =?UTF-8?q?=E3=83=AD=E3=83=BC=E3=83=80=E3=83=BC=E3=81=8CLoader=E3=81=A8App?= =?UTF-8?q?ClassLoader=E3=81=AE2=E3=81=A4=E3=81=AB=E5=88=86=E3=81=8B?= =?UTF-8?q?=E3=82=8C=E3=81=A6=E3=81=84=E3=82=8B=E3=81=A8=E6=84=8F=E5=9B=B3?= =?UTF-8?q?=E3=81=97=E3=81=AA=E3=81=84=E5=8B=95=E4=BD=9C=E3=82=92=E3=81=99?= =?UTF-8?q?=E3=82=8B=E3=82=B1=E3=83=BC=E3=82=B9=E3=81=8C=E3=81=82=E3=82=8B?= =?UTF-8?q?=E3=81=9F=E3=82=81=E3=81=AE=E5=AF=BE=E5=87=A6=E3=81=A7=E3=81=99?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit たとえば、logbackはlogbackのクラスをロードしたクラスローダーからしか設定ファイルlogback.xmlリソースを検索しません。 このようなケースでlogbackのクラスがAppClassLoaderの担当する外部ライブラリ(JAR)からロードされ、設定ファイルlogback.xmlがLoaderの担当するEXE内リソースに存在すると logbackのクラスが設定ファイルlogback.xmlを見つけることができませんでした。 今回の対処により外部ライブラリ(JAR)からのlogbackクラスもLoaderによってロードされるようになり、Loader担当のEXE内リソースlogback.xmlを見つけられるようになります。 git-svn-id: http://svn.osdn.net/svnroot/exewrap/exewrap/trunk/exewrap@90 d83a06de-854e-4732-85b7-fdf7162022b6 --- src/include/jvm.h | 1 + src/java/Loader.java | 51 +++++++++++++++++++++++++++++++++++----- src/jvm.c | 15 ++++++++---- src/loader.c | 8 +++---- src/resources/exewrap.rc | 4 ++-- 5 files changed, 62 insertions(+), 17 deletions(-) diff --git a/src/include/jvm.h b/src/include/jvm.h index b88d176..27c0777 100644 --- a/src/include/jvm.h +++ b/src/include/jvm.h @@ -19,6 +19,7 @@ extern jint destroy_java_vm(void); extern JNIEnv* attach_java_vm(void); extern jint detach_java_vm(void); extern BOOL set_application_properties(SYSTEMTIME* startup); +extern wchar_t* get_classpath(void); extern void get_java_runtime_version(const wchar_t* version_string, DWORD* major, DWORD* minor, DWORD* build, DWORD* revision); extern wchar_t* get_java_version_string(DWORD major, DWORD minor, DWORD build, DWORD revision); extern wchar_t* get_module_version(wchar_t* buf, size_t size); diff --git a/src/java/Loader.java b/src/java/Loader.java index 5046ad3..e678489 100644 --- a/src/java/Loader.java +++ b/src/java/Loader.java @@ -1,4 +1,5 @@ import java.io.ByteArrayOutputStream; +import java.io.File; import java.io.FileDescriptor; import java.io.FileOutputStream; import java.io.IOException; @@ -6,6 +7,7 @@ import java.io.UnsupportedEncodingException; import java.net.MalformedURLException; import java.net.URL; +import java.net.URLClassLoader; import java.net.URLEncoder; import java.net.URLStreamHandler; import java.net.URLStreamHandlerFactory; @@ -15,15 +17,17 @@ import java.security.ProtectionDomain; import java.security.cert.Certificate; import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedList; import java.util.Map; import java.util.Queue; +import java.util.Set; import java.util.jar.JarEntry; import java.util.jar.JarInputStream; import java.util.jar.Manifest; import java.util.jar.Attributes.Name; -public class Loader extends ClassLoader { +public class Loader extends URLClassLoader { private static String CONTEXT_PATH; private static Map classes = new HashMap(); @@ -41,7 +45,7 @@ public class Loader extends ClassLoader { private static URL context; private static URLStreamHandler handler; - public static Class initialize(JarInputStream[] jars, URLStreamHandlerFactory factory, String utilities, String mainClassName, int consoleCodePage) throws MalformedURLException, ClassNotFoundException { + public static Class initialize(JarInputStream[] jars, URLStreamHandlerFactory factory, String utilities, String classPath, String mainClassName, int consoleCodePage) throws MalformedURLException, ClassNotFoundException { URL.setURLStreamHandlerFactory(factory); handler = factory.createURLStreamHandler("exewrap"); context = new URL("exewrap:" + CONTEXT_PATH + "!/"); @@ -69,7 +73,7 @@ public static Class initialize(JarInputStream[] jars, URLStreamHandlerFactory jar = inputs.poll(); ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); - + if(utilities != null) { if(System.getProperty("exewrap.console.encoding") == null) { @@ -102,7 +106,31 @@ public static Class initialize(JarInputStream[] jars, URLStreamHandlerFactory Class.forName("exewrap.util.EventLogHandler", true, systemClassLoader); } } - + + if(systemClassLoader instanceof Loader) { + Loader loader = (Loader)systemClassLoader; + + try { + // JgfBNgCLASS_PATHɒlj܂B + classPath = new File(".").getCanonicalPath() + ";" + classPath; + } catch(Exception ignore) {} + + Set paths = new HashSet(); + for(String path : classPath.split(";")) { + try { + if(path.length() > 0) { + File file = new File(path).getCanonicalFile(); + String s = file.toString().toLowerCase(); + if(!paths.contains(s)) { + URL url = file.toURI().toURL(); + loader.addURL(url); + paths.add(s); + } + } + } catch(Exception ignore) {} + } + } + if(mainClassName != null) { return Class.forName(mainClassName, true, systemClassLoader); } else { @@ -114,7 +142,7 @@ public static Class initialize(JarInputStream[] jars, URLStreamHandlerFactory private ProtectionDomain protectionDomain; public Loader(ClassLoader parent) throws MalformedURLException { - super(parent); + super(new URL[0], parent); String path = System.getProperty("java.application.path"); if(path == null) { @@ -140,6 +168,11 @@ public Loader(ClassLoader parent) throws MalformedURLException { } protected Class findClass(String name) throws ClassNotFoundException { + // OCuiJARjNXT܂B‚ȂEXE\[XNXT܂B + try { + return super.findClass(name); + } catch(ClassNotFoundException ignore) {} + String entryName = name.replace('.', '/').concat(".class"); byte[] bytes = classes.remove(entryName); if(bytes == null) { @@ -169,7 +202,13 @@ protected Class findClass(String name) throws ClassNotFoundException { return defineClass(name, bytes, 0, bytes.length, protectionDomain); } - protected URL findResource(String name) { + public URL findResource(String name) { + // OCuiJARj烊\[XT܂B‚ȂEXE\[X烊\[XT܂B + URL url = super.findResource(name); + if(url != null) { + return url; + } + byte[] bytes = resources.get(name); if(bytes == null) { try { diff --git a/src/jvm.c b/src/jvm.c index 52fa72f..aaafa94 100644 --- a/src/jvm.c +++ b/src/jvm.c @@ -17,6 +17,7 @@ jint destroy_java_vm(void); JNIEnv* attach_java_vm(void); jint detach_java_vm(void); BOOL set_application_properties(SYSTEMTIME* startup); +wchar_t* get_class_path(void); void get_java_runtime_version(const wchar_t* version_string, DWORD* major, DWORD* minor, DWORD* build, DWORD* revision); wchar_t* get_java_version_string(DWORD major, DWORD minor, DWORD build, DWORD revision); wchar_t* get_module_version(wchar_t* buf, size_t size); @@ -149,12 +150,12 @@ JNIEnv* create_java_vm(const wchar_t* vm_args_opt, BOOL use_server_vm, BOOL use_ goto EXIT; } - if(classpath != NULL) + if(GetModuleFileName(NULL, wchar_buf, BUFFER_SIZE) != 0) { char* str; size_t len; - str = to_platform_encoding(classpath); + str = to_platform_encoding(wchar_buf); strcpy_s(char_buf, BUFFER_SIZE * 2, "-Djava.class.path="); strcat_s(char_buf, BUFFER_SIZE * 2, str); free(str); @@ -836,6 +837,12 @@ BOOL set_application_properties(SYSTEMTIME* startup) } +wchar_t* get_classpath() +{ + return classpath; +} + + BOOL initialize_path(const wchar_t* relative_classpath, const wchar_t* relative_extdirs, BOOL use_server_vm, BOOL use_side_by_side_jre) { wchar_t* module_path = NULL; @@ -1360,8 +1367,7 @@ BOOL initialize_path(const wchar_t* relative_classpath, const wchar_t* relative_ GetModuleFileName(NULL, buffer, BUFFER_SIZE); - wcscpy_s(classpath, BUFFER_SIZE, buffer); - wcscat_s(classpath, BUFFER_SIZE, L";"); + wcscpy_s(classpath, BUFFER_SIZE, L""); wcscpy_s(libpath, BUFFER_SIZE, L".;"); wcscat_s(libpath, BUFFER_SIZE, jvmpath); @@ -1390,7 +1396,6 @@ BOOL initialize_path(const wchar_t* relative_classpath, const wchar_t* relative_ p = NULL; } } - wcscat_s(classpath, BUFFER_SIZE, L"."); if(relative_extdirs != NULL) { diff --git a/src/loader.c b/src/loader.c index 04a0e24..959a988 100644 --- a/src/loader.c +++ b/src/loader.c @@ -179,11 +179,11 @@ BOOL load_main_class(int argc, const wchar_t* argv[], const wchar_t* utilities, swprintf_s(result->msg, LOAD_RESULT_MAX_MESSAGE_LENGTH, _(MSG_ID_ERR_GET_FIELD), L"Loader.resources"); goto EXIT; } - Loader_initialize = (*env)->GetStaticMethodID(env, Loader, "initialize", "([Ljava/util/jar/JarInputStream;Ljava/net/URLStreamHandlerFactory;Ljava/lang/String;Ljava/lang/String;I)Ljava/lang/Class;"); + Loader_initialize = (*env)->GetStaticMethodID(env, Loader, "initialize", "([Ljava/util/jar/JarInputStream;Ljava/net/URLStreamHandlerFactory;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)Ljava/lang/Class;"); if(Loader_initialize == NULL) { result->msg_id = MSG_ID_ERR_GET_METHOD; - swprintf_s(result->msg, LOAD_RESULT_MAX_MESSAGE_LENGTH, _(MSG_ID_ERR_GET_METHOD), L"Loader.initialize(java.util.jar.JarInputStream[], java.net.URLStreamHandlerFactory, java.lang.String, java.lang.String, int)"); + swprintf_s(result->msg, LOAD_RESULT_MAX_MESSAGE_LENGTH, _(MSG_ID_ERR_GET_METHOD), L"Loader.initialize(java.util.jar.JarInputStream[], java.net.URLStreamHandlerFactory, java.lang.String, java.lang.String, java.lang.String, int)"); goto EXIT; } @@ -400,11 +400,11 @@ BOOL load_main_class(int argc, const wchar_t* argv[], const wchar_t* utilities, } (*env)->SetObjectArrayElement(env, jars, 1, jarInputStream); } - + // call Loader.initialize main_class = from_utf8((char*)get_resource(L"MAIN_CLASS", NULL)); // MAIN_CLASS͒`ĂȂꍇ main_class = NULL ̂܂܏i߂܂B console_code_page = GetConsoleOutputCP(); - MainClass = (*env)->CallStaticObjectMethod(env, Loader, Loader_initialize, jars, urlStreamHandlerFactory, to_jstring(env, utilities), to_jstring(env, main_class), console_code_page); + MainClass = (*env)->CallStaticObjectMethod(env, Loader, Loader_initialize, jars, urlStreamHandlerFactory, to_jstring(env, utilities), to_jstring(env, get_classpath()), to_jstring(env, main_class), console_code_page); if(MainClass == NULL) { result->msg_id = MSG_ID_ERR_LOAD_MAIN_CLASS; diff --git a/src/resources/exewrap.rc b/src/resources/exewrap.rc index a7037e8..91a0299 100644 --- a/src/resources/exewrap.rc +++ b/src/resources/exewrap.rc @@ -3,7 +3,7 @@ LANGUAGE 0,0 VS_VERSION_INFO VERSIONINFO -FILEVERSION 1,6,1,0 +FILEVERSION 1,6,2,0 FILEFLAGSMASK VS_FFI_FILEFLAGSMASK FILEFLAGS VS_FF_PRERELEASE FILEOS VOS_NT_WINDOWS32 @@ -16,7 +16,7 @@ FILETYPE VFT_APP VALUE "FileDescription", "Native executable java application wrapper.\0" VALUE "LegalCopyright", "(C) 2005-2020 HIRUKAWA Ryo\0" VALUE "ProductName", "exewrap\0" - VALUE "ProductVersion", "1.6.1\0" + VALUE "ProductVersion", "1.6.2\0" VALUE "OriginalFilename", "exewrap.exe\0" } }