8346377: Properly support static builds for Windows

Reviewed-by: erikj
This commit is contained in:
Magnus Ihse Bursie 2025-01-13 12:25:10 +00:00
parent 06126361db
commit c885e59cfa
5 changed files with 55 additions and 21 deletions

View File

@ -67,10 +67,8 @@ else ifeq ($(call isTargetOs, windows), true)
BROKEN_STATIC_LIBS += splashscreen
# libsspi_bridge has name conflicts with sunmscapi
BROKEN_STATIC_LIBS += sspi_bridge
# These libs define DllMain which conflict with Hotspot
BROKEN_STATIC_LIBS += awt dt_shmem dt_socket
# These libs are dependent on any of the above disabled libs
BROKEN_STATIC_LIBS += fontmanager jawt lcms net nio
# dt_shmem define jdwpTransport_OnLoad which conflict with dt_socket
BROKEN_STATIC_LIBS += dt_shmem
endif
$(foreach module, $(STATIC_LIB_MODULES), \

View File

@ -197,8 +197,8 @@ AC_DEFUN([FLAGS_SETUP_LDFLAGS_CPU_DEP],
$2LDFLAGS_JDKEXE="$LDFLAGS_JDK_COMMON $EXECUTABLE_LDFLAGS \
${$1_CPU_EXECUTABLE_LDFLAGS} $REPRODUCIBLE_LDFLAGS $FILE_MACRO_LDFLAGS"
$2LDFLAGS_STATIC_JDK="$BASIC_LDFLAGS $BASIC_LDFLAGS_JVM_ONLY \
$OS_LDFLAGS ${$2EXTRA_LDFLAGS} $REPRODUCIBLE_LDFLAGS $FILE_MACRO_LDFLAGS"
$2LDFLAGS_STATIC_JDK="$BASIC_LDFLAGS $OS_LDFLAGS ${$2EXTRA_LDFLAGS} \
$REPRODUCIBLE_LDFLAGS $FILE_MACRO_LDFLAGS"
$2JVM_LDFLAGS="$BASIC_LDFLAGS $BASIC_LDFLAGS_JVM_ONLY $OS_LDFLAGS $OS_LDFLAGS_JVM_ONLY \
$DEBUGLEVEL_LDFLAGS $DEBUGLEVEL_LDFLAGS_JVM_ONLY \

View File

@ -285,6 +285,8 @@ void os::run_periodic_checks(outputStream* st) {
static LONG WINAPI Uncaught_Exception_Handler(struct _EXCEPTION_POINTERS* exceptionInfo);
#define JVM_LIB_NAME "jvm.dll"
void os::init_system_properties_values() {
// sysclasspath, java_home, dll_dir
{
@ -300,15 +302,27 @@ void os::init_system_properties_values() {
home_dir[MAX_PATH] = '\0';
} else {
os::jvm_path(home_dir, sizeof(home_dir));
// Found the full path to jvm.dll.
// Now cut the path to <java_home>/jre if we can.
*(strrchr(home_dir, '\\')) = '\0'; // get rid of \jvm.dll
// Found the full path to the binary. It is normally of this structure:
// <jdk_path>/bin/<hotspot_variant>/jvm.dll
// but can also be like this for a statically linked binary:
// <jdk_path>/bin/<executable>.exe
pslash = strrchr(home_dir, '\\');
if (pslash != nullptr) {
*pslash = '\0'; // get rid of \{client|server}
if (strncmp(pslash + 1, JVM_LIB_NAME, strlen(JVM_LIB_NAME)) == 0) {
// Binary name is jvm.dll. Get rid of \jvm.dll.
*pslash = '\0';
}
// Get rid of \hotspot_variant>, if binary is jvm.dll,
// or cut off \<executable>, if it is a statically linked binary.
pslash = strrchr(home_dir, '\\');
if (pslash != nullptr) {
*pslash = '\0'; // get rid of \bin
*pslash = '\0';
// Get rid of \bin
pslash = strrchr(home_dir, '\\');
if (pslash != nullptr) {
*pslash = '\0';
}
}
}
}
@ -1402,9 +1416,7 @@ void* os::dll_lookup(void *lib, const char *name) {
}
void* os::lookup_function(const char* name) {
// This is needed only for static builds which are not supported on Windows
ShouldNotReachHere();
return nullptr; // Satisfy compiler
return ::GetProcAddress(nullptr, name);
}
// Directory routines copied from src/win32/native/java/io/dirent_md.c

View File

@ -155,6 +155,12 @@ CreateExecutionEnvironment(int *pargc, char ***pargv,
char *jdkroot, jint so_jdkroot,
char *jvmpath, jint so_jvmpath,
char *jvmcfg, jint so_jvmcfg) {
if (JLI_IsStaticallyLinked()) {
// With static builds, all JDK and VM natives are statically linked
// with the launcher executable. The 'jrepath', 'jvmpath' and
// 'jvmcfg' are not used by the caller for static builds. Simply return.
return;
}
char *jvmtype;
int i = 0;
@ -222,6 +228,12 @@ LoadMSVCRT()
char crtpath[MAXPATHLEN];
if (!loaded) {
if (JLI_IsStaticallyLinked()) {
// For statically linked builds, we rely on the system msvcrt dlls
loaded = 1;
return JNI_TRUE;
}
/*
* The Microsoft C Runtime Library needs to be loaded first. A copy is
* assumed to be present in the "bin" directory of the JDK installation root.
@ -365,10 +377,14 @@ LoadJavaVM(const char *jvmpath, InvocationFunctions *ifn)
*/
LoadMSVCRT();
/* Load the Java VM DLL */
if ((handle = LoadLibrary(jvmpath)) == 0) {
JLI_ReportErrorMessage(DLL_ERROR4, (char *)jvmpath);
return JNI_FALSE;
if (JLI_IsStaticallyLinked()) {
handle = GetModuleHandle(NULL);
} else {
/* Load the Java VM DLL */
if ((handle = LoadLibrary(jvmpath)) == 0) {
JLI_ReportErrorMessage(DLL_ERROR4, (char *)jvmpath);
return JNI_FALSE;
}
}
/* Now get the function addresses */
@ -781,7 +797,11 @@ jclass FindBootStrapClass(JNIEnv *env, const char *classname)
HMODULE hJvm;
if (findBootClass == NULL) {
hJvm = GetModuleHandle(JVM_DLL);
if (JLI_IsStaticallyLinked()) {
hJvm = GetModuleHandle(NULL);
} else {
hJvm = GetModuleHandle(JVM_DLL);
}
if (hJvm == NULL) return NULL;
/* need to use the demangled entry point */
findBootClass = (FindClassFromBootLoader_t *)GetProcAddress(hJvm,

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -49,7 +49,11 @@ extern "C"
* Here we just need to get handle to initialize the pointers to
* required mlib routines.
*/
hDLL = ::GetModuleHandle(TEXT("mlib_image.dll"));
if (JVM_IsStaticallyLinked()) {
hDLL = ::GetModuleHandle(NULL);
} else {
hDLL = ::GetModuleHandle(TEXT("mlib_image.dll"));
}
if (hDLL == NULL) {
return MLIB_FAILURE;