Merge
This commit is contained in:
commit
059329b346
make
src
hotspot
cpu/aarch64
share
classfile
gc
shenandoah
shenandoahConcurrentMark.cppshenandoahControlThread.cppshenandoahHeap.cppshenandoahMarkCompact.cppshenandoahPhaseTimings.cppshenandoahPhaseTimings.hppshenandoahUtils.cpp
z
jvmci
oops
constantPool.cppconstantPool.hppinstanceClassLoaderKlass.hppinstanceKlass.cppinstanceKlass.hppinstanceMirrorKlass.hppinstanceRefKlass.hppklass.hppmethod.cpp
prims
runtime
utilities
java.base/share/classes/sun/security/ssl
jdk.compiler/share/classes/com/sun/tools/javac/parser
jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops
jdk.incubator.jpackage
linux
classes/jdk/incubator/jpackage/internal
native
applauncher
common
jpackageapplauncher
libapplauncher
macosx
classes/jdk/incubator/jpackage/internal
native
applauncher
common
jpackageapplauncher
libapplauncher
share
classes/jdk/incubator/jpackage/internal
native
unix/native
common
libapplauncher
windows
classes/jdk/incubator/jpackage/internal
native
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2011, 2020, 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
|
||||
@ -79,7 +79,7 @@ AC_DEFUN([LIB_CHECK_POTENTIAL_FREETYPE],
|
||||
AC_DEFUN_ONCE([LIB_SETUP_FREETYPE],
|
||||
[
|
||||
AC_ARG_WITH(freetype, [AS_HELP_STRING([--with-freetype],
|
||||
[specify whether to use 'system' or 'bundled' freetype. Other values are errors.
|
||||
[specify whether to use 'system' or 'bundled' freetype.
|
||||
The selected option applies to both build time and run time.
|
||||
The default behaviour can be platform dependent.
|
||||
If using 'system' and either the include files or libraries cannot be
|
||||
@ -90,76 +90,90 @@ AC_DEFUN_ONCE([LIB_SETUP_FREETYPE],
|
||||
AC_ARG_WITH(freetype-lib, [AS_HELP_STRING([--with-freetype-lib],
|
||||
[specify directory for the freetype library])])
|
||||
|
||||
# This setup is to verify access to system installed freetype header and libraries.
|
||||
# On Windows and MacOS this does not apply and using these options will report an error.
|
||||
# On other platforms (Linux, Solaris), they will default to using
|
||||
# the system libraries. If they are found automatically, nothing need be done.
|
||||
# If they are not found, the configure "--with-freetype-*" options may be used to fix that.
|
||||
# If the preference is to bundle on these platforms then use --with-freetype=bundled
|
||||
# This setup is to verify access to system installed freetype header and
|
||||
# libraries. On Windows and MacOS this does not apply and using these options
|
||||
# will report an error. On other platforms (Linux, Solaris), they will
|
||||
# default to using the system libraries. If they are found automatically,
|
||||
# nothing need be done. If they are not found, the configure
|
||||
# "--with-freetype-*" options may be used to fix that. If the preference is
|
||||
# to bundle on these platforms then use --with-freetype=bundled.
|
||||
|
||||
FREETYPE_BASE_NAME=freetype
|
||||
FREETYPE_CFLAGS=
|
||||
FREETYPE_LIBS=
|
||||
|
||||
if (test "x$with_freetype_include" = "x" && test "x$with_freetype_lib" != "x") || \
|
||||
(test "x$with_freetype_include" != "x" && test "x$with_freetype_lib" = "x"); then
|
||||
AC_MSG_ERROR(['must specify both or neither of --with-freetype-include and --with-freetype-lib])
|
||||
if (test "x$with_freetype_include" = "x" && test "x$with_freetype_lib" != "x") || \
|
||||
(test "x$with_freetype_include" != "x" && test "x$with_freetype_lib" = "x"); then
|
||||
AC_MSG_ERROR([Must specify both or neither of --with-freetype-include and --with-freetype-lib])
|
||||
fi
|
||||
|
||||
FREETYPE_TO_USE=bundled
|
||||
if (test "x$OPENJDK_TARGET_OS" != "xwindows" && test "x$OPENJDK_TARGET_OS" != "xmacosx" \
|
||||
&& test "x$OPENJDK_TARGET_OS" != "xaix"); then
|
||||
if test "x$OPENJDK_TARGET_OS" != "xwindows" && \
|
||||
test "x$OPENJDK_TARGET_OS" != "xmacosx" && \
|
||||
test "x$OPENJDK_TARGET_OS" != "xaix"; then
|
||||
FREETYPE_TO_USE=system
|
||||
fi
|
||||
if (test "x$with_freetype" != "x"); then
|
||||
if (test "x$with_freetype" = "xsystem"); then
|
||||
if test "x$with_freetype" != "x" ; then
|
||||
if test "x$with_freetype" = "xsystem" ; then
|
||||
FREETYPE_TO_USE=system
|
||||
elif (test "x$with_freetype" = "xbundled"); then
|
||||
elif test "x$with_freetype" = "xbundled" ; then
|
||||
FREETYPE_TO_USE=bundled
|
||||
if (test "x$with_freetype_include" != "x" || test "x$with_freetype_lib" != "x"); then
|
||||
if test "x$with_freetype_include" != "x" || \
|
||||
test "x$with_freetype_lib" != "x" ; then
|
||||
AC_MSG_ERROR(['bundled' cannot be specified with --with-freetype-include and --with-freetype-lib])
|
||||
fi
|
||||
else
|
||||
AC_MSG_ERROR(['valid values for --with-freetype are 'system' and 'bundled'])
|
||||
AC_MSG_ERROR([Valid values for --with-freetype are 'system' and 'bundled'])
|
||||
fi
|
||||
fi
|
||||
|
||||
if (test "x$with_freetype_include" != "x" && test "x$with_freetype_lib" != "x"); then
|
||||
FREETYPE_TO_USE=system
|
||||
if test "x$with_freetype_include" != "x" && \
|
||||
test "x$with_freetype_lib" != "x" ; then
|
||||
FREETYPE_TO_USE=system
|
||||
fi
|
||||
|
||||
if (test "x$FREETYPE_TO_USE" = "xsystem") && \
|
||||
(test "x$OPENJDK_TARGET_OS" = "xwindows" || test "x$OPENJDK_TARGET_OS" = "xmacosx"); then
|
||||
AC_MSG_ERROR([Only bundled freetype can be specified on Mac and Windows])
|
||||
if test "x$FREETYPE_TO_USE" = "xsystem" && \
|
||||
(test "x$OPENJDK_TARGET_OS" = "xwindows" || \
|
||||
test "x$OPENJDK_TARGET_OS" = "xmacosx"); then
|
||||
AC_MSG_ERROR([Only bundled freetype can be specified on Mac and Windows])
|
||||
fi
|
||||
|
||||
if (test "x$with_freetype_include" != "x"); then
|
||||
if test "x$with_freetype_include" != "x" ; then
|
||||
POTENTIAL_FREETYPE_INCLUDE_PATH="$with_freetype_include"
|
||||
fi
|
||||
if (test "x$with_freetype_lib" != "x"); then
|
||||
if test "x$with_freetype_lib" != "x" ; then
|
||||
POTENTIAL_FREETYPE_LIB_PATH="$with_freetype_lib"
|
||||
fi
|
||||
|
||||
if (test "x$FREETYPE_TO_USE" = "xsystem"); then
|
||||
if (test "x$POTENTIAL_FREETYPE_INCLUDE_PATH" != "x" && test "x$POTENTIAL_FREETYPE_LIB_PATH" != "x"); then
|
||||
if test "x$FREETYPE_TO_USE" = "xsystem" ; then
|
||||
if test "x$POTENTIAL_FREETYPE_INCLUDE_PATH" != "x" && \
|
||||
test "x$POTENTIAL_FREETYPE_LIB_PATH" != "x" ; then
|
||||
# Okay, we got it. Check that it works.
|
||||
LIB_CHECK_POTENTIAL_FREETYPE($POTENTIAL_FREETYPE_INCLUDE_PATH, $POTENTIAL_FREETYPE_LIB_PATH, [--with-freetype])
|
||||
if (test "x$FOUND_FREETYPE" != "xyes"); then
|
||||
LIB_CHECK_POTENTIAL_FREETYPE($POTENTIAL_FREETYPE_INCLUDE_PATH,
|
||||
$POTENTIAL_FREETYPE_LIB_PATH, [--with-freetype])
|
||||
if test "x$FOUND_FREETYPE" != "xyes" ; then
|
||||
AC_MSG_ERROR([Can not find or use freetype at location given by --with-freetype-lib|include])
|
||||
fi
|
||||
else
|
||||
# User did not specify a location, but asked for system freetype. Try to locate it.
|
||||
# User did not specify a location, but asked for system freetype.
|
||||
# Try to locate it.
|
||||
|
||||
# If we have a sysroot, assume that's where we are supposed to look and skip pkg-config.
|
||||
if (test "x$SYSROOT" = "x"); then
|
||||
if (test "x$FOUND_FREETYPE" != "xyes"); then
|
||||
# Check modules using pkg-config, but only if we have it (ugly output results otherwise)
|
||||
if (test "x$PKG_CONFIG" != "x"); then
|
||||
# If we have a sysroot, assume that's where we are supposed to look and
|
||||
# skip pkg-config.
|
||||
if test "x$SYSROOT" = "x" ; then
|
||||
if test "x$FOUND_FREETYPE" != "xyes" ; then
|
||||
# Check modules using pkg-config, but only if we have it (ugly output
|
||||
# results otherwise)
|
||||
if test "x$PKG_CONFIG" != "x" ; then
|
||||
PKG_CHECK_MODULES(FREETYPE, freetype2, [FOUND_FREETYPE=yes], [FOUND_FREETYPE=no])
|
||||
if (test "x$FOUND_FREETYPE" = "xyes"); then
|
||||
# On solaris, pkg_check adds -lz to freetype libs, which isn't necessary for us.
|
||||
if test "x$FOUND_FREETYPE" = "xyes" ; then
|
||||
# On solaris, pkg_check adds -lz to freetype libs, which isn't
|
||||
# necessary for us.
|
||||
FREETYPE_LIBS=`$ECHO $FREETYPE_LIBS | $SED 's/-lz//g'`
|
||||
# 64-bit libs for Solaris x86 are installed in the amd64 subdirectory, change lib to lib/amd64
|
||||
if (test "x$OPENJDK_TARGET_OS" = "xsolaris" && test "x$OPENJDK_TARGET_CPU" = "xx86_64"); then
|
||||
# 64-bit libs for Solaris x86 are installed in the amd64
|
||||
# subdirectory, change lib to lib/amd64
|
||||
if test "x$OPENJDK_TARGET_OS" = "xsolaris" && \
|
||||
test "x$OPENJDK_TARGET_CPU" = "xx86_64" ; then
|
||||
FREETYPE_LIBS=`$ECHO $FREETYPE_LIBS | $SED 's?/lib?/lib/amd64?g'`
|
||||
fi
|
||||
AC_MSG_CHECKING([for freetype])
|
||||
@ -169,59 +183,65 @@ AC_DEFUN_ONCE([LIB_SETUP_FREETYPE],
|
||||
fi
|
||||
fi
|
||||
|
||||
if (test "x$FOUND_FREETYPE" != "xyes"); then
|
||||
if test "x$FOUND_FREETYPE" != "xyes" ; then
|
||||
# Check in well-known locations
|
||||
FREETYPE_BASE_DIR="$SYSROOT/usr"
|
||||
LIB_CHECK_POTENTIAL_FREETYPE([$FREETYPE_BASE_DIR/include], [$FREETYPE_BASE_DIR/lib], [well-known location])
|
||||
|
||||
if (test "x$FOUND_FREETYPE" != "xyes"); then
|
||||
FREETYPE_BASE_DIR="$SYSROOT/usr/X11"
|
||||
LIB_CHECK_POTENTIAL_FREETYPE([$FREETYPE_BASE_DIR/include], [$FREETYPE_BASE_DIR/lib], [well-known location])
|
||||
fi
|
||||
if (test "x$FOUND_FREETYPE" != "xyes"); then
|
||||
FREETYPE_BASE_DIR="$SYSROOT/usr/local"
|
||||
LIB_CHECK_POTENTIAL_FREETYPE([$FREETYPE_BASE_DIR/include], [$FREETYPE_BASE_DIR/lib], [well-known location])
|
||||
fi
|
||||
|
||||
if (test "x$FOUND_FREETYPE" != "xyes"); then
|
||||
FREETYPE_BASE_DIR="$SYSROOT/usr"
|
||||
if (test "x$OPENJDK_TARGET_CPU_BITS" = "x64"); then
|
||||
LIB_CHECK_POTENTIAL_FREETYPE([$FREETYPE_BASE_DIR/include], [$FREETYPE_BASE_DIR/lib/$OPENJDK_TARGET_CPU-linux-gnu], [well-known location])
|
||||
if (test "x$FOUND_FREETYPE" != "xyes"); then
|
||||
LIB_CHECK_POTENTIAL_FREETYPE([$FREETYPE_BASE_DIR/include], [$FREETYPE_BASE_DIR/lib64], [well-known location])
|
||||
fi
|
||||
else
|
||||
LIB_CHECK_POTENTIAL_FREETYPE([$FREETYPE_BASE_DIR/include], [$FREETYPE_BASE_DIR/lib/i386-linux-gnu], [well-known location])
|
||||
if (test "x$FOUND_FREETYPE" != "xyes"); then
|
||||
LIB_CHECK_POTENTIAL_FREETYPE([$FREETYPE_BASE_DIR/include], [$FREETYPE_BASE_DIR/lib32], [well-known location])
|
||||
fi
|
||||
if test "x$OPENJDK_TARGET_CPU_BITS" = "x64" ; then
|
||||
LIB_CHECK_POTENTIAL_FREETYPE([$FREETYPE_BASE_DIR/include],
|
||||
[$FREETYPE_BASE_DIR/lib/$OPENJDK_TARGET_CPU-linux-gnu], [well-known location])
|
||||
if test "x$FOUND_FREETYPE" != "xyes" ; then
|
||||
LIB_CHECK_POTENTIAL_FREETYPE([$FREETYPE_BASE_DIR/include],
|
||||
[$FREETYPE_BASE_DIR/lib64], [well-known location])
|
||||
fi
|
||||
else
|
||||
LIB_CHECK_POTENTIAL_FREETYPE([$FREETYPE_BASE_DIR/include],
|
||||
[$FREETYPE_BASE_DIR/lib/i386-linux-gnu], [well-known location])
|
||||
if test "x$FOUND_FREETYPE" != "xyes" ; then
|
||||
LIB_CHECK_POTENTIAL_FREETYPE([$FREETYPE_BASE_DIR/include],
|
||||
[$FREETYPE_BASE_DIR/lib32], [well-known location])
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "x$FOUND_FREETYPE" != "xyes" ; then
|
||||
LIB_CHECK_POTENTIAL_FREETYPE([$FREETYPE_BASE_DIR/include],
|
||||
[$FREETYPE_BASE_DIR/lib], [well-known location])
|
||||
fi
|
||||
|
||||
if test "x$FOUND_FREETYPE" != "xyes" ; then
|
||||
FREETYPE_BASE_DIR="$SYSROOT/usr/X11"
|
||||
LIB_CHECK_POTENTIAL_FREETYPE([$FREETYPE_BASE_DIR/include],
|
||||
[$FREETYPE_BASE_DIR/lib], [well-known location])
|
||||
fi
|
||||
|
||||
if test "x$FOUND_FREETYPE" != "xyes" ; then
|
||||
FREETYPE_BASE_DIR="$SYSROOT/usr/local"
|
||||
LIB_CHECK_POTENTIAL_FREETYPE([$FREETYPE_BASE_DIR/include],
|
||||
[$FREETYPE_BASE_DIR/lib], [well-known location])
|
||||
fi
|
||||
fi # end check in well-known locations
|
||||
|
||||
if (test "x$FOUND_FREETYPE" != "xyes"); then
|
||||
if test "x$FOUND_FREETYPE" != "xyes" ; then
|
||||
HELP_MSG_MISSING_DEPENDENCY([freetype])
|
||||
AC_MSG_ERROR([Could not find freetype! $HELP_MSG ])
|
||||
fi
|
||||
fi # end user specified settings
|
||||
|
||||
# Set FREETYPE_CFLAGS, _LIBS and _LIB_PATH from include and lib dir.
|
||||
if (test "x$FREETYPE_CFLAGS" = "x"); then
|
||||
if (test -d $FREETYPE_INCLUDE_PATH/freetype2/freetype); then
|
||||
if test "x$FREETYPE_CFLAGS" = "x" ; then
|
||||
if test -d $FREETYPE_INCLUDE_PATH/freetype2/freetype ; then
|
||||
FREETYPE_CFLAGS="-I$FREETYPE_INCLUDE_PATH/freetype2 -I$FREETYPE_INCLUDE_PATH"
|
||||
else
|
||||
FREETYPE_CFLAGS="-I$FREETYPE_INCLUDE_PATH"
|
||||
fi
|
||||
fi
|
||||
|
||||
if (test "x$FREETYPE_LIBS" = "x"); then
|
||||
if test "x$FREETYPE_LIBS" = "x" ; then
|
||||
FREETYPE_LIBS="-L$FREETYPE_LIB_PATH -l$FREETYPE_BASE_NAME"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
AC_MSG_RESULT([Using freetype: $FREETYPE_TO_USE])
|
||||
|
||||
AC_MSG_RESULT([Using freetype: $FREETYPE_TO_USE])
|
||||
|
||||
AC_SUBST(FREETYPE_TO_USE)
|
||||
AC_SUBST(FREETYPE_CFLAGS)
|
||||
|
@ -86,7 +86,7 @@ DISABLED_WARNINGS_gcc := parentheses comment unknown-pragmas address \
|
||||
delete-non-virtual-dtor char-subscripts array-bounds int-in-bool-context \
|
||||
ignored-qualifiers missing-field-initializers implicit-fallthrough \
|
||||
empty-body strict-overflow sequence-point maybe-uninitialized \
|
||||
misleading-indentation cast-function-type invalid-offsetof
|
||||
misleading-indentation cast-function-type
|
||||
|
||||
ifeq ($(call check-jvm-feature, zero), true)
|
||||
DISABLED_WARNINGS_gcc += return-type switch clobbered
|
||||
@ -95,8 +95,7 @@ endif
|
||||
DISABLED_WARNINGS_clang := tautological-compare \
|
||||
undefined-var-template sometimes-uninitialized unknown-pragmas \
|
||||
delete-non-virtual-dtor missing-braces char-subscripts \
|
||||
ignored-qualifiers missing-field-initializers mismatched-tags \
|
||||
invalid-offsetof
|
||||
ignored-qualifiers missing-field-initializers mismatched-tags
|
||||
|
||||
DISABLED_WARNINGS_solstudio := labelnotused hidef w_novirtualdescr inlafteruse \
|
||||
unknownpragma doubunder w_enumnotused w_toomanyenumnotused \
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2018, 2020, 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
|
||||
@ -27,48 +27,43 @@ include LibCommon.gmk
|
||||
|
||||
################################################################################
|
||||
|
||||
# Output app launcher library in resources dir, and symbols in the object dir
|
||||
$(eval $(call SetupJdkLibrary, BUILD_LIB_APPLAUNCHER, \
|
||||
NAME := applauncher, \
|
||||
OUTPUT_DIR := $(JDK_OUTPUTDIR)/modules/$(MODULE)/jdk/incubator/jpackage/internal/resources, \
|
||||
SYMBOLS_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libapplauncher, \
|
||||
TOOLCHAIN := TOOLCHAIN_LINK_CXX, \
|
||||
OPTIMIZATION := LOW, \
|
||||
CFLAGS := $(CXXFLAGS_JDKLIB) $(X_CFLAGS), \
|
||||
CFLAGS_windows := -EHsc -DUNICODE -D_UNICODE, \
|
||||
LDFLAGS := $(LDFLAGS_JDKLIB) $(LDFLAGS_CXX_JDK) \
|
||||
$(call SET_SHARED_LIBRARY_ORIGIN), \
|
||||
LIBS := $(LIBCXX), \
|
||||
LIBS_windows := user32.lib shell32.lib advapi32.lib ole32.lib, \
|
||||
LIBS_linux := -ldl -lpthread, \
|
||||
LIBS_macosx := -ldl -framework Cocoa, \
|
||||
))
|
||||
|
||||
$(BUILD_LIB_APPLAUNCHER): $(call FindLib, java.base, java)
|
||||
|
||||
TARGETS += $(BUILD_LIB_APPLAUNCHER)
|
||||
|
||||
JPACKAGE_APPLAUNCHER_SRC := \
|
||||
$(TOPDIR)/src/jdk.incubator.jpackage/$(OPENJDK_TARGET_OS)/native/jpackageapplauncher
|
||||
$(call FindSrcDirsForComponent, jdk.incubator.jpackage, applauncher) \
|
||||
$(call FindSrcDirsForComponent, jdk.incubator.jpackage, common)
|
||||
|
||||
|
||||
ifeq ($(call isTargetOs, windows), true)
|
||||
JpackageWithStaticCrt = \
|
||||
$(filter-out -MD, $1) -MT
|
||||
else
|
||||
JpackageWithStaticCrt = \
|
||||
$1
|
||||
endif
|
||||
|
||||
|
||||
JPACKAGE_OUTPUT_DIR := $(JDK_OUTPUTDIR)/modules/$(MODULE)/jdk/incubator/jpackage/internal/resources
|
||||
JPACKAGE_CXXFLAGS_windows := -EHsc -DUNICODE -D_UNICODE
|
||||
|
||||
# Output app launcher executable in resources dir, and symbols in the object dir
|
||||
$(eval $(call SetupJdkExecutable, BUILD_JPACKAGE_APPLAUNCHEREXE, \
|
||||
NAME := jpackageapplauncher, \
|
||||
OUTPUT_DIR := $(JDK_OUTPUTDIR)/modules/$(MODULE)/jdk/incubator/jpackage/internal/resources, \
|
||||
OUTPUT_DIR := $(JPACKAGE_OUTPUT_DIR), \
|
||||
SYMBOLS_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/jpackageapplauncher, \
|
||||
SRC := $(JPACKAGE_APPLAUNCHER_SRC), \
|
||||
TOOLCHAIN := TOOLCHAIN_LINK_CXX, \
|
||||
OPTIMIZATION := LOW, \
|
||||
CFLAGS := $(CFLAGS_JDKEXE), \
|
||||
CXXFLAGS := $(CXXFLAGS_JDKEXE), \
|
||||
CFLAGS_windows := -EHsc -DLAUNCHERC -DUNICODE -D_UNICODE, \
|
||||
CXXFLAGS := $(call JpackageWithStaticCrt, $(CXXFLAGS_JDKEXE)) \
|
||||
$(addprefix -I, $(JPACKAGE_APPLAUNCHER_SRC)), \
|
||||
CXXFLAGS_windows := $(JPACKAGE_CXXFLAGS_windows), \
|
||||
LDFLAGS := $(LDFLAGS_JDKEXE), \
|
||||
LIBS_macosx := -framework Cocoa, \
|
||||
LIBS := $(LIBCXX), \
|
||||
LIBS_linux := -ldl, \
|
||||
LIBS_windows := user32.lib shell32.lib advapi32.lib, \
|
||||
))
|
||||
|
||||
$(BUILD_JPACKAGE_APPLAUNCHEREXE): $(call FindLib, java.base, java)
|
||||
|
||||
TARGETS += $(BUILD_JPACKAGE_APPLAUNCHEREXE)
|
||||
|
||||
################################################################################
|
||||
@ -78,12 +73,11 @@ ifeq ($(call isTargetOs, windows), true)
|
||||
$(eval $(call SetupJdkLibrary, BUILD_LIB_JPACKAGE, \
|
||||
NAME := jpackage, \
|
||||
OPTIMIZATION := LOW, \
|
||||
CFLAGS := $(CXXFLAGS_JDKLIB), \
|
||||
CFLAGS_windows := -EHsc -DUNICODE -D_UNICODE, \
|
||||
EXTRA_SRC := jdk.incubator.jpackage:common, \
|
||||
CXXFLAGS := $(CXXFLAGS_JDKLIB) $(JPACKAGE_CXXFLAGS_windows), \
|
||||
LDFLAGS := $(LDFLAGS_JDKLIB) $(LDFLAGS_CXX_JDK) \
|
||||
$(call SET_SHARED_LIBRARY_ORIGIN), \
|
||||
LIBS := $(LIBCXX), \
|
||||
LIBS_windows := user32.lib shell32.lib advapi32.lib ole32.lib, \
|
||||
))
|
||||
|
||||
TARGETS += $(BUILD_LIB_JPACKAGE)
|
||||
@ -92,11 +86,11 @@ ifeq ($(call isTargetOs, windows), true)
|
||||
# Output library in resources dir, and symbols in the object dir
|
||||
$(eval $(call SetupJdkLibrary, BUILD_LIB_WIXHELPER, \
|
||||
NAME := wixhelper, \
|
||||
OUTPUT_DIR := $(JDK_OUTPUTDIR)/modules/$(MODULE)/jdk/incubator/jpackage/internal/resources, \
|
||||
OUTPUT_DIR := $(JPACKAGE_OUTPUT_DIR), \
|
||||
SYMBOLS_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libwixhelper, \
|
||||
OPTIMIZATION := LOW, \
|
||||
CFLAGS := $(CXXFLAGS_JDKLIB), \
|
||||
CFLAGS_windows := -EHsc -DUNICODE -D_UNICODE -MT, \
|
||||
CXXFLAGS := $(call JpackageWithStaticCrt, $(CXXFLAGS_JDKLIB)) \
|
||||
$(JPACKAGE_CXXFLAGS_windows), \
|
||||
LDFLAGS := $(LDFLAGS_JDKLIB) $(LDFLAGS_CXX_JDK), \
|
||||
LIBS := $(LIBCXX), \
|
||||
LIBS_windows := msi.lib Shlwapi.lib User32.lib, \
|
||||
@ -104,17 +98,18 @@ ifeq ($(call isTargetOs, windows), true)
|
||||
|
||||
TARGETS += $(BUILD_LIB_WIXHELPER)
|
||||
|
||||
JPACKAGE_MSIWRAPPER_SRC := \
|
||||
$(call FindSrcDirsForComponent, jdk.incubator.jpackage, msiwrapper) \
|
||||
$(call FindSrcDirsForComponent, jdk.incubator.jpackage, common)
|
||||
|
||||
# Build exe installer wrapper for msi installer
|
||||
$(eval $(call SetupJdkExecutable, BUILD_JPACKAGE_MSIWRAPPER, \
|
||||
NAME := msiwrapper, \
|
||||
OUTPUT_DIR := $(JDK_OUTPUTDIR)/modules/$(MODULE)/jdk/incubator/jpackage/internal/resources, \
|
||||
OUTPUT_DIR := $(JPACKAGE_OUTPUT_DIR), \
|
||||
SYMBOLS_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/msiwrapper, \
|
||||
SRC := $(TOPDIR)/src/jdk.incubator.jpackage/$(OPENJDK_TARGET_OS)/native/msiwrapper, \
|
||||
EXTRA_FILES := $(addprefix $(TOPDIR)/src/jdk.incubator.jpackage/$(OPENJDK_TARGET_OS)/native/libjpackage/, \
|
||||
FileUtils.cpp Log.cpp WinSysInfo.cpp tstrings.cpp WinErrorHandling.cpp ErrorHandling.cpp), \
|
||||
CFLAGS := $(CXXFLAGS_JDKEXE) -MT \
|
||||
$(addprefix -I$(TOPDIR)/src/jdk.incubator.jpackage/$(OPENJDK_TARGET_OS)/native/, msiwrapper libjpackage), \
|
||||
CFLAGS_windows := -EHsc -DUNICODE -D_UNICODE, \
|
||||
SRC := $(JPACKAGE_MSIWRAPPER_SRC), \
|
||||
CXXFLAGS := $(call JpackageWithStaticCrt, $(CXXFLAGS_JDKEXE)) \
|
||||
$(addprefix -I, $(JPACKAGE_MSIWRAPPER_SRC)) $(JPACKAGE_CXXFLAGS_windows), \
|
||||
LDFLAGS := $(LDFLAGS_JDKEXE), \
|
||||
LIBS := $(LIBCXX), \
|
||||
))
|
||||
@ -123,18 +118,17 @@ ifeq ($(call isTargetOs, windows), true)
|
||||
|
||||
# Build non-console version of launcher
|
||||
$(eval $(call SetupJdkExecutable, BUILD_JPACKAGE_APPLAUNCHERWEXE, \
|
||||
NAME := jpackageapplauncherw, \
|
||||
OUTPUT_DIR := $(JDK_OUTPUTDIR)/modules/$(MODULE)/jdk/incubator/jpackage/internal/resources, \
|
||||
SYMBOLS_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/jpackageapplauncherw, \
|
||||
SRC := $(JPACKAGE_APPLAUNCHER_SRC), \
|
||||
TOOLCHAIN := TOOLCHAIN_LINK_CXX, \
|
||||
OPTIMIZATION := LOW, \
|
||||
CFLAGS := $(CXXFLAGS_JDKEXE), \
|
||||
CFLAGS_windows := -EHsc -DUNICODE -D_UNICODE, \
|
||||
LDFLAGS := $(LDFLAGS_JDKEXE), \
|
||||
LIBS := $(LIBCXX), \
|
||||
LIBS_windows := user32.lib shell32.lib advapi32.lib, \
|
||||
))
|
||||
NAME := jpackageapplauncherw, \
|
||||
OUTPUT_DIR := $(JPACKAGE_OUTPUT_DIR), \
|
||||
SYMBOLS_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/jpackageapplauncherw, \
|
||||
SRC := $(BUILD_JPACKAGE_APPLAUNCHEREXE_SRC), \
|
||||
TOOLCHAIN := $(BUILD_JPACKAGE_APPLAUNCHEREXE_TOOLCHAIN), \
|
||||
OPTIMIZATION := $(BUILD_JPACKAGE_APPLAUNCHEREXE_OPTIMIZATION), \
|
||||
CXXFLAGS := $(BUILD_JPACKAGE_APPLAUNCHEREXE_CXXFLAGS), \
|
||||
CXXFLAGS_windows := $(BUILD_JPACKAGE_APPLAUNCHEREXE_CXXFLAGS_windows) -DJP_LAUNCHERW, \
|
||||
LDFLAGS := $(BUILD_JPACKAGE_APPLAUNCHEREXE_LDFLAGS), \
|
||||
LIBS := $(BUILD_JPACKAGE_APPLAUNCHEREXE_LIBS), \
|
||||
))
|
||||
|
||||
TARGETS += $(BUILD_JPACKAGE_APPLAUNCHERWEXE)
|
||||
|
||||
|
@ -16619,6 +16619,35 @@ instruct vsub2D(vecX dst, vecX src1, vecX src2)
|
||||
|
||||
// --------------------------------- MUL --------------------------------------
|
||||
|
||||
instruct vmul8B(vecD dst, vecD src1, vecD src2)
|
||||
%{
|
||||
predicate(n->as_Vector()->length() == 4 ||
|
||||
n->as_Vector()->length() == 8);
|
||||
match(Set dst (MulVB src1 src2));
|
||||
ins_cost(INSN_COST);
|
||||
format %{ "mulv $dst,$src1,$src2\t# vector (8B)" %}
|
||||
ins_encode %{
|
||||
__ mulv(as_FloatRegister($dst$$reg), __ T8B,
|
||||
as_FloatRegister($src1$$reg),
|
||||
as_FloatRegister($src2$$reg));
|
||||
%}
|
||||
ins_pipe(vmul64);
|
||||
%}
|
||||
|
||||
instruct vmul16B(vecX dst, vecX src1, vecX src2)
|
||||
%{
|
||||
predicate(n->as_Vector()->length() == 16);
|
||||
match(Set dst (MulVB src1 src2));
|
||||
ins_cost(INSN_COST);
|
||||
format %{ "mulv $dst,$src1,$src2\t# vector (16B)" %}
|
||||
ins_encode %{
|
||||
__ mulv(as_FloatRegister($dst$$reg), __ T16B,
|
||||
as_FloatRegister($src1$$reg),
|
||||
as_FloatRegister($src2$$reg));
|
||||
%}
|
||||
ins_pipe(vmul128);
|
||||
%}
|
||||
|
||||
instruct vmul4S(vecD dst, vecD src1, vecD src2)
|
||||
%{
|
||||
predicate(n->as_Vector()->length() == 2 ||
|
||||
|
@ -170,12 +170,12 @@ OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_
|
||||
}
|
||||
|
||||
void RegisterSaver::restore_live_registers(MacroAssembler* masm, bool restore_vectors) {
|
||||
#if COMPILER2_OR_JVMCI
|
||||
__ pop_CPU_state(restore_vectors);
|
||||
__ leave();
|
||||
#else
|
||||
#if !COMPILER2_OR_JVMCI
|
||||
assert(!restore_vectors, "vectors are generated only by C2 and JVMCI");
|
||||
#endif
|
||||
__ pop_CPU_state(restore_vectors);
|
||||
__ leave();
|
||||
|
||||
}
|
||||
|
||||
void RegisterSaver::restore_result_registers(MacroAssembler* masm) {
|
||||
|
@ -58,9 +58,7 @@ ConstantPool* BytecodeConstantPool::create_constant_pool(TRAPS) const {
|
||||
_orig->copy_cp_to(1, _orig->length() - 1, cp_h, 1, CHECK_NULL);
|
||||
|
||||
// Preserve dynamic constant information from the original pool
|
||||
if (_orig->has_dynamic_constant()) {
|
||||
cp->set_has_dynamic_constant();
|
||||
}
|
||||
cp->copy_fields(_orig);
|
||||
|
||||
for (int i = 0; i < _entries.length(); ++i) {
|
||||
BytecodeCPEntry entry = _entries.at(i);
|
||||
|
@ -315,7 +315,7 @@ void ShenandoahConcurrentMark::mark_roots(ShenandoahPhaseTimings::Phase root_pha
|
||||
|
||||
void ShenandoahConcurrentMark::update_roots(ShenandoahPhaseTimings::Phase root_phase) {
|
||||
assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Must be at a safepoint");
|
||||
assert(root_phase == ShenandoahPhaseTimings::full_gc_roots ||
|
||||
assert(root_phase == ShenandoahPhaseTimings::full_gc_update_roots ||
|
||||
root_phase == ShenandoahPhaseTimings::degen_gc_update_roots,
|
||||
"Only for these phases");
|
||||
|
||||
@ -414,8 +414,6 @@ void ShenandoahConcurrentMark::mark_from_roots() {
|
||||
WorkGang* workers = _heap->workers();
|
||||
uint nworkers = workers->active_workers();
|
||||
|
||||
ShenandoahGCPhase conc_mark_phase(ShenandoahPhaseTimings::conc_mark);
|
||||
|
||||
if (_heap->process_references()) {
|
||||
ReferenceProcessor* rp = _heap->ref_processor();
|
||||
rp->set_active_mt_degree(nworkers);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2019, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2013, 2020, Red Hat, Inc. 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
|
||||
@ -242,6 +242,22 @@ void ShenandoahControlThread::run_service() {
|
||||
heuristics->clear_metaspace_oom();
|
||||
}
|
||||
|
||||
// Commit worker statistics to cycle data
|
||||
heap->phase_timings()->flush_par_workers_to_cycle();
|
||||
|
||||
// Print GC stats for current cycle
|
||||
{
|
||||
LogTarget(Info, gc, stats) lt;
|
||||
if (lt.is_enabled()) {
|
||||
ResourceMark rm;
|
||||
LogStream ls(lt);
|
||||
heap->phase_timings()->print_cycle_on(&ls);
|
||||
}
|
||||
}
|
||||
|
||||
// Commit statistics to globals
|
||||
heap->phase_timings()->flush_cycle_to_global();
|
||||
|
||||
// Print Metaspace change following GC (if logging is enabled).
|
||||
MetaspaceUtils::print_metaspace_change(meta_sizes);
|
||||
|
||||
@ -265,6 +281,7 @@ void ShenandoahControlThread::run_service() {
|
||||
current :
|
||||
current - (ShenandoahUncommitDelay / 1000.0);
|
||||
service_uncommit(shrink_before);
|
||||
heap->phase_timings()->flush_cycle_to_global();
|
||||
last_shrink_time = current;
|
||||
}
|
||||
|
||||
|
@ -1190,7 +1190,7 @@ void ShenandoahHeap::print_tracing_info() const {
|
||||
ResourceMark rm;
|
||||
LogStream ls(lt);
|
||||
|
||||
phase_timings()->print_on(&ls);
|
||||
phase_timings()->print_global_on(&ls);
|
||||
|
||||
ls.cr();
|
||||
ls.cr();
|
||||
@ -2198,20 +2198,14 @@ void ShenandoahHeap::stop() {
|
||||
|
||||
void ShenandoahHeap::stw_unload_classes(bool full_gc) {
|
||||
if (!unload_classes()) return;
|
||||
bool purged_class;
|
||||
|
||||
// Unload classes and purge SystemDictionary.
|
||||
{
|
||||
ShenandoahGCSubPhase phase(full_gc ?
|
||||
ShenandoahPhaseTimings::full_gc_purge_class_unload :
|
||||
ShenandoahPhaseTimings::purge_class_unload);
|
||||
purged_class = SystemDictionary::do_unloading(gc_timer());
|
||||
}
|
||||
bool purged_class = SystemDictionary::do_unloading(gc_timer());
|
||||
|
||||
{
|
||||
ShenandoahGCSubPhase phase(full_gc ?
|
||||
ShenandoahPhaseTimings::full_gc_purge_par :
|
||||
ShenandoahPhaseTimings::purge_par);
|
||||
ShenandoahIsAliveSelector is_alive;
|
||||
uint num_workers = _workers->active_workers();
|
||||
ShenandoahClassUnloadingTask unlink_task(is_alive.is_alive_closure(), num_workers, purged_class);
|
||||
@ -2239,8 +2233,8 @@ void ShenandoahHeap::stw_process_weak_roots(bool full_gc) {
|
||||
ShenandoahPhaseTimings::purge);
|
||||
uint num_workers = _workers->active_workers();
|
||||
ShenandoahPhaseTimings::Phase timing_phase = full_gc ?
|
||||
ShenandoahPhaseTimings::full_gc_purge_par :
|
||||
ShenandoahPhaseTimings::purge_par;
|
||||
ShenandoahPhaseTimings::full_gc_purge_weak_par :
|
||||
ShenandoahPhaseTimings::purge_weak_par;
|
||||
ShenandoahGCSubPhase phase(timing_phase);
|
||||
ShenandoahGCWorkerPhase worker_phase(timing_phase);
|
||||
|
||||
|
@ -88,7 +88,7 @@ void ShenandoahMarkCompact::do_it(GCCause::Cause gc_cause) {
|
||||
assert(Thread::current()->is_VM_thread(), "Do full GC only while world is stopped");
|
||||
|
||||
{
|
||||
ShenandoahGCPhase phase(ShenandoahPhaseTimings::full_gc_heapdumps);
|
||||
ShenandoahGCPhase phase(ShenandoahPhaseTimings::full_gc_heapdump_pre);
|
||||
heap->pre_full_gc_dump(_gc_timer);
|
||||
}
|
||||
|
||||
@ -204,7 +204,7 @@ void ShenandoahMarkCompact::do_it(GCCause::Cause gc_cause) {
|
||||
}
|
||||
|
||||
{
|
||||
ShenandoahGCPhase phase(ShenandoahPhaseTimings::full_gc_heapdumps);
|
||||
ShenandoahGCPhase phase(ShenandoahPhaseTimings::full_gc_heapdump_post);
|
||||
heap->post_full_gc_dump(_gc_timer);
|
||||
}
|
||||
}
|
||||
@ -242,8 +242,8 @@ void ShenandoahMarkCompact::phase1_mark_heap() {
|
||||
rp->setup_policy(true); // forcefully purge all soft references
|
||||
rp->set_active_mt_degree(heap->workers()->active_workers());
|
||||
|
||||
cm->update_roots(ShenandoahPhaseTimings::full_gc_roots);
|
||||
cm->mark_roots(ShenandoahPhaseTimings::full_gc_roots);
|
||||
cm->update_roots(ShenandoahPhaseTimings::full_gc_update_roots);
|
||||
cm->mark_roots(ShenandoahPhaseTimings::full_gc_scan_roots);
|
||||
cm->finish_mark_from_roots(/* full_gc = */ true);
|
||||
heap->mark_complete_marking_context();
|
||||
heap->parallel_cleaning(true /* full_gc */);
|
||||
@ -767,7 +767,7 @@ void ShenandoahMarkCompact::phase3_update_references() {
|
||||
#if COMPILER2_OR_JVMCI
|
||||
DerivedPointerTable::clear();
|
||||
#endif
|
||||
ShenandoahRootAdjuster rp(nworkers, ShenandoahPhaseTimings::full_gc_roots);
|
||||
ShenandoahRootAdjuster rp(nworkers, ShenandoahPhaseTimings::full_gc_adjust_roots);
|
||||
ShenandoahAdjustRootPointersTask task(&rp, _preserved_marks);
|
||||
workers->run_task(&task);
|
||||
#if COMPILER2_OR_JVMCI
|
||||
|
@ -30,8 +30,14 @@
|
||||
#include "gc/shenandoah/shenandoahHeap.hpp"
|
||||
#include "gc/shenandoah/shenandoahHeuristics.hpp"
|
||||
#include "gc/shenandoah/shenandoahUtils.hpp"
|
||||
#include "runtime/orderAccess.hpp"
|
||||
#include "utilities/ostream.hpp"
|
||||
|
||||
#define SHENANDOAH_PHASE_NAME_FORMAT "%-28s"
|
||||
#define SHENANDOAH_S_TIME_FORMAT "%8.3lf"
|
||||
#define SHENANDOAH_US_TIME_FORMAT "%8.0lf"
|
||||
#define SHENANDOAH_US_WORKER_TIME_FORMAT "%3.0lf"
|
||||
|
||||
#define GC_PHASE_DECLARE_NAME(type, title) \
|
||||
title,
|
||||
|
||||
@ -42,58 +48,155 @@ const char* ShenandoahPhaseTimings::_phase_names[] = {
|
||||
#undef GC_PHASE_DECLARE_NAME
|
||||
|
||||
ShenandoahPhaseTimings::ShenandoahPhaseTimings() {
|
||||
uint max_workers = MAX2(ConcGCThreads, ParallelGCThreads);
|
||||
assert(max_workers > 0, "Must have some GC threads");
|
||||
_max_workers = MAX2(ConcGCThreads, ParallelGCThreads);
|
||||
assert(_max_workers > 0, "Must have some GC threads");
|
||||
|
||||
#define GC_PAR_PHASE_DECLARE_WORKER_DATA(type, title) \
|
||||
_gc_par_phases[ShenandoahPhaseTimings::type] = new WorkerDataArray<double>(title, max_workers);
|
||||
// Root scanning phases
|
||||
SHENANDOAH_GC_PAR_PHASE_DO(,, GC_PAR_PHASE_DECLARE_WORKER_DATA)
|
||||
#undef GC_PAR_PHASE_DECLARE_WORKER_DATA
|
||||
// Initialize everything to sane defaults
|
||||
for (uint i = 0; i < _num_phases; i++) {
|
||||
#define SHENANDOAH_WORKER_DATA_NULL(type, title) \
|
||||
_worker_data[i] = NULL;
|
||||
SHENANDOAH_GC_PAR_PHASE_DO(,, SHENANDOAH_WORKER_DATA_NULL)
|
||||
#undef SHENANDOAH_WORKER_DATA_NULL
|
||||
_cycle_data[i] = 0;
|
||||
}
|
||||
|
||||
// Then punch in the worker-related data.
|
||||
// Every worker phase get a bunch of internal objects, except
|
||||
// the very first slot, which is "<total>" and is not populated.
|
||||
for (uint i = 0; i < _num_phases; i++) {
|
||||
if (is_worker_phase(Phase(i))) {
|
||||
int c = 0;
|
||||
#define SHENANDOAH_WORKER_DATA_INIT(type, title) \
|
||||
if (c++ != 0) _worker_data[i + c] = new ShenandoahWorkerData(title, _max_workers);
|
||||
SHENANDOAH_GC_PAR_PHASE_DO(,, SHENANDOAH_WORKER_DATA_INIT)
|
||||
#undef SHENANDOAH_WORKER_DATA_INIT
|
||||
}
|
||||
}
|
||||
|
||||
_policy = ShenandoahHeap::heap()->shenandoah_policy();
|
||||
assert(_policy != NULL, "Can not be NULL");
|
||||
|
||||
_current_worker_phase = _invalid_phase;
|
||||
}
|
||||
|
||||
ShenandoahPhaseTimings::Phase ShenandoahPhaseTimings::worker_par_phase(Phase phase, GCParPhases par_phase) {
|
||||
assert(is_worker_phase(phase), "Phase should accept worker phase times: %s", phase_name(phase));
|
||||
Phase p = Phase(phase + 1 + par_phase);
|
||||
assert(p >= 0 && p < _num_phases, "Out of bound for: %s", phase_name(phase));
|
||||
return p;
|
||||
}
|
||||
|
||||
ShenandoahWorkerData* ShenandoahPhaseTimings::worker_data(Phase phase, GCParPhases par_phase) {
|
||||
Phase p = worker_par_phase(phase, par_phase);
|
||||
ShenandoahWorkerData* wd = _worker_data[p];
|
||||
assert(wd != NULL, "Counter initialized: %s", phase_name(p));
|
||||
return wd;
|
||||
}
|
||||
|
||||
bool ShenandoahPhaseTimings::is_worker_phase(Phase phase) {
|
||||
assert(phase >= 0 && phase < _num_phases, "Out of bounds");
|
||||
switch (phase) {
|
||||
case init_evac:
|
||||
case scan_roots:
|
||||
case update_roots:
|
||||
case final_update_refs_roots:
|
||||
case full_gc_scan_roots:
|
||||
case full_gc_update_roots:
|
||||
case full_gc_adjust_roots:
|
||||
case degen_gc_update_roots:
|
||||
case full_gc_purge_class_unload:
|
||||
case full_gc_purge_weak_par:
|
||||
case purge_class_unload:
|
||||
case purge_weak_par:
|
||||
case heap_iteration_roots:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void ShenandoahPhaseTimings::set_cycle_data(Phase phase, double time) {
|
||||
#ifdef ASSERT
|
||||
double d = _cycle_data[phase];
|
||||
assert(d == 0, "Should not be set yet: %s, current value: %lf", phase_name(phase), d);
|
||||
#endif
|
||||
_cycle_data[phase] = time;
|
||||
}
|
||||
|
||||
void ShenandoahPhaseTimings::record_phase_time(Phase phase, double time) {
|
||||
if (!_policy->is_at_shutdown()) {
|
||||
_timing_data[phase].add(time);
|
||||
set_cycle_data(phase, time);
|
||||
}
|
||||
}
|
||||
|
||||
void ShenandoahPhaseTimings::record_workers_start(Phase phase) {
|
||||
for (uint i = 0; i < GCParPhasesSentinel; i++) {
|
||||
_gc_par_phases[i]->reset();
|
||||
assert(is_worker_phase(phase), "Phase should accept worker phase times: %s", phase_name(phase));
|
||||
|
||||
assert(_current_worker_phase == _invalid_phase, "Should not be set yet: requested %s, existing %s",
|
||||
phase_name(phase), phase_name(_current_worker_phase));
|
||||
_current_worker_phase = phase;
|
||||
|
||||
for (uint i = 1; i < GCParPhasesSentinel; i++) {
|
||||
worker_data(phase, GCParPhases(i))->reset();
|
||||
}
|
||||
}
|
||||
|
||||
void ShenandoahPhaseTimings::record_workers_end(Phase phase) {
|
||||
if (_policy->is_at_shutdown()) {
|
||||
// Do not record the past-shutdown events
|
||||
return;
|
||||
}
|
||||
|
||||
assert(phase == init_evac ||
|
||||
phase == scan_roots ||
|
||||
phase == update_roots ||
|
||||
phase == final_update_refs_roots ||
|
||||
phase == full_gc_roots ||
|
||||
phase == degen_gc_update_roots ||
|
||||
phase == full_gc_purge_par ||
|
||||
phase == purge_par ||
|
||||
phase == heap_iteration_roots,
|
||||
"Phase should accept accept per-thread phase times: %s", phase_name(phase));
|
||||
|
||||
double s = 0;
|
||||
for (uint i = 1; i < GCParPhasesSentinel; i++) {
|
||||
double t = _gc_par_phases[i]->sum();
|
||||
_timing_data[phase + i + 1].add(t); // add to each line in phase
|
||||
s += t;
|
||||
}
|
||||
_timing_data[phase + 1].add(s); // add to total for phase
|
||||
assert(is_worker_phase(phase), "Phase should accept worker phase times: %s", phase_name(phase));
|
||||
_current_worker_phase = _invalid_phase;
|
||||
}
|
||||
|
||||
void ShenandoahPhaseTimings::print_on(outputStream* out) const {
|
||||
void ShenandoahPhaseTimings::flush_par_workers_to_cycle() {
|
||||
for (uint pi = 0; pi < _num_phases; pi++) {
|
||||
Phase phase = Phase(pi);
|
||||
if (is_worker_phase(phase)) {
|
||||
double s = 0;
|
||||
for (uint i = 1; i < GCParPhasesSentinel; i++) {
|
||||
double t = worker_data(phase, GCParPhases(i))->sum();
|
||||
// add to each line in phase
|
||||
set_cycle_data(Phase(phase + i + 1), t);
|
||||
s += t;
|
||||
}
|
||||
// add to total for phase
|
||||
set_cycle_data(Phase(phase + 1), s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ShenandoahPhaseTimings::flush_cycle_to_global() {
|
||||
for (uint i = 0; i < _num_phases; i++) {
|
||||
_global_data[i].add(_cycle_data[i]);
|
||||
_cycle_data[i] = 0;
|
||||
}
|
||||
OrderAccess::fence();
|
||||
}
|
||||
|
||||
void ShenandoahPhaseTimings::print_cycle_on(outputStream* out) const {
|
||||
out->cr();
|
||||
out->print_cr("All times are wall-clock times, except per-root-class counters, that are sum over");
|
||||
out->print_cr("all workers. Dividing the <total> over the root stage time estimates parallelism.");
|
||||
out->cr();
|
||||
for (uint i = 0; i < _num_phases; i++) {
|
||||
double v = _cycle_data[i] * 1000000.0;
|
||||
if (v > 0) {
|
||||
out->print(SHENANDOAH_PHASE_NAME_FORMAT " " SHENANDOAH_US_TIME_FORMAT " us", _phase_names[i], v);
|
||||
if (_worker_data[i] != NULL) {
|
||||
out->print(", workers (us): ");
|
||||
for (size_t c = 0; c < _max_workers; c++) {
|
||||
double tv = _worker_data[i]->get(c);
|
||||
if (tv != ShenandoahWorkerData::uninitialized()) {
|
||||
out->print(SHENANDOAH_US_WORKER_TIME_FORMAT ", ", tv * 1000000.0);
|
||||
} else {
|
||||
out->print("%3s, ", "---");
|
||||
}
|
||||
}
|
||||
}
|
||||
out->cr();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ShenandoahPhaseTimings::print_global_on(outputStream* out) const {
|
||||
out->cr();
|
||||
out->print_cr("GC STATISTICS:");
|
||||
out->print_cr(" \"(G)\" (gross) pauses include VM time: time to notify and block threads, do the pre-");
|
||||
@ -107,37 +210,43 @@ void ShenandoahPhaseTimings::print_on(outputStream* out) const {
|
||||
out->cr();
|
||||
|
||||
for (uint i = 0; i < _num_phases; i++) {
|
||||
if (_timing_data[i].maximum() != 0) {
|
||||
out->print_cr("%-27s = %8.2lf s (a = %8.0lf us) (n = " INT32_FORMAT_W(5) ") (lvls, us = %8.0lf, %8.0lf, %8.0lf, %8.0lf, %8.0lf)",
|
||||
if (_global_data[i].maximum() != 0) {
|
||||
out->print_cr(SHENANDOAH_PHASE_NAME_FORMAT " = " SHENANDOAH_S_TIME_FORMAT " s "
|
||||
"(a = " SHENANDOAH_US_TIME_FORMAT " us) "
|
||||
"(n = " INT32_FORMAT_W(5) ") (lvls, us = "
|
||||
SHENANDOAH_US_TIME_FORMAT ", "
|
||||
SHENANDOAH_US_TIME_FORMAT ", "
|
||||
SHENANDOAH_US_TIME_FORMAT ", "
|
||||
SHENANDOAH_US_TIME_FORMAT ", "
|
||||
SHENANDOAH_US_TIME_FORMAT ")",
|
||||
_phase_names[i],
|
||||
_timing_data[i].sum(),
|
||||
_timing_data[i].avg() * 1000000.0,
|
||||
_timing_data[i].num(),
|
||||
_timing_data[i].percentile(0) * 1000000.0,
|
||||
_timing_data[i].percentile(25) * 1000000.0,
|
||||
_timing_data[i].percentile(50) * 1000000.0,
|
||||
_timing_data[i].percentile(75) * 1000000.0,
|
||||
_timing_data[i].maximum() * 1000000.0
|
||||
_global_data[i].sum(),
|
||||
_global_data[i].avg() * 1000000.0,
|
||||
_global_data[i].num(),
|
||||
_global_data[i].percentile(0) * 1000000.0,
|
||||
_global_data[i].percentile(25) * 1000000.0,
|
||||
_global_data[i].percentile(50) * 1000000.0,
|
||||
_global_data[i].percentile(75) * 1000000.0,
|
||||
_global_data[i].maximum() * 1000000.0
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ShenandoahPhaseTimings::record_worker_time(ShenandoahPhaseTimings::GCParPhases phase, uint worker_id, double secs) {
|
||||
_gc_par_phases[phase]->set(worker_id, secs);
|
||||
}
|
||||
|
||||
ShenandoahWorkerTimingsTracker::ShenandoahWorkerTimingsTracker(ShenandoahPhaseTimings::GCParPhases phase, uint worker_id) :
|
||||
_phase(phase), _timings(ShenandoahHeap::heap()->phase_timings()), _worker_id(worker_id) {
|
||||
ShenandoahWorkerTimingsTracker::ShenandoahWorkerTimingsTracker(ShenandoahPhaseTimings::GCParPhases par_phase, uint worker_id) :
|
||||
_timings(ShenandoahHeap::heap()->phase_timings()), _phase(_timings->current_worker_phase()),
|
||||
_par_phase(par_phase), _worker_id(worker_id) {
|
||||
assert(_timings->worker_data(_phase, _par_phase)->get(_worker_id) == ShenandoahWorkerData::uninitialized(),
|
||||
"Should not be set yet: %s", ShenandoahPhaseTimings::phase_name(_timings->worker_par_phase(_phase, _par_phase)));
|
||||
_start_time = os::elapsedTime();
|
||||
}
|
||||
|
||||
ShenandoahWorkerTimingsTracker::~ShenandoahWorkerTimingsTracker() {
|
||||
_timings->record_worker_time(_phase, _worker_id, os::elapsedTime() - _start_time);
|
||||
_timings->worker_data(_phase, _par_phase)->set(_worker_id, os::elapsedTime() - _start_time);
|
||||
|
||||
if (ShenandoahGCPhase::is_root_work_phase()) {
|
||||
ShenandoahPhaseTimings::Phase root_phase = ShenandoahGCPhase::current_phase();
|
||||
ShenandoahPhaseTimings::Phase cur_phase = (ShenandoahPhaseTimings::Phase)((int)root_phase + (int)_phase + 1);
|
||||
ShenandoahPhaseTimings::Phase cur_phase = _timings->worker_par_phase(root_phase, _par_phase);
|
||||
_event.commit(GCId::current(), _worker_id, ShenandoahPhaseTimings::phase_name(cur_phase));
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2019, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2017, 2020, Red Hat, Inc. 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
|
||||
@ -79,8 +79,9 @@ class outputStream;
|
||||
f(weakrefs_process, " Process") \
|
||||
f(purge, " System Purge") \
|
||||
f(purge_class_unload, " Unload Classes") \
|
||||
f(purge_par, " Parallel Cleanup") \
|
||||
SHENANDOAH_GC_PAR_PHASE_DO(purge_par_roots, " PC: ", f) \
|
||||
SHENANDOAH_GC_PAR_PHASE_DO(purge_cu_par_, " CU: ", f) \
|
||||
f(purge_weak_par, " Weak Roots") \
|
||||
SHENANDOAH_GC_PAR_PHASE_DO(purge_weak_par_, " WR: ", f) \
|
||||
f(purge_cldg, " CLDG") \
|
||||
f(final_update_region_states, " Update Region States") \
|
||||
f(retire_tlabs, " Retire TLABs") \
|
||||
@ -119,29 +120,35 @@ class outputStream;
|
||||
\
|
||||
f(full_gc_gross, "Pause Full GC (G)") \
|
||||
f(full_gc, "Pause Full GC (N)") \
|
||||
f(full_gc_heapdumps, " Heap Dumps") \
|
||||
f(full_gc_heapdump_pre, " Pre Heap Dump") \
|
||||
f(full_gc_prepare, " Prepare") \
|
||||
f(full_gc_roots, " Roots") \
|
||||
SHENANDOAH_GC_PAR_PHASE_DO(full_gc_, " F: ", f) \
|
||||
f(full_gc_scan_roots, " Scan Roots") \
|
||||
SHENANDOAH_GC_PAR_PHASE_DO(full_gc_scan_roots_, " FS: ", f) \
|
||||
f(full_gc_update_roots, " Update Roots") \
|
||||
SHENANDOAH_GC_PAR_PHASE_DO(full_gc_update_roots_, " FU: ", f) \
|
||||
f(full_gc_mark, " Mark") \
|
||||
f(full_gc_mark_finish_queues, " Finish Queues") \
|
||||
f(full_gc_weakrefs, " Weak References") \
|
||||
f(full_gc_weakrefs_process, " Process") \
|
||||
f(full_gc_purge, " System Purge") \
|
||||
f(full_gc_purge_class_unload, " Unload Classes") \
|
||||
f(full_gc_purge_par, " Parallel Cleanup") \
|
||||
SHENANDOAH_GC_PAR_PHASE_DO(full_gc_purge_roots, " PC: ", f) \
|
||||
f(full_gc_purge_cldg, " CLDG") \
|
||||
SHENANDOAH_GC_PAR_PHASE_DO(full_gc_purge_cu_par_, " CU: ", f) \
|
||||
f(full_gc_purge_weak_par, " Weak Roots") \
|
||||
SHENANDOAH_GC_PAR_PHASE_DO(full_gc_purge_weak_p_, " WR: ", f) \
|
||||
f(full_gc_purge_cldg, " CLDG") \
|
||||
f(full_gc_calculate_addresses, " Calculate Addresses") \
|
||||
f(full_gc_calculate_addresses_regular, " Regular Objects") \
|
||||
f(full_gc_calculate_addresses_humong, " Humongous Objects") \
|
||||
f(full_gc_adjust_pointers, " Adjust Pointers") \
|
||||
f(full_gc_adjust_roots, " Adjust Roots") \
|
||||
SHENANDOAH_GC_PAR_PHASE_DO(full_gc_adjust_roots_, " FA: ", f) \
|
||||
f(full_gc_copy_objects, " Copy Objects") \
|
||||
f(full_gc_copy_objects_regular, " Regular Objects") \
|
||||
f(full_gc_copy_objects_humong, " Humongous Objects") \
|
||||
f(full_gc_copy_objects_reset_complete, " Reset Complete Bitmap") \
|
||||
f(full_gc_copy_objects_rebuild, " Rebuild Region Sets") \
|
||||
f(full_gc_resize_tlabs, " Resize TLABs") \
|
||||
f(full_gc_heapdump_post, " Post Heap Dump") \
|
||||
\
|
||||
f(conc_uncommit, "Concurrent Uncommit") \
|
||||
\
|
||||
@ -149,7 +156,11 @@ class outputStream;
|
||||
SHENANDOAH_GC_PAR_PHASE_DO(heap_iteration_roots_, " HI: ", f) \
|
||||
// end
|
||||
|
||||
typedef WorkerDataArray<double> ShenandoahWorkerData;
|
||||
|
||||
class ShenandoahPhaseTimings : public CHeapObj<mtGC> {
|
||||
friend class ShenandoahGCPhase;
|
||||
friend class ShenandoahWorkerTimingsTracker;
|
||||
public:
|
||||
#define GC_PHASE_DECLARE_ENUM(type, title) type,
|
||||
|
||||
@ -167,39 +178,54 @@ public:
|
||||
#undef GC_PHASE_DECLARE_ENUM
|
||||
|
||||
private:
|
||||
HdrSeq _timing_data[_num_phases];
|
||||
size_t _max_workers;
|
||||
double _cycle_data[_num_phases];
|
||||
HdrSeq _global_data[_num_phases];
|
||||
static const char* _phase_names[_num_phases];
|
||||
|
||||
WorkerDataArray<double>* _gc_par_phases[ShenandoahPhaseTimings::GCParPhasesSentinel];
|
||||
Phase _current_worker_phase;
|
||||
ShenandoahWorkerData* _worker_data[_num_phases];
|
||||
ShenandoahCollectorPolicy* _policy;
|
||||
|
||||
static bool is_worker_phase(Phase phase);
|
||||
Phase current_worker_phase() { return _current_worker_phase; }
|
||||
|
||||
ShenandoahWorkerData* worker_data(Phase phase, GCParPhases par_phase);
|
||||
Phase worker_par_phase(Phase phase, GCParPhases par_phase);
|
||||
|
||||
void set_cycle_data(Phase phase, double time);
|
||||
|
||||
public:
|
||||
ShenandoahPhaseTimings();
|
||||
|
||||
void record_phase_time(Phase phase, double time);
|
||||
void record_worker_time(GCParPhases phase, uint worker_id, double time);
|
||||
|
||||
void record_workers_start(Phase phase);
|
||||
void record_workers_end(Phase phase);
|
||||
|
||||
void flush_par_workers_to_cycle();
|
||||
void flush_cycle_to_global();
|
||||
|
||||
static const char* phase_name(Phase phase) {
|
||||
assert(phase >= 0 && phase < _num_phases, "Out of bound");
|
||||
return _phase_names[phase];
|
||||
}
|
||||
|
||||
void print_on(outputStream* out) const;
|
||||
void print_cycle_on(outputStream* out) const;
|
||||
void print_global_on(outputStream* out) const;
|
||||
};
|
||||
|
||||
class ShenandoahWorkerTimingsTracker : public StackObj {
|
||||
private:
|
||||
ShenandoahPhaseTimings::GCParPhases const _phase;
|
||||
ShenandoahPhaseTimings* const _timings;
|
||||
ShenandoahPhaseTimings* const _timings;
|
||||
ShenandoahPhaseTimings::Phase const _phase;
|
||||
ShenandoahPhaseTimings::GCParPhases const _par_phase;
|
||||
uint const _worker_id;
|
||||
|
||||
double _start_time;
|
||||
EventGCPhaseParallel _event;
|
||||
public:
|
||||
ShenandoahWorkerTimingsTracker(ShenandoahPhaseTimings::GCParPhases phase, uint worker_id);
|
||||
ShenandoahWorkerTimingsTracker(ShenandoahPhaseTimings::GCParPhases par_phase, uint worker_id);
|
||||
~ShenandoahWorkerTimingsTracker();
|
||||
};
|
||||
|
||||
|
@ -132,7 +132,9 @@ bool ShenandoahGCPhase::is_root_work_phase() {
|
||||
case ShenandoahPhaseTimings::init_evac:
|
||||
case ShenandoahPhaseTimings::final_update_refs_roots:
|
||||
case ShenandoahPhaseTimings::degen_gc_update_roots:
|
||||
case ShenandoahPhaseTimings::full_gc_roots:
|
||||
case ShenandoahPhaseTimings::full_gc_scan_roots:
|
||||
case ShenandoahPhaseTimings::full_gc_update_roots:
|
||||
case ShenandoahPhaseTimings::full_gc_adjust_roots:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
|
@ -287,12 +287,14 @@ void ZPageAllocator::increase_used(size_t size, bool relocation) {
|
||||
}
|
||||
|
||||
void ZPageAllocator::decrease_used(size_t size, bool reclaimed) {
|
||||
// Only pages explicitly released with the reclaimed flag set
|
||||
// counts as reclaimed bytes. This flag is true when we release
|
||||
// a page after relocation, and is false when we release a page
|
||||
// to undo an allocation.
|
||||
if (reclaimed) {
|
||||
// Only pages explicitly released with the reclaimed flag set
|
||||
// counts as reclaimed bytes. This flag is typically true when
|
||||
// a worker releases a page after relocation, and is typically
|
||||
// false when we release a page to undo an allocation.
|
||||
_reclaimed += size;
|
||||
} else {
|
||||
_allocated -= size;
|
||||
}
|
||||
_used -= size;
|
||||
if (_used < _used_low) {
|
||||
|
@ -116,7 +116,8 @@
|
||||
nonstatic_field(ConstantPool, _tags, Array<u1>*) \
|
||||
nonstatic_field(ConstantPool, _pool_holder, InstanceKlass*) \
|
||||
nonstatic_field(ConstantPool, _length, int) \
|
||||
nonstatic_field(ConstantPool, _flags, int) \
|
||||
nonstatic_field(ConstantPool, _flags, u2) \
|
||||
nonstatic_field(ConstantPool, _source_file_name_index, u2) \
|
||||
\
|
||||
nonstatic_field(ConstMethod, _constants, ConstantPool*) \
|
||||
nonstatic_field(ConstMethod, _flags, u2) \
|
||||
@ -155,10 +156,9 @@
|
||||
\
|
||||
nonstatic_field(InstanceKlass, _fields, Array<u2>*) \
|
||||
nonstatic_field(InstanceKlass, _constants, ConstantPool*) \
|
||||
nonstatic_field(InstanceKlass, _source_file_name_index, u2) \
|
||||
nonstatic_field(InstanceKlass, _init_state, u1) \
|
||||
nonstatic_field(InstanceKlass, _init_thread, Thread*) \
|
||||
nonstatic_field(InstanceKlass, _misc_flags, u4) \
|
||||
nonstatic_field(InstanceKlass, _misc_flags, u2) \
|
||||
nonstatic_field(InstanceKlass, _annotations, Annotations*) \
|
||||
\
|
||||
volatile_nonstatic_field(JavaFrameAnchor, _last_Java_sp, intptr_t*) \
|
||||
|
@ -65,6 +65,20 @@ ConstantPool* ConstantPool::allocate(ClassLoaderData* loader_data, int length, T
|
||||
return new (loader_data, size, MetaspaceObj::ConstantPoolType, THREAD) ConstantPool(tags);
|
||||
}
|
||||
|
||||
void ConstantPool::copy_fields(const ConstantPool* orig) {
|
||||
// Preserve dynamic constant information from the original pool
|
||||
if (orig->has_dynamic_constant()) {
|
||||
set_has_dynamic_constant();
|
||||
}
|
||||
|
||||
// Copy class version
|
||||
set_major_version(orig->major_version());
|
||||
set_minor_version(orig->minor_version());
|
||||
|
||||
set_source_file_name_index(orig->source_file_name_index());
|
||||
set_generic_signature_index(orig->generic_signature_index());
|
||||
}
|
||||
|
||||
#ifdef ASSERT
|
||||
|
||||
// MetaspaceObj allocation invariant is calloc equivalent memory
|
||||
|
@ -110,6 +110,16 @@ class ConstantPool : public Metadata {
|
||||
// save space on 64-bit platforms.
|
||||
Array<Klass*>* _resolved_klasses;
|
||||
|
||||
u2 _major_version; // major version number of class file
|
||||
u2 _minor_version; // minor version number of class file
|
||||
|
||||
// Constant pool index to the utf8 entry of the Generic signature,
|
||||
// or 0 if none.
|
||||
u2 _generic_signature_index;
|
||||
// Constant pool index to the utf8 entry for the name of source file
|
||||
// containing this klass, 0 if not specified.
|
||||
u2 _source_file_name_index;
|
||||
|
||||
enum {
|
||||
_has_preresolution = 1, // Flags
|
||||
_on_stack = 2,
|
||||
@ -117,8 +127,9 @@ class ConstantPool : public Metadata {
|
||||
_has_dynamic_constant = 8
|
||||
};
|
||||
|
||||
int _flags; // old fashioned bit twiddling
|
||||
int _length; // number of elements in the array
|
||||
u2 _flags; // old fashioned bit twiddling
|
||||
|
||||
int _length; // number of elements in the array
|
||||
|
||||
union {
|
||||
// set for CDS to restore resolved references
|
||||
@ -135,8 +146,8 @@ class ConstantPool : public Metadata {
|
||||
|
||||
void set_operands(Array<u2>* operands) { _operands = operands; }
|
||||
|
||||
int flags() const { return _flags; }
|
||||
void set_flags(int f) { _flags = f; }
|
||||
u2 flags() const { return _flags; }
|
||||
void set_flags(u2 f) { _flags = f; }
|
||||
|
||||
private:
|
||||
intptr_t* base() const { return (intptr_t*) (((char*) this) + sizeof(ConstantPool)); }
|
||||
@ -189,6 +200,30 @@ class ConstantPool : public Metadata {
|
||||
_flags |= _has_preresolution;
|
||||
}
|
||||
|
||||
// minor and major version numbers of class file
|
||||
u2 major_version() const { return _major_version; }
|
||||
void set_major_version(u2 major_version) { _major_version = major_version; }
|
||||
u2 minor_version() const { return _minor_version; }
|
||||
void set_minor_version(u2 minor_version) { _minor_version = minor_version; }
|
||||
|
||||
// generics support
|
||||
Symbol* generic_signature() const {
|
||||
return (_generic_signature_index == 0) ?
|
||||
(Symbol*)NULL : symbol_at(_generic_signature_index);
|
||||
}
|
||||
u2 generic_signature_index() const { return _generic_signature_index; }
|
||||
void set_generic_signature_index(u2 sig_index) { _generic_signature_index = sig_index; }
|
||||
|
||||
// source file name
|
||||
Symbol* source_file_name() const {
|
||||
return (_source_file_name_index == 0) ?
|
||||
(Symbol*)NULL : symbol_at(_source_file_name_index);
|
||||
}
|
||||
u2 source_file_name_index() const { return _source_file_name_index; }
|
||||
void set_source_file_name_index(u2 sourcefile_index) { _source_file_name_index = sourcefile_index; }
|
||||
|
||||
void copy_fields(const ConstantPool* orig);
|
||||
|
||||
// Redefine classes support. If a method refering to this constant pool
|
||||
// is on the executing stack, or as a handle in vm code, this constant pool
|
||||
// can't be removed from the set of previous versions saved in the instance
|
||||
|
@ -43,7 +43,7 @@ public:
|
||||
static const KlassID ID = InstanceClassLoaderKlassID;
|
||||
|
||||
private:
|
||||
InstanceClassLoaderKlass(const ClassFileParser& parser) : InstanceKlass(parser, InstanceKlass::_misc_kind_class_loader, ID) {}
|
||||
InstanceClassLoaderKlass(const ClassFileParser& parser) : InstanceKlass(parser, InstanceKlass::_kind_class_loader, ID) {}
|
||||
|
||||
public:
|
||||
InstanceClassLoaderKlass() { assert(DumpSharedSpaces || UseSharedSpaces, "only for CDS"); }
|
||||
|
@ -442,7 +442,7 @@ InstanceKlass* InstanceKlass::allocate_instance_klass(const ClassFileParser& par
|
||||
ik = new (loader_data, size, THREAD) InstanceClassLoaderKlass(parser);
|
||||
} else {
|
||||
// normal
|
||||
ik = new (loader_data, size, THREAD) InstanceKlass(parser, InstanceKlass::_misc_kind_other);
|
||||
ik = new (loader_data, size, THREAD) InstanceKlass(parser, InstanceKlass::_kind_other);
|
||||
}
|
||||
} else {
|
||||
// reference
|
||||
@ -483,15 +483,15 @@ Array<int>* InstanceKlass::create_new_default_vtable_indices(int len, TRAPS) {
|
||||
InstanceKlass::InstanceKlass(const ClassFileParser& parser, unsigned kind, KlassID id) :
|
||||
Klass(id),
|
||||
_nest_members(NULL),
|
||||
_nest_host_index(0),
|
||||
_nest_host(NULL),
|
||||
_record_components(NULL),
|
||||
_static_field_size(parser.static_field_size()),
|
||||
_nonstatic_oop_map_size(nonstatic_oop_map_size(parser.total_oop_map_count())),
|
||||
_itable_len(parser.itable_size()),
|
||||
_init_thread(NULL),
|
||||
_nest_host_index(0),
|
||||
_init_state(allocated),
|
||||
_reference_type(parser.reference_type())
|
||||
_reference_type(parser.reference_type()),
|
||||
_init_thread(NULL)
|
||||
{
|
||||
set_vtable_length(parser.vtable_size());
|
||||
set_kind(kind);
|
||||
|
@ -191,10 +191,6 @@ class InstanceKlass: public Klass {
|
||||
// has not been validated.
|
||||
Array<jushort>* _nest_members;
|
||||
|
||||
// The NestHost attribute. The class info index for the class
|
||||
// that is the nest-host of this class. This data has not been validated.
|
||||
jushort _nest_host_index;
|
||||
|
||||
// Resolved nest-host klass: either true nest-host or self if we are not
|
||||
// nested, or an error occurred resolving or validating the nominated
|
||||
// nest-host. Can also be set directly by JDK API's that establish nest
|
||||
@ -217,60 +213,63 @@ class InstanceKlass: public Klass {
|
||||
// (including inherited fields but after header_size()).
|
||||
int _nonstatic_field_size;
|
||||
int _static_field_size; // number words used by static fields (oop and non-oop) in this klass
|
||||
// Constant pool index to the utf8 entry of the Generic signature,
|
||||
// or 0 if none.
|
||||
u2 _generic_signature_index;
|
||||
// Constant pool index to the utf8 entry for the name of source file
|
||||
// containing this klass, 0 if not specified.
|
||||
u2 _source_file_name_index;
|
||||
|
||||
int _nonstatic_oop_map_size;// size in words of nonstatic oop map blocks
|
||||
int _itable_len; // length of Java itable (in words)
|
||||
|
||||
// The NestHost attribute. The class info index for the class
|
||||
// that is the nest-host of this class. This data has not been validated.
|
||||
u2 _nest_host_index;
|
||||
u2 _this_class_index; // constant pool entry
|
||||
|
||||
u2 _static_oop_field_count;// number of static oop fields in this klass
|
||||
u2 _java_fields_count; // The number of declared Java fields
|
||||
int _nonstatic_oop_map_size;// size in words of nonstatic oop map blocks
|
||||
|
||||
int _itable_len; // length of Java itable (in words)
|
||||
volatile u2 _idnum_allocated_count; // JNI/JVMTI: increments with the addition of methods, old ids don't change
|
||||
|
||||
// _is_marked_dependent can be set concurrently, thus cannot be part of the
|
||||
// _misc_flags.
|
||||
bool _is_marked_dependent; // used for marking during flushing and deoptimization
|
||||
|
||||
// The low two bits of _misc_flags contains the kind field.
|
||||
// Class states are defined as ClassState (see above).
|
||||
// Place the _init_state here to utilize the unused 2-byte after
|
||||
// _idnum_allocated_count.
|
||||
u1 _init_state; // state of class
|
||||
|
||||
// This can be used to quickly discriminate among the four kinds of
|
||||
// InstanceKlass.
|
||||
// InstanceKlass. This should be an enum (?)
|
||||
static const unsigned _kind_other = 0; // concrete InstanceKlass
|
||||
static const unsigned _kind_reference = 1; // InstanceRefKlass
|
||||
static const unsigned _kind_class_loader = 2; // InstanceClassLoaderKlass
|
||||
static const unsigned _kind_mirror = 3; // InstanceMirrorKlass
|
||||
|
||||
static const unsigned _misc_kind_field_size = 2;
|
||||
static const unsigned _misc_kind_field_pos = 0;
|
||||
static const unsigned _misc_kind_field_mask = (1u << _misc_kind_field_size) - 1u;
|
||||
u1 _reference_type; // reference type
|
||||
u1 _kind; // kind of InstanceKlass
|
||||
|
||||
static const unsigned _misc_kind_other = 0; // concrete InstanceKlass
|
||||
static const unsigned _misc_kind_reference = 1; // InstanceRefKlass
|
||||
static const unsigned _misc_kind_class_loader = 2; // InstanceClassLoaderKlass
|
||||
static const unsigned _misc_kind_mirror = 3; // InstanceMirrorKlass
|
||||
|
||||
// Start after _misc_kind field.
|
||||
enum {
|
||||
_misc_rewritten = 1 << 2, // methods rewritten.
|
||||
_misc_has_nonstatic_fields = 1 << 3, // for sizing with UseCompressedOops
|
||||
_misc_should_verify_class = 1 << 4, // allow caching of preverification
|
||||
_misc_is_unsafe_anonymous = 1 << 5, // has embedded _unsafe_anonymous_host field
|
||||
_misc_is_contended = 1 << 6, // marked with contended annotation
|
||||
_misc_has_nonstatic_concrete_methods = 1 << 7, // class/superclass/implemented interfaces has non-static, concrete methods
|
||||
_misc_declares_nonstatic_concrete_methods = 1 << 8, // directly declares non-static, concrete methods
|
||||
_misc_has_been_redefined = 1 << 9, // class has been redefined
|
||||
_misc_has_passed_fingerprint_check = 1 << 10, // when this class was loaded, the fingerprint computed from its
|
||||
_misc_rewritten = 1 << 0, // methods rewritten.
|
||||
_misc_has_nonstatic_fields = 1 << 1, // for sizing with UseCompressedOops
|
||||
_misc_should_verify_class = 1 << 2, // allow caching of preverification
|
||||
_misc_is_unsafe_anonymous = 1 << 3, // has embedded _unsafe_anonymous_host field
|
||||
_misc_is_contended = 1 << 4, // marked with contended annotation
|
||||
_misc_has_nonstatic_concrete_methods = 1 << 5, // class/superclass/implemented interfaces has non-static, concrete methods
|
||||
_misc_declares_nonstatic_concrete_methods = 1 << 6, // directly declares non-static, concrete methods
|
||||
_misc_has_been_redefined = 1 << 7, // class has been redefined
|
||||
_misc_has_passed_fingerprint_check = 1 << 8, // when this class was loaded, the fingerprint computed from its
|
||||
// code source was found to be matching the value recorded by AOT.
|
||||
_misc_is_scratch_class = 1 << 11, // class is the redefined scratch class
|
||||
_misc_is_shared_boot_class = 1 << 12, // defining class loader is boot class loader
|
||||
_misc_is_shared_platform_class = 1 << 13, // defining class loader is platform class loader
|
||||
_misc_is_shared_app_class = 1 << 14, // defining class loader is app class loader
|
||||
_misc_has_resolved_methods = 1 << 15, // resolved methods table entries added for this class
|
||||
_misc_is_being_redefined = 1 << 16, // used for locking redefinition
|
||||
_misc_has_contended_annotations = 1 << 17 // has @Contended annotation
|
||||
_misc_is_scratch_class = 1 << 9, // class is the redefined scratch class
|
||||
_misc_is_shared_boot_class = 1 << 10, // defining class loader is boot class loader
|
||||
_misc_is_shared_platform_class = 1 << 11, // defining class loader is platform class loader
|
||||
_misc_is_shared_app_class = 1 << 12, // defining class loader is app class loader
|
||||
_misc_has_resolved_methods = 1 << 13, // resolved methods table entries added for this class
|
||||
_misc_is_being_redefined = 1 << 14, // used for locking redefinition
|
||||
_misc_has_contended_annotations = 1 << 15 // has @Contended annotation
|
||||
};
|
||||
u2 shared_loader_type_bits() const {
|
||||
return _misc_is_shared_boot_class|_misc_is_shared_platform_class|_misc_is_shared_app_class;
|
||||
}
|
||||
u4 _misc_flags;
|
||||
u2 _minor_version; // minor version number of class file
|
||||
u2 _major_version; // major version number of class file
|
||||
u2 _misc_flags; // There is more space in access_flags for more flags.
|
||||
|
||||
Thread* _init_thread; // Pointer to current thread doing initialization (to handle recursive initialization)
|
||||
OopMapCache* volatile _oop_map_cache; // OopMapCache for all methods in the klass (allocated lazily)
|
||||
JNIid* _jni_ids; // First JNI identifier for static fields in this class
|
||||
@ -287,15 +286,6 @@ class InstanceKlass: public Klass {
|
||||
JvmtiCachedClassFileData* _cached_class_file;
|
||||
#endif
|
||||
|
||||
volatile u2 _idnum_allocated_count; // JNI/JVMTI: increments with the addition of methods, old ids don't change
|
||||
|
||||
// Class states are defined as ClassState (see above).
|
||||
// Place the _init_state here to utilize the unused 2-byte after
|
||||
// _idnum_allocated_count.
|
||||
u1 _init_state; // state of class
|
||||
u1 _reference_type; // reference type
|
||||
|
||||
u2 _this_class_index; // constant pool entry
|
||||
#if INCLUDE_JVMTI
|
||||
JvmtiCachedClassFieldMap* _jvmti_cached_class_field_map; // JVMTI: used during heap iteration
|
||||
#endif
|
||||
@ -730,22 +720,15 @@ public:
|
||||
}
|
||||
|
||||
// source file name
|
||||
Symbol* source_file_name() const {
|
||||
return (_source_file_name_index == 0) ?
|
||||
(Symbol*)NULL : _constants->symbol_at(_source_file_name_index);
|
||||
}
|
||||
u2 source_file_name_index() const {
|
||||
return _source_file_name_index;
|
||||
}
|
||||
void set_source_file_name_index(u2 sourcefile_index) {
|
||||
_source_file_name_index = sourcefile_index;
|
||||
}
|
||||
Symbol* source_file_name() const { return _constants->source_file_name(); }
|
||||
u2 source_file_name_index() const { return _constants->source_file_name_index(); }
|
||||
void set_source_file_name_index(u2 sourcefile_index) { _constants->set_source_file_name_index(sourcefile_index); }
|
||||
|
||||
// minor and major version numbers of class file
|
||||
u2 minor_version() const { return _minor_version; }
|
||||
void set_minor_version(u2 minor_version) { _minor_version = minor_version; }
|
||||
u2 major_version() const { return _major_version; }
|
||||
void set_major_version(u2 major_version) { _major_version = major_version; }
|
||||
u2 minor_version() const { return _constants->minor_version(); }
|
||||
void set_minor_version(u2 minor_version) { _constants->set_minor_version(minor_version); }
|
||||
u2 major_version() const { return _constants->major_version(); }
|
||||
void set_major_version(u2 major_version) { _constants->set_major_version(major_version); }
|
||||
|
||||
// source debug extension
|
||||
const char* source_debug_extension() const { return _source_debug_extension; }
|
||||
@ -852,24 +835,20 @@ public:
|
||||
private:
|
||||
|
||||
void set_kind(unsigned kind) {
|
||||
assert(kind <= _misc_kind_field_mask, "Invalid InstanceKlass kind");
|
||||
unsigned fmask = _misc_kind_field_mask << _misc_kind_field_pos;
|
||||
unsigned flags = _misc_flags & ~fmask;
|
||||
_misc_flags = (flags | (kind << _misc_kind_field_pos));
|
||||
_kind = (u1)kind;
|
||||
}
|
||||
|
||||
bool is_kind(unsigned desired) const {
|
||||
unsigned kind = (_misc_flags >> _misc_kind_field_pos) & _misc_kind_field_mask;
|
||||
return kind == desired;
|
||||
return _kind == (u1)desired;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
// Other is anything that is not one of the more specialized kinds of InstanceKlass.
|
||||
bool is_other_instance_klass() const { return is_kind(_misc_kind_other); }
|
||||
bool is_reference_instance_klass() const { return is_kind(_misc_kind_reference); }
|
||||
bool is_mirror_instance_klass() const { return is_kind(_misc_kind_mirror); }
|
||||
bool is_class_loader_instance_klass() const { return is_kind(_misc_kind_class_loader); }
|
||||
bool is_other_instance_klass() const { return is_kind(_kind_other); }
|
||||
bool is_reference_instance_klass() const { return is_kind(_kind_reference); }
|
||||
bool is_mirror_instance_klass() const { return is_kind(_kind_mirror); }
|
||||
bool is_class_loader_instance_klass() const { return is_kind(_kind_class_loader); }
|
||||
|
||||
#if INCLUDE_JVMTI
|
||||
|
||||
@ -943,16 +922,9 @@ public:
|
||||
void set_initial_method_idnum(u2 value) { _idnum_allocated_count = value; }
|
||||
|
||||
// generics support
|
||||
Symbol* generic_signature() const {
|
||||
return (_generic_signature_index == 0) ?
|
||||
(Symbol*)NULL : _constants->symbol_at(_generic_signature_index);
|
||||
}
|
||||
u2 generic_signature_index() const {
|
||||
return _generic_signature_index;
|
||||
}
|
||||
void set_generic_signature_index(u2 sig_index) {
|
||||
_generic_signature_index = sig_index;
|
||||
}
|
||||
Symbol* generic_signature() const { return _constants->generic_signature(); }
|
||||
u2 generic_signature_index() const { return _constants->generic_signature_index(); }
|
||||
void set_generic_signature_index(u2 sig_index) { _constants->set_generic_signature_index(sig_index); }
|
||||
|
||||
u2 enclosing_method_data(int offset) const;
|
||||
u2 enclosing_method_class_index() const {
|
||||
|
@ -50,7 +50,7 @@ class InstanceMirrorKlass: public InstanceKlass {
|
||||
private:
|
||||
static int _offset_of_static_fields;
|
||||
|
||||
InstanceMirrorKlass(const ClassFileParser& parser) : InstanceKlass(parser, InstanceKlass::_misc_kind_mirror, ID) {}
|
||||
InstanceMirrorKlass(const ClassFileParser& parser) : InstanceKlass(parser, InstanceKlass::_kind_mirror, ID) {}
|
||||
|
||||
public:
|
||||
InstanceMirrorKlass() { assert(DumpSharedSpaces || UseSharedSpaces, "only for CDS"); }
|
||||
|
@ -53,7 +53,7 @@ class InstanceRefKlass: public InstanceKlass {
|
||||
static const KlassID ID = InstanceRefKlassID;
|
||||
|
||||
private:
|
||||
InstanceRefKlass(const ClassFileParser& parser) : InstanceKlass(parser, InstanceKlass::_misc_kind_reference, ID) {}
|
||||
InstanceRefKlass(const ClassFileParser& parser) : InstanceKlass(parser, InstanceKlass::_kind_reference, ID) {}
|
||||
|
||||
public:
|
||||
InstanceRefKlass() { assert(DumpSharedSpaces || UseSharedSpaces, "only for CDS"); }
|
||||
|
@ -117,6 +117,9 @@ class Klass : public Metadata {
|
||||
// Klass identifier used to implement devirtualized oop closure dispatching.
|
||||
const KlassID _id;
|
||||
|
||||
// vtable length
|
||||
int _vtable_len;
|
||||
|
||||
// The fields _super_check_offset, _secondary_super_cache, _secondary_supers
|
||||
// and _primary_supers all help make fast subtype checks. See big discussion
|
||||
// in doc/server_compiler/checktype.txt
|
||||
@ -136,7 +139,7 @@ class Klass : public Metadata {
|
||||
// Ordered list of all primary supertypes
|
||||
Klass* _primary_supers[_primary_super_limit];
|
||||
// java/lang/Class instance mirroring this class
|
||||
OopHandle _java_mirror;
|
||||
OopHandle _java_mirror;
|
||||
// Superclass
|
||||
Klass* _super;
|
||||
// First subclass (NULL if none); _subklass->next_sibling() is next one
|
||||
@ -162,9 +165,6 @@ class Klass : public Metadata {
|
||||
markWord _prototype_header; // Used when biased locking is both enabled and disabled for this type
|
||||
jint _biased_lock_revocation_count;
|
||||
|
||||
// vtable length
|
||||
int _vtable_len;
|
||||
|
||||
private:
|
||||
// This is an index into FileMapHeader::_shared_path_table[], to
|
||||
// associate this class with the JAR file where it's loaded from during
|
||||
@ -179,6 +179,7 @@ private:
|
||||
_has_raw_archived_mirror = 1
|
||||
};
|
||||
#endif
|
||||
|
||||
// The _archived_mirror is set at CDS dump time pointing to the cached mirror
|
||||
// in the open archive heap region when archiving java object is supported.
|
||||
CDS_JAVA_HEAP_ONLY(narrowOop _archived_mirror;)
|
||||
|
@ -1432,6 +1432,7 @@ methodHandle Method::make_method_handle_intrinsic(vmIntrinsics::ID iid,
|
||||
ConstantPool* cp_oop = ConstantPool::allocate(loader_data, cp_length, CHECK_(empty));
|
||||
cp = constantPoolHandle(THREAD, cp_oop);
|
||||
}
|
||||
cp->copy_fields(holder->constants());
|
||||
cp->set_pool_holder(holder);
|
||||
cp->symbol_at_put(_imcp_invoke_name, name);
|
||||
cp->symbol_at_put(_imcp_invoke_signature, signature);
|
||||
|
@ -1699,10 +1699,9 @@ jvmtiError VM_RedefineClasses::merge_cp_and_rewrite(
|
||||
return JVMTI_ERROR_INTERNAL;
|
||||
}
|
||||
|
||||
if (old_cp->has_dynamic_constant()) {
|
||||
merge_cp->set_has_dynamic_constant();
|
||||
scratch_cp->set_has_dynamic_constant();
|
||||
}
|
||||
// Save fields from the old_cp.
|
||||
merge_cp->copy_fields(old_cp());
|
||||
scratch_cp->copy_fields(old_cp());
|
||||
|
||||
log_info(redefine, class, constantpool)("merge_cp_len=%d, index_map_len=%d", merge_cp_length, _index_map_count);
|
||||
|
||||
@ -3373,9 +3372,7 @@ void VM_RedefineClasses::set_new_constant_pool(
|
||||
// reference to the cp holder is needed for copy_operands()
|
||||
smaller_cp->set_pool_holder(scratch_class);
|
||||
|
||||
if (scratch_cp->has_dynamic_constant()) {
|
||||
smaller_cp->set_has_dynamic_constant();
|
||||
}
|
||||
smaller_cp->copy_fields(scratch_cp());
|
||||
|
||||
scratch_cp->copy_cp_to(1, scratch_cp_length - 1, smaller_cp, 1, THREAD);
|
||||
if (HAS_PENDING_EXCEPTION) {
|
||||
@ -4254,16 +4251,6 @@ void VM_RedefineClasses::redefine_single_class(jclass the_jclass,
|
||||
|
||||
swap_annotations(the_class, scratch_class);
|
||||
|
||||
// Replace minor version number of class file
|
||||
u2 old_minor_version = the_class->minor_version();
|
||||
the_class->set_minor_version(scratch_class->minor_version());
|
||||
scratch_class->set_minor_version(old_minor_version);
|
||||
|
||||
// Replace major version number of class file
|
||||
u2 old_major_version = the_class->major_version();
|
||||
the_class->set_major_version(scratch_class->major_version());
|
||||
scratch_class->set_major_version(old_major_version);
|
||||
|
||||
// Replace CP indexes for class and name+type of enclosing method
|
||||
u2 old_class_idx = the_class->enclosing_method_class_index();
|
||||
u2 old_method_idx = the_class->enclosing_method_method_index();
|
||||
|
@ -210,6 +210,10 @@ typedef HashtableEntry<InstanceKlass*, mtClass> KlassHashtableEntry;
|
||||
nonstatic_field(ConstantPool, _operands, Array<u2>*) \
|
||||
nonstatic_field(ConstantPool, _resolved_klasses, Array<Klass*>*) \
|
||||
nonstatic_field(ConstantPool, _length, int) \
|
||||
nonstatic_field(ConstantPool, _minor_version, u2) \
|
||||
nonstatic_field(ConstantPool, _major_version, u2) \
|
||||
nonstatic_field(ConstantPool, _generic_signature_index, u2) \
|
||||
nonstatic_field(ConstantPool, _source_file_name_index, u2) \
|
||||
nonstatic_field(ConstantPoolCache, _resolved_references, OopHandle) \
|
||||
nonstatic_field(ConstantPoolCache, _reference_map, Array<u2>*) \
|
||||
nonstatic_field(ConstantPoolCache, _length, int) \
|
||||
@ -222,7 +226,6 @@ typedef HashtableEntry<InstanceKlass*, mtClass> KlassHashtableEntry;
|
||||
nonstatic_field(InstanceKlass, _fields, Array<u2>*) \
|
||||
nonstatic_field(InstanceKlass, _java_fields_count, u2) \
|
||||
nonstatic_field(InstanceKlass, _constants, ConstantPool*) \
|
||||
nonstatic_field(InstanceKlass, _source_file_name_index, u2) \
|
||||
nonstatic_field(InstanceKlass, _source_debug_extension, const char*) \
|
||||
nonstatic_field(InstanceKlass, _inner_classes, Array<jushort>*) \
|
||||
nonstatic_field(InstanceKlass, _nonstatic_field_size, int) \
|
||||
@ -230,9 +233,7 @@ typedef HashtableEntry<InstanceKlass*, mtClass> KlassHashtableEntry;
|
||||
nonstatic_field(InstanceKlass, _static_oop_field_count, u2) \
|
||||
nonstatic_field(InstanceKlass, _nonstatic_oop_map_size, int) \
|
||||
nonstatic_field(InstanceKlass, _is_marked_dependent, bool) \
|
||||
nonstatic_field(InstanceKlass, _misc_flags, u4) \
|
||||
nonstatic_field(InstanceKlass, _minor_version, u2) \
|
||||
nonstatic_field(InstanceKlass, _major_version, u2) \
|
||||
nonstatic_field(InstanceKlass, _misc_flags, u2) \
|
||||
nonstatic_field(InstanceKlass, _init_state, u1) \
|
||||
nonstatic_field(InstanceKlass, _init_thread, Thread*) \
|
||||
nonstatic_field(InstanceKlass, _itable_len, int) \
|
||||
@ -241,7 +242,6 @@ typedef HashtableEntry<InstanceKlass*, mtClass> KlassHashtableEntry;
|
||||
nonstatic_field(InstanceKlass, _jni_ids, JNIid*) \
|
||||
nonstatic_field(InstanceKlass, _osr_nmethods_head, nmethod*) \
|
||||
JVMTI_ONLY(nonstatic_field(InstanceKlass, _breakpoints, BreakpointInfo*)) \
|
||||
nonstatic_field(InstanceKlass, _generic_signature_index, u2) \
|
||||
volatile_nonstatic_field(InstanceKlass, _methods_jmethod_ids, jmethodID*) \
|
||||
volatile_nonstatic_field(InstanceKlass, _idnum_allocated_count, u2) \
|
||||
nonstatic_field(InstanceKlass, _annotations, Annotations*) \
|
||||
|
@ -235,7 +235,11 @@ inline int wcslen(const jchar* x) { return wcslen((const wchar_t*)x); }
|
||||
#define FORMAT64_MODIFIER "ll"
|
||||
#endif // _LP64
|
||||
|
||||
#define offset_of(klass,field) offsetof(klass,field)
|
||||
// gcc warns about applying offsetof() to non-POD object or calculating
|
||||
// offset directly when base address is NULL. Use 16 to get around the
|
||||
// warning. The -Wno-invalid-offsetof option could be used to suppress
|
||||
// this warning, but we instead just avoid the use of offsetof().
|
||||
#define offset_of(klass,field) (size_t)((intx)&(((klass*)16)->field) - 16)
|
||||
|
||||
#if defined(_LP64) && defined(__APPLE__)
|
||||
#define JLONG_FORMAT "%ld"
|
||||
|
@ -350,7 +350,7 @@ enum NamedGroup {
|
||||
|
||||
static NamedGroup nameOf(String name) {
|
||||
for (NamedGroup group : NamedGroup.values()) {
|
||||
if (group.name.equals(name)) {
|
||||
if (group.name.equalsIgnoreCase(name)) {
|
||||
return group;
|
||||
}
|
||||
}
|
||||
|
@ -30,18 +30,18 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.sun.source.doctree.AttributeTree.ValueKind;
|
||||
import com.sun.source.doctree.ErroneousTree;
|
||||
import com.sun.source.doctree.UnknownBlockTagTree;
|
||||
import com.sun.tools.javac.parser.DocCommentParser.TagParser.Kind;
|
||||
import com.sun.tools.javac.parser.Tokens.Comment;
|
||||
import com.sun.tools.javac.parser.Tokens.TokenKind;
|
||||
import com.sun.tools.javac.tree.DCTree;
|
||||
import com.sun.tools.javac.tree.DCTree.DCAttribute;
|
||||
import com.sun.tools.javac.tree.DCTree.DCDocComment;
|
||||
import com.sun.tools.javac.tree.DCTree.DCEndElement;
|
||||
import com.sun.tools.javac.tree.DCTree.DCEndPosTree;
|
||||
import com.sun.tools.javac.tree.DCTree.DCErroneous;
|
||||
import com.sun.tools.javac.tree.DCTree.DCIdentifier;
|
||||
import com.sun.tools.javac.tree.DCTree.DCReference;
|
||||
import com.sun.tools.javac.tree.DCTree.DCStartElement;
|
||||
import com.sun.tools.javac.tree.DCTree.DCText;
|
||||
import com.sun.tools.javac.tree.DocTreeMaker;
|
||||
import com.sun.tools.javac.tree.JCTree;
|
||||
@ -54,7 +54,7 @@ import com.sun.tools.javac.util.Names;
|
||||
import com.sun.tools.javac.util.Position;
|
||||
import com.sun.tools.javac.util.StringUtils;
|
||||
|
||||
import static com.sun.tools.javac.util.LayoutCharacters.*;
|
||||
import static com.sun.tools.javac.util.LayoutCharacters.EOI;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -261,7 +261,7 @@ public class DocCommentParser {
|
||||
/**
|
||||
* Read a series of block tags, including their content.
|
||||
* Standard tags parse their content appropriately.
|
||||
* Non-standard tags are represented by {@link UnknownBlockTag}.
|
||||
* Non-standard tags are represented by {@link UnknownBlockTagTree}.
|
||||
*/
|
||||
protected List<DCTree> blockTags() {
|
||||
ListBuffer<DCTree> tags = new ListBuffer<>();
|
||||
@ -273,7 +273,7 @@ public class DocCommentParser {
|
||||
/**
|
||||
* Read a single block tag, including its content.
|
||||
* Standard tags parse their content appropriately.
|
||||
* Non-standard tags are represented by {@link UnknownBlockTag}.
|
||||
* Non-standard tags are represented by {@link UnknownBlockTagTree}.
|
||||
*/
|
||||
protected DCTree blockTag() {
|
||||
int p = bp;
|
||||
@ -321,8 +321,8 @@ public class DocCommentParser {
|
||||
/**
|
||||
* Read a single inline tag, including its content.
|
||||
* Standard tags parse their content appropriately.
|
||||
* Non-standard tags are represented by {@link UnknownBlockTag}.
|
||||
* Malformed tags may be returned as {@link Erroneous}.
|
||||
* Non-standard tags are represented by {@link UnknownBlockTagTree}.
|
||||
* Malformed tags may be returned as {@link ErroneousTree}.
|
||||
*/
|
||||
protected DCTree inlineTag() {
|
||||
int p = bp - 1;
|
||||
@ -413,13 +413,6 @@ public class DocCommentParser {
|
||||
lastNonWhite = bp;
|
||||
break;
|
||||
|
||||
case '@':
|
||||
if (newline)
|
||||
break loop;
|
||||
newline = false;
|
||||
lastNonWhite = bp;
|
||||
break;
|
||||
|
||||
default:
|
||||
newline = false;
|
||||
lastNonWhite = bp;
|
||||
|
@ -92,6 +92,10 @@ public class ConstantPool extends Metadata implements ClassConstants {
|
||||
poolHolder = new MetadataField(type.getAddressField("_pool_holder"), 0);
|
||||
length = new CIntField(type.getCIntegerField("_length"), 0);
|
||||
resolved_klasses = type.getAddressField("_resolved_klasses");
|
||||
majorVersion = new CIntField(type.getCIntegerField("_major_version"), 0);
|
||||
minorVersion = new CIntField(type.getCIntegerField("_minor_version"), 0);
|
||||
sourceFileNameIndex = new CIntField(type.getCIntegerField("_source_file_name_index"), 0);
|
||||
genericSignatureIndex = new CIntField(type.getCIntegerField("_generic_signature_index"), 0);
|
||||
headerSize = type.getSize();
|
||||
elementSize = 0;
|
||||
// fetch constants:
|
||||
@ -112,6 +116,10 @@ public class ConstantPool extends Metadata implements ClassConstants {
|
||||
private static AddressField resolved_klasses;
|
||||
private static MetadataField poolHolder;
|
||||
private static CIntField length; // number of elements in oop
|
||||
private static CIntField majorVersion;
|
||||
private static CIntField minorVersion;
|
||||
private static CIntField genericSignatureIndex;
|
||||
private static CIntField sourceFileNameIndex;
|
||||
|
||||
private static long headerSize;
|
||||
private static long elementSize;
|
||||
@ -131,6 +139,20 @@ public class ConstantPool extends Metadata implements ClassConstants {
|
||||
public Oop getResolvedReferences() {
|
||||
return getCache().getResolvedReferences();
|
||||
}
|
||||
public long majorVersion() { return majorVersion.getValue(this); }
|
||||
public long minorVersion() { return minorVersion.getValue(this); }
|
||||
|
||||
public Symbol getGenericSignature() {
|
||||
long index = genericSignatureIndex.getValue(this);
|
||||
if (index != 0) {
|
||||
return getSymbolAt(index);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Symbol getSourceFileName() { return getSymbolAt(sourceFileNameIndex.getValue(this)); }
|
||||
|
||||
public KlassArray getResolvedKlasses() {
|
||||
return new KlassArray(resolved_klasses.getValue(getAddress()));
|
||||
}
|
||||
|
@ -95,7 +95,6 @@ public class InstanceKlass extends Klass {
|
||||
constants = new MetadataField(type.getAddressField("_constants"), 0);
|
||||
sourceDebugExtension = type.getAddressField("_source_debug_extension");
|
||||
innerClasses = type.getAddressField("_inner_classes");
|
||||
sourceFileNameIndex = new CIntField(type.getCIntegerField("_source_file_name_index"), 0);
|
||||
nonstaticFieldSize = new CIntField(type.getCIntegerField("_nonstatic_field_size"), 0);
|
||||
staticFieldSize = new CIntField(type.getCIntegerField("_static_field_size"), 0);
|
||||
staticOopFieldCount = new CIntField(type.getCIntegerField("_static_oop_field_count"), 0);
|
||||
@ -106,10 +105,7 @@ public class InstanceKlass extends Klass {
|
||||
if (VM.getVM().isJvmtiSupported()) {
|
||||
breakpoints = type.getAddressField("_breakpoints");
|
||||
}
|
||||
genericSignatureIndex = new CIntField(type.getCIntegerField("_generic_signature_index"), 0);
|
||||
miscFlags = new CIntField(type.getCIntegerField("_misc_flags"), 0);
|
||||
majorVersion = new CIntField(type.getCIntegerField("_major_version"), 0);
|
||||
minorVersion = new CIntField(type.getCIntegerField("_minor_version"), 0);
|
||||
headerSize = type.getSize();
|
||||
|
||||
// read field offset constants
|
||||
@ -169,7 +165,6 @@ public class InstanceKlass extends Klass {
|
||||
private static MetadataField constants;
|
||||
private static AddressField sourceDebugExtension;
|
||||
private static AddressField innerClasses;
|
||||
private static CIntField sourceFileNameIndex;
|
||||
private static CIntField nonstaticFieldSize;
|
||||
private static CIntField staticFieldSize;
|
||||
private static CIntField staticOopFieldCount;
|
||||
@ -178,10 +173,7 @@ public class InstanceKlass extends Klass {
|
||||
private static CIntField initState;
|
||||
private static CIntField itableLen;
|
||||
private static AddressField breakpoints;
|
||||
private static CIntField genericSignatureIndex;
|
||||
private static CIntField miscFlags;
|
||||
private static CIntField majorVersion;
|
||||
private static CIntField minorVersion;
|
||||
|
||||
// type safe enum for ClassState from instanceKlass.hpp
|
||||
public static class ClassState {
|
||||
@ -427,23 +419,16 @@ public class InstanceKlass extends Klass {
|
||||
return allFieldsCount;
|
||||
}
|
||||
public ConstantPool getConstants() { return (ConstantPool) constants.getValue(this); }
|
||||
public Symbol getSourceFileName() { return getConstants().getSymbolAt(sourceFileNameIndex.getValue(this)); }
|
||||
public Symbol getSourceFileName() { return getConstants().getSourceFileName(); }
|
||||
public String getSourceDebugExtension(){ return CStringUtilities.getString(sourceDebugExtension.getValue(getAddress())); }
|
||||
public long getNonstaticFieldSize() { return nonstaticFieldSize.getValue(this); }
|
||||
public long getStaticOopFieldCount() { return staticOopFieldCount.getValue(this); }
|
||||
public long getNonstaticOopMapSize() { return nonstaticOopMapSize.getValue(this); }
|
||||
public boolean getIsMarkedDependent() { return isMarkedDependent.getValue(this) != 0; }
|
||||
public long getItableLen() { return itableLen.getValue(this); }
|
||||
public long majorVersion() { return majorVersion.getValue(this); }
|
||||
public long minorVersion() { return minorVersion.getValue(this); }
|
||||
public Symbol getGenericSignature() {
|
||||
long index = genericSignatureIndex.getValue(this);
|
||||
if (index != 0) {
|
||||
return getConstants().getSymbolAt(index);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
public long majorVersion() { return getConstants().majorVersion(); }
|
||||
public long minorVersion() { return getConstants().minorVersion(); }
|
||||
public Symbol getGenericSignature() { return getConstants().getGenericSignature(); }
|
||||
|
||||
// "size helper" == instance size in words
|
||||
public long getSizeHelper() {
|
||||
|
8
src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/LinuxAppImageBuilder.java
8
src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/LinuxAppImageBuilder.java
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 2020, 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
|
||||
@ -40,7 +40,6 @@ import static jdk.incubator.jpackage.internal.StandardBundlerParam.*;
|
||||
|
||||
public class LinuxAppImageBuilder extends AbstractAppImageBuilder {
|
||||
|
||||
private static final String LIBRARY_NAME = "libapplauncher.so";
|
||||
final static String DEFAULT_ICON = "java32.png";
|
||||
|
||||
private final ApplicationLayout appLayout;
|
||||
@ -109,11 +108,6 @@ public class LinuxAppImageBuilder extends AbstractAppImageBuilder {
|
||||
// create the primary launcher
|
||||
createLauncherForEntryPoint(params, null);
|
||||
|
||||
// Copy library to the launcher folder
|
||||
try (InputStream is_lib = getResourceAsStream(LIBRARY_NAME)) {
|
||||
writeEntry(is_lib, appLayout.dllDirectory().resolve(LIBRARY_NAME));
|
||||
}
|
||||
|
||||
// create the additional launchers, if any
|
||||
List<Map<String, ? super Object>> entryPoints
|
||||
= StandardBundlerParam.ADD_LAUNCHERS.fetchFrom(params);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 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
|
||||
@ -23,39 +23,36 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#ifndef PLATFORM_DEFS_H
|
||||
#define PLATFORM_DEFS_H
|
||||
#include "AppLauncher.h"
|
||||
#include "FileUtils.h"
|
||||
#include "UnixSysInfo.h"
|
||||
|
||||
// Define Windows compatibility requirements XP or later
|
||||
#define WINVER 0x0600
|
||||
#define _WIN32_WINNT 0x0600
|
||||
|
||||
#include <Windows.h>
|
||||
#include <tchar.h>
|
||||
#include <shlobj.h>
|
||||
#include <direct.h>
|
||||
#include <process.h>
|
||||
#include <malloc.h>
|
||||
#include <string>
|
||||
namespace {
|
||||
|
||||
using namespace std;
|
||||
void launchApp() {
|
||||
setlocale(LC_ALL, "en_US.utf8");
|
||||
|
||||
#ifndef WINDOWS
|
||||
#define WINDOWS
|
||||
#endif
|
||||
const tstring launcherPath = SysInfo::getProcessModulePath();
|
||||
|
||||
typedef std::wstring TString;
|
||||
#define StringLength wcslen
|
||||
// Launcher should be in "bin" subdirectory of app image.
|
||||
const tstring appImageRoot = FileUtils::dirname(
|
||||
FileUtils::dirname(launcherPath));
|
||||
|
||||
#define TRAILING_PATHSEPARATOR '\\'
|
||||
#define BAD_TRAILING_PATHSEPARATOR '/'
|
||||
#define PATH_SEPARATOR ';'
|
||||
#define BAD_PATH_SEPARATOR ':'
|
||||
AppLauncher()
|
||||
.setImageRoot(appImageRoot)
|
||||
.addJvmLibName(_T("lib/libjli.so"))
|
||||
.setAppDir(FileUtils::mkpath() << appImageRoot << _T("lib/app"))
|
||||
.setDefaultRuntimePath(FileUtils::mkpath() << appImageRoot
|
||||
<< _T("lib/runtime"))
|
||||
.launch();
|
||||
}
|
||||
|
||||
typedef ULONGLONG TPlatformNumber;
|
||||
typedef DWORD TProcessID;
|
||||
} // namespace
|
||||
|
||||
typedef void* Module;
|
||||
typedef void* Procedure;
|
||||
|
||||
#endif // PLATFORM_DEFS_H
|
||||
int main(int argc, char *argv[]) {
|
||||
SysInfo::argc = argc;
|
||||
SysInfo::argv = argv;
|
||||
return AppLauncher::launch(std::nothrow, launchApp);
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
#include <unistd.h>
|
||||
#include "FileUtils.h"
|
||||
#include "ErrorHandling.h"
|
||||
|
||||
namespace SysInfo {
|
||||
|
||||
tstring getProcessModulePath() {
|
||||
const char* path = "/proc/self/exe";
|
||||
char buffer[PATH_MAX] = { 0 };
|
||||
ssize_t len = readlink(path, buffer, sizeof(buffer));
|
||||
if (len < 0) {
|
||||
JP_THROW(tstrings::any() << "readlink(" << path
|
||||
<< ") failed. Error: " << lastCRTError());
|
||||
}
|
||||
|
||||
return tstring(buffer, len);
|
||||
}
|
||||
|
||||
} // end of namespace SysInfo
|
@ -1,87 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2019, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <locale.h>
|
||||
#include <string>
|
||||
#include <libgen.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
typedef bool (*start_launcher)(int argc, char* argv[]);
|
||||
typedef void (*stop_launcher)();
|
||||
|
||||
#define MAX_PATH 1024
|
||||
|
||||
std::string GetProgramPath() {
|
||||
ssize_t len = 0;
|
||||
std::string result;
|
||||
char buffer[MAX_PATH] = {0};
|
||||
|
||||
if ((len = readlink("/proc/self/exe", buffer, MAX_PATH - 1)) != -1) {
|
||||
buffer[len] = '\0';
|
||||
result = buffer;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int result = 1;
|
||||
setlocale(LC_ALL, "en_US.utf8");
|
||||
void* library = NULL;
|
||||
|
||||
{
|
||||
std::string programPath = GetProgramPath();
|
||||
std::string libraryName = dirname((char*)programPath.c_str());
|
||||
libraryName += "/../lib/libapplauncher.so";
|
||||
library = dlopen(libraryName.c_str(), RTLD_LAZY);
|
||||
|
||||
if (library == NULL) {
|
||||
fprintf(stderr, "dlopen failed: %s\n", dlerror());
|
||||
fprintf(stderr, "%s not found.\n", libraryName.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
if (library != NULL) {
|
||||
start_launcher start = (start_launcher)dlsym(library, "start_launcher");
|
||||
stop_launcher stop = (stop_launcher)dlsym(library, "stop_launcher");
|
||||
|
||||
if (start != NULL && stop != NULL) {
|
||||
if (start(argc, argv) == true) {
|
||||
result = 0;
|
||||
stop();
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "cannot find start_launcher and stop_launcher in libapplauncher.so");
|
||||
}
|
||||
|
||||
dlclose(library);
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,73 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2019, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#ifndef LINUXPLATFORM_H
|
||||
#define LINUXPLATFORM_H
|
||||
|
||||
#include "Platform.h"
|
||||
#include "PosixPlatform.h"
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include <pthread.h>
|
||||
#include <list>
|
||||
|
||||
class LinuxPlatform : virtual public Platform, PosixPlatform {
|
||||
private:
|
||||
pthread_t FMainThread;
|
||||
|
||||
protected:
|
||||
virtual TString getTmpDirString();
|
||||
|
||||
public:
|
||||
LinuxPlatform(void);
|
||||
virtual ~LinuxPlatform(void);
|
||||
|
||||
TString GetPackageAppDirectory();
|
||||
TString GetPackageLauncherDirectory();
|
||||
TString GetPackageRuntimeBinDirectory();
|
||||
|
||||
virtual void ShowMessage(TString title, TString description);
|
||||
virtual void ShowMessage(TString description);
|
||||
|
||||
virtual TCHAR* ConvertStringToFileSystemString(
|
||||
TCHAR* Source, bool &release);
|
||||
virtual TCHAR* ConvertFileSystemStringToString(
|
||||
TCHAR* Source, bool &release);
|
||||
|
||||
virtual TString GetPackageRootDirectory();
|
||||
virtual TString GetAppDataDirectory();
|
||||
virtual TString GetAppName();
|
||||
|
||||
virtual TString GetModuleFileName();
|
||||
|
||||
virtual TString GetBundledJavaLibraryFileName(TString RuntimePath);
|
||||
|
||||
virtual ISectionalPropertyContainer* GetConfigFile(TString FileName);
|
||||
|
||||
virtual bool IsMainThread();
|
||||
virtual TPlatformNumber GetMemorySize();
|
||||
};
|
||||
|
||||
#endif //LINUXPLATFORM_H
|
@ -65,7 +65,6 @@ public class MacAppImageBuilder extends AbstractAppImageBuilder {
|
||||
private static final ResourceBundle I18N = ResourceBundle.getBundle(
|
||||
"jdk.incubator.jpackage.internal.resources.MacResources");
|
||||
|
||||
private static final String LIBRARY_NAME = "libapplauncher.dylib";
|
||||
private static final String TEMPLATE_BUNDLE_ICON = "java.icns";
|
||||
private static final String OS_TYPE_CODE = "APPL";
|
||||
private static final String TEMPLATE_INFO_PLIST_LITE =
|
||||
@ -265,11 +264,9 @@ public class MacAppImageBuilder extends AbstractAppImageBuilder {
|
||||
|
||||
// create the main app launcher
|
||||
try (InputStream is_launcher =
|
||||
getResourceAsStream("jpackageapplauncher");
|
||||
InputStream is_lib = getResourceAsStream(LIBRARY_NAME)) {
|
||||
getResourceAsStream("jpackageapplauncher")) {
|
||||
// Copy executable and library to MacOS folder
|
||||
writeEntry(is_launcher, executable);
|
||||
writeEntry(is_lib, macOSDir.resolve(LIBRARY_NAME));
|
||||
}
|
||||
executable.toFile().setExecutable(true, false);
|
||||
// generate main app launcher config file
|
||||
|
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#include "AppLauncher.h"
|
||||
#include "FileUtils.h"
|
||||
#include "UnixSysInfo.h"
|
||||
#include "JvmLauncher.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
Jvm* jvmLauncher = 0;
|
||||
|
||||
void launchJvm() {
|
||||
// On Mac JLI_Launch() spawns a new thread that actually starts the JVM.
|
||||
// This new thread simply re-runs launcher's main() function with
|
||||
// arguments passed into JLI_Launch() call.
|
||||
// Jvm::launch() calls JLI_Launch() triggering thread spawning.
|
||||
jvmLauncher->launch();
|
||||
}
|
||||
|
||||
void initJvmLauncher() {
|
||||
const tstring launcherPath = SysInfo::getProcessModulePath();
|
||||
|
||||
// Launcher should be in "Contents/MacOS" subdirectory of app image.
|
||||
// However, don't strip "Contents" folder from launcher path, so that app
|
||||
// image root directory would be set to "Contents" subfolder of app image.
|
||||
const tstring appImageRoot = FileUtils::dirname(
|
||||
FileUtils::dirname(launcherPath));
|
||||
|
||||
// Create JVM launcher and save in global variable.
|
||||
jvmLauncher = AppLauncher()
|
||||
.setImageRoot(appImageRoot)
|
||||
.addJvmLibName(_T("Contents/Home/lib/libjli.dylib"))
|
||||
.setAppDir(FileUtils::mkpath() << appImageRoot << _T("app"))
|
||||
.setDefaultRuntimePath(FileUtils::mkpath() << appImageRoot
|
||||
<< _T("runtime"))
|
||||
.createJvmLauncher();
|
||||
|
||||
// Kick start JVM launching. The function wouldn't return!
|
||||
launchJvm();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
setlocale(LC_ALL, "en_US.utf8");
|
||||
if (jvmLauncher) {
|
||||
// This is the call from the thread spawned by JVM.
|
||||
// Skip initialization phase as we have done this already in the first
|
||||
// call of main().
|
||||
// Besides we should ignore main() arguments because these are the
|
||||
// arguments passed into JLI_Launch() call and not the arguments with
|
||||
// which the launcher was started.
|
||||
return AppLauncher::launch(std::nothrow, launchJvm);
|
||||
}
|
||||
|
||||
SysInfo::argc = argc;
|
||||
SysInfo::argv = argv;
|
||||
return AppLauncher::launch(std::nothrow, initJvmLauncher);
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#include <mach-o/dyld.h>
|
||||
#include "FileUtils.h"
|
||||
#include "ErrorHandling.h"
|
||||
|
||||
namespace SysInfo {
|
||||
|
||||
tstring getProcessModulePath() {
|
||||
std::vector<char> buffer;
|
||||
uint32_t bufferSize = 0;
|
||||
do {
|
||||
int len = _NSGetExecutablePath(buffer.data(), &bufferSize);
|
||||
if (len == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (len > 0) {
|
||||
JP_THROW(tstrings::any() << "_NSGetExecutablePath() failed");
|
||||
}
|
||||
|
||||
buffer.resize(bufferSize);
|
||||
} while (true);
|
||||
tstring reply = tstring(buffer.data(),
|
||||
buffer.size() - 1 /* don't count trailing '0' */);
|
||||
return FileUtils::toAbsolutePath(reply);
|
||||
}
|
||||
|
||||
} // end of namespace SysInfo
|
@ -1,81 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2019, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#include <dlfcn.h>
|
||||
#include <unistd.h>
|
||||
|
||||
typedef bool (*start_launcher)(int argc, char* argv[]);
|
||||
typedef void (*stop_launcher)();
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
#if !__has_feature(objc_arc)
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
#endif
|
||||
|
||||
int result = 1;
|
||||
|
||||
@try {
|
||||
setlocale(LC_ALL, "en_US.utf8");
|
||||
|
||||
NSBundle *mainBundle = [NSBundle mainBundle];
|
||||
NSString *mainBundlePath = [mainBundle bundlePath];
|
||||
NSString *libraryName = [mainBundlePath stringByAppendingPathComponent:@"Contents/MacOS/libapplauncher.dylib"];
|
||||
|
||||
void* library = dlopen([libraryName UTF8String], RTLD_LAZY);
|
||||
|
||||
if (library == NULL) {
|
||||
NSLog(@"%@ not found.\n", libraryName);
|
||||
}
|
||||
|
||||
if (library != NULL) {
|
||||
start_launcher start =
|
||||
(start_launcher)dlsym(library, "start_launcher");
|
||||
stop_launcher stop =
|
||||
(stop_launcher)dlsym(library, "stop_launcher");
|
||||
|
||||
if (start != NULL && stop != NULL) {
|
||||
if (start(argc, argv) == true) {
|
||||
result = 0;
|
||||
stop();
|
||||
}
|
||||
} else if (start == NULL) {
|
||||
NSLog(@"start_launcher not found in %@.\n", libraryName);
|
||||
} else {
|
||||
NSLog(@"stop_launcher not found in %@.\n", libraryName);
|
||||
}
|
||||
dlclose(library);
|
||||
}
|
||||
} @catch (NSException *exception) {
|
||||
NSLog(@"%@: %@", exception, [exception callStackSymbols]);
|
||||
result = 1;
|
||||
}
|
||||
|
||||
#if !__has_feature(objc_arc)
|
||||
[pool drain];
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
@ -1,71 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2019, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#ifndef MACPLATFORM_H
|
||||
#define MACPLATFORM_H
|
||||
|
||||
#include "Platform.h"
|
||||
#include "PosixPlatform.h"
|
||||
|
||||
class MacPlatform : virtual public Platform, PosixPlatform {
|
||||
private:
|
||||
bool UsePListForConfigFile();
|
||||
|
||||
protected:
|
||||
virtual TString getTmpDirString();
|
||||
|
||||
public:
|
||||
MacPlatform(void);
|
||||
virtual ~MacPlatform(void);
|
||||
|
||||
public:
|
||||
virtual void ShowMessage(TString title, TString description);
|
||||
virtual void ShowMessage(TString description);
|
||||
|
||||
virtual TCHAR* ConvertStringToFileSystemString(
|
||||
TCHAR* Source, bool &release);
|
||||
virtual TCHAR* ConvertFileSystemStringToString(
|
||||
TCHAR* Source, bool &release);
|
||||
|
||||
virtual TString GetPackageRootDirectory();
|
||||
virtual TString GetAppDataDirectory();
|
||||
virtual TString GetBundledJavaLibraryFileName(TString RuntimePath);
|
||||
virtual TString GetAppName();
|
||||
|
||||
TString GetPackageAppDirectory();
|
||||
TString GetPackageLauncherDirectory();
|
||||
TString GetPackageRuntimeBinDirectory();
|
||||
|
||||
virtual ISectionalPropertyContainer* GetConfigFile(TString FileName);
|
||||
virtual TString GetModuleFileName();
|
||||
|
||||
virtual bool IsMainThread();
|
||||
virtual TPlatformNumber GetMemorySize();
|
||||
|
||||
virtual std::map<TString, TString> GetKeys();
|
||||
};
|
||||
|
||||
|
||||
#endif // MACPLATFORM_H
|
@ -1,505 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2019, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#include "Platform.h"
|
||||
|
||||
#include "MacPlatform.h"
|
||||
#include "Helpers.h"
|
||||
#include "Package.h"
|
||||
#include "PropertyFile.h"
|
||||
#include "IniFile.h"
|
||||
|
||||
#include <sys/sysctl.h>
|
||||
#include <pthread.h>
|
||||
#include <vector>
|
||||
#include <signal.h>
|
||||
#include <mach-o/dyld.h>
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <AppKit/NSRunningApplication.h>
|
||||
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#include <CoreFoundation/CFString.h>
|
||||
|
||||
#ifdef __OBJC__
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#endif //__OBJC__
|
||||
|
||||
#define MAC_JPACKAGE_TMP_DIR \
|
||||
"/Library/Application Support/Java/JPackage/tmp"
|
||||
|
||||
NSString* StringToNSString(TString Value) {
|
||||
NSString* result = [NSString stringWithCString : Value.c_str()
|
||||
encoding : [NSString defaultCStringEncoding]];
|
||||
return result;
|
||||
}
|
||||
|
||||
FileSystemStringToString::FileSystemStringToString(const TCHAR* value) {
|
||||
bool release = false;
|
||||
PlatformString lvalue = PlatformString(value);
|
||||
Platform& platform = Platform::GetInstance();
|
||||
TCHAR* buffer = platform.ConvertFileSystemStringToString(lvalue, release);
|
||||
FData = buffer;
|
||||
|
||||
if (buffer != NULL && release == true) {
|
||||
delete[] buffer;
|
||||
}
|
||||
}
|
||||
|
||||
FileSystemStringToString::operator TString() {
|
||||
return FData;
|
||||
}
|
||||
|
||||
StringToFileSystemString::StringToFileSystemString(const TString &value) {
|
||||
FRelease = false;
|
||||
PlatformString lvalue = PlatformString(value);
|
||||
Platform& platform = Platform::GetInstance();
|
||||
FData = platform.ConvertStringToFileSystemString(lvalue, FRelease);
|
||||
}
|
||||
|
||||
StringToFileSystemString::~StringToFileSystemString() {
|
||||
if (FRelease == true) {
|
||||
delete[] FData;
|
||||
}
|
||||
}
|
||||
|
||||
StringToFileSystemString::operator TCHAR* () {
|
||||
return FData;
|
||||
}
|
||||
|
||||
MacPlatform::MacPlatform(void) : Platform(), PosixPlatform() {
|
||||
}
|
||||
|
||||
MacPlatform::~MacPlatform(void) {
|
||||
}
|
||||
|
||||
TString MacPlatform::GetPackageAppDirectory() {
|
||||
return FilePath::IncludeTrailingSeparator(
|
||||
GetPackageRootDirectory()) + _T("app");
|
||||
}
|
||||
|
||||
TString MacPlatform::GetPackageLauncherDirectory() {
|
||||
return FilePath::IncludeTrailingSeparator(
|
||||
GetPackageRootDirectory()) + _T("MacOS");
|
||||
}
|
||||
|
||||
TString MacPlatform::GetPackageRuntimeBinDirectory() {
|
||||
return FilePath::IncludeTrailingSeparator(GetPackageRootDirectory()) +
|
||||
_T("runtime/Contents/Home/bin");
|
||||
}
|
||||
|
||||
bool MacPlatform::UsePListForConfigFile() {
|
||||
return FilePath::FileExists(GetConfigFileName()) == false;
|
||||
}
|
||||
|
||||
void MacPlatform::ShowMessage(TString Title, TString Description) {
|
||||
NSString *ltitle = StringToNSString(Title);
|
||||
NSString *ldescription = StringToNSString(Description);
|
||||
|
||||
NSLog(@"%@:%@", ltitle, ldescription);
|
||||
}
|
||||
|
||||
void MacPlatform::ShowMessage(TString Description) {
|
||||
TString appname = GetModuleFileName();
|
||||
appname = FilePath::ExtractFileName(appname);
|
||||
ShowMessage(appname, Description);
|
||||
}
|
||||
|
||||
TString MacPlatform::getTmpDirString() {
|
||||
return TString(MAC_JPACKAGE_TMP_DIR);
|
||||
}
|
||||
|
||||
TCHAR* MacPlatform::ConvertStringToFileSystemString(TCHAR* Source,
|
||||
bool &release) {
|
||||
TCHAR* result = NULL;
|
||||
release = false;
|
||||
CFStringRef StringRef = CFStringCreateWithCString(kCFAllocatorDefault,
|
||||
Source, kCFStringEncodingUTF8);
|
||||
|
||||
if (StringRef != NULL) {
|
||||
@ try {
|
||||
CFIndex length =
|
||||
CFStringGetMaximumSizeOfFileSystemRepresentation(StringRef);
|
||||
result = new char[length + 1];
|
||||
if (result != NULL) {
|
||||
if (CFStringGetFileSystemRepresentation(StringRef,
|
||||
result, length)) {
|
||||
release = true;
|
||||
} else {
|
||||
delete[] result;
|
||||
result = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
@finally
|
||||
{
|
||||
CFRelease(StringRef);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
TCHAR* MacPlatform::ConvertFileSystemStringToString(TCHAR* Source,
|
||||
bool &release) {
|
||||
TCHAR* result = NULL;
|
||||
release = false;
|
||||
CFStringRef StringRef = CFStringCreateWithFileSystemRepresentation(
|
||||
kCFAllocatorDefault, Source);
|
||||
|
||||
if (StringRef != NULL) {
|
||||
@ try {
|
||||
CFIndex length = CFStringGetLength(StringRef);
|
||||
|
||||
if (length > 0) {
|
||||
CFIndex maxSize = CFStringGetMaximumSizeForEncoding(
|
||||
length, kCFStringEncodingUTF8);
|
||||
|
||||
result = new char[maxSize + 1];
|
||||
if (result != NULL) {
|
||||
if (CFStringGetCString(StringRef, result, maxSize,
|
||||
kCFStringEncodingUTF8) == true) {
|
||||
release = true;
|
||||
} else {
|
||||
delete[] result;
|
||||
result = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@finally
|
||||
{
|
||||
CFRelease(StringRef);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
TString MacPlatform::GetPackageRootDirectory() {
|
||||
NSBundle *mainBundle = [NSBundle mainBundle];
|
||||
NSString *mainBundlePath = [mainBundle bundlePath];
|
||||
NSString *contentsPath =
|
||||
[mainBundlePath stringByAppendingString : @"/Contents"];
|
||||
TString result = [contentsPath UTF8String];
|
||||
return result;
|
||||
}
|
||||
|
||||
TString MacPlatform::GetAppDataDirectory() {
|
||||
TString result;
|
||||
NSArray *paths = NSSearchPathForDirectoriesInDomains(
|
||||
NSApplicationSupportDirectory, NSUserDomainMask, YES);
|
||||
NSString *applicationSupportDirectory = [paths firstObject];
|
||||
result = [applicationSupportDirectory UTF8String];
|
||||
return result;
|
||||
}
|
||||
|
||||
TString MacPlatform::GetBundledJavaLibraryFileName(TString RuntimePath) {
|
||||
TString result;
|
||||
|
||||
// first try lib/, then lib/jli
|
||||
result = FilePath::IncludeTrailingSeparator(RuntimePath) +
|
||||
_T("Contents/Home/lib/libjli.dylib");
|
||||
|
||||
if (FilePath::FileExists(result) == false) {
|
||||
result = FilePath::IncludeTrailingSeparator(RuntimePath) +
|
||||
_T("Contents/Home/lib/jli/libjli.dylib");
|
||||
|
||||
if (FilePath::FileExists(result) == false) {
|
||||
// cannot find
|
||||
NSLog(@"Cannot find libjli.dysym!");
|
||||
result = _T("");
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
TString MacPlatform::GetAppName() {
|
||||
NSString *appName = [[NSProcessInfo processInfo] processName];
|
||||
TString result = [appName UTF8String];
|
||||
return result;
|
||||
}
|
||||
|
||||
void PosixProcess::Cleanup() {
|
||||
if (FOutputHandle != 0) {
|
||||
close(FOutputHandle);
|
||||
FOutputHandle = 0;
|
||||
}
|
||||
|
||||
if (FInputHandle != 0) {
|
||||
close(FInputHandle);
|
||||
FInputHandle = 0;
|
||||
}
|
||||
|
||||
sigaction(SIGINT, &savintr, (struct sigaction *) 0);
|
||||
sigaction(SIGQUIT, &savequit, (struct sigaction *) 0);
|
||||
sigprocmask(SIG_SETMASK, &saveblock, (sigset_t *) 0);
|
||||
}
|
||||
|
||||
#define PIPE_READ 0
|
||||
#define PIPE_WRITE 1
|
||||
|
||||
bool PosixProcess::Execute(const TString Application,
|
||||
const std::vector<TString> Arguments, bool AWait) {
|
||||
bool result = false;
|
||||
|
||||
if (FRunning == false) {
|
||||
FRunning = true;
|
||||
|
||||
int handles[2];
|
||||
|
||||
if (pipe(handles) == -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
struct sigaction sa;
|
||||
sa.sa_handler = SIG_IGN;
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sa.sa_flags = 0;
|
||||
sigemptyset(&savintr.sa_mask);
|
||||
sigemptyset(&savequit.sa_mask);
|
||||
sigaction(SIGINT, &sa, &savintr);
|
||||
sigaction(SIGQUIT, &sa, &savequit);
|
||||
sigaddset(&sa.sa_mask, SIGCHLD);
|
||||
sigprocmask(SIG_BLOCK, &sa.sa_mask, &saveblock);
|
||||
|
||||
FChildPID = fork();
|
||||
|
||||
// PID returned by vfork is 0 for the child process and the
|
||||
// PID of the child process for the parent.
|
||||
if (FChildPID == -1) {
|
||||
// Error
|
||||
TString message = PlatformString::Format(
|
||||
_T("Error: Unable to create process %s"),
|
||||
Application.data());
|
||||
throw Exception(message);
|
||||
} else if (FChildPID == 0) {
|
||||
Cleanup();
|
||||
TString command = Application;
|
||||
|
||||
for (std::vector<TString>::const_iterator iterator =
|
||||
Arguments.begin(); iterator != Arguments.end();
|
||||
iterator++) {
|
||||
command += TString(_T(" ")) + *iterator;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
printf("%s\n", command.data());
|
||||
#endif // DEBUG
|
||||
|
||||
dup2(handles[PIPE_READ], STDIN_FILENO);
|
||||
dup2(handles[PIPE_WRITE], STDOUT_FILENO);
|
||||
|
||||
close(handles[PIPE_READ]);
|
||||
close(handles[PIPE_WRITE]);
|
||||
|
||||
execl("/bin/sh", "sh", "-c", command.data(), (char *) 0);
|
||||
|
||||
_exit(127);
|
||||
} else {
|
||||
FOutputHandle = handles[PIPE_READ];
|
||||
FInputHandle = handles[PIPE_WRITE];
|
||||
|
||||
if (AWait == true) {
|
||||
ReadOutput();
|
||||
Wait();
|
||||
Cleanup();
|
||||
FRunning = false;
|
||||
result = true;
|
||||
} else {
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void AppendPListArrayToIniFile(NSDictionary *infoDictionary,
|
||||
IniFile *result, TString Section) {
|
||||
NSString *sectionKey =
|
||||
[NSString stringWithUTF8String : PlatformString(Section).toMultibyte()];
|
||||
NSDictionary *array = [infoDictionary objectForKey : sectionKey];
|
||||
|
||||
for (id option in array) {
|
||||
if ([option isKindOfClass : [NSString class]]) {
|
||||
TString arg = [option UTF8String];
|
||||
|
||||
TString name;
|
||||
TString value;
|
||||
|
||||
if (Helpers::SplitOptionIntoNameValue(arg, name, value) == true) {
|
||||
result->Append(Section, name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AppendPListDictionaryToIniFile(NSDictionary *infoDictionary,
|
||||
IniFile *result, TString Section, bool FollowSection = true) {
|
||||
NSDictionary *dictionary = NULL;
|
||||
|
||||
if (FollowSection == true) {
|
||||
NSString *sectionKey = [NSString stringWithUTF8String : PlatformString(
|
||||
Section).toMultibyte()];
|
||||
dictionary = [infoDictionary objectForKey : sectionKey];
|
||||
} else {
|
||||
dictionary = infoDictionary;
|
||||
}
|
||||
|
||||
for (id key in dictionary) {
|
||||
id option = [dictionary valueForKey : key];
|
||||
|
||||
if ([key isKindOfClass : [NSString class]] &&
|
||||
[option isKindOfClass : [NSString class]]) {
|
||||
TString name = [key UTF8String];
|
||||
TString value = [option UTF8String];
|
||||
result->Append(Section, name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Convert parts of the info.plist to the INI format the rest of the jpackage
|
||||
// uses unless a jpackage config file exists.
|
||||
ISectionalPropertyContainer* MacPlatform::GetConfigFile(TString FileName) {
|
||||
IniFile* result = new IniFile();
|
||||
if (result == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (UsePListForConfigFile() == false) {
|
||||
result->LoadFromFile(FileName);
|
||||
} else {
|
||||
NSBundle *mainBundle = [NSBundle mainBundle];
|
||||
NSDictionary *infoDictionary = [mainBundle infoDictionary];
|
||||
std::map<TString, TString> keys = GetKeys();
|
||||
|
||||
// JPackage options.
|
||||
AppendPListDictionaryToIniFile(infoDictionary, result,
|
||||
keys[CONFIG_SECTION_APPLICATION], false);
|
||||
|
||||
// jvmargs
|
||||
AppendPListArrayToIniFile(infoDictionary, result,
|
||||
keys[CONFIG_SECTION_JAVAOPTIONS]);
|
||||
|
||||
// Generate AppCDS Cache
|
||||
AppendPListDictionaryToIniFile(infoDictionary, result,
|
||||
keys[CONFIG_SECTION_APPCDSJAVAOPTIONS]);
|
||||
AppendPListDictionaryToIniFile(infoDictionary, result,
|
||||
keys[CONFIG_SECTION_APPCDSGENERATECACHEJAVAOPTIONS]);
|
||||
|
||||
// args
|
||||
AppendPListArrayToIniFile(infoDictionary, result,
|
||||
keys[CONFIG_SECTION_ARGOPTIONS]);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
TString GetModuleFileNameOSX() {
|
||||
Dl_info module_info;
|
||||
if (dladdr(reinterpret_cast<void*> (GetModuleFileNameOSX),
|
||||
&module_info) == 0) {
|
||||
// Failed to find the symbol we asked for.
|
||||
return std::string();
|
||||
}
|
||||
return TString(module_info.dli_fname);
|
||||
}
|
||||
|
||||
TString MacPlatform::GetModuleFileName() {
|
||||
TString result;
|
||||
DynamicBuffer<TCHAR> buffer(MAX_PATH);
|
||||
uint32_t size = buffer.GetSize();
|
||||
|
||||
if (_NSGetExecutablePath(buffer.GetData(), &size) == 0) {
|
||||
result = FileSystemStringToString(buffer.GetData());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool MacPlatform::IsMainThread() {
|
||||
bool result = (pthread_main_np() == 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
TPlatformNumber MacPlatform::GetMemorySize() {
|
||||
unsigned long long memory = [[NSProcessInfo processInfo] physicalMemory];
|
||||
|
||||
// Convert from bytes to megabytes.
|
||||
TPlatformNumber result = memory / 1048576;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::map<TString, TString> MacPlatform::GetKeys() {
|
||||
std::map<TString, TString> keys;
|
||||
|
||||
if (UsePListForConfigFile() == false) {
|
||||
return Platform::GetKeys();
|
||||
} else {
|
||||
keys.insert(std::map<TString, TString>::value_type(CONFIG_VERSION,
|
||||
_T("app.version")));
|
||||
keys.insert(std::map<TString, TString>::value_type(CONFIG_MAINJAR_KEY,
|
||||
_T("JavaMainJarName")));
|
||||
keys.insert(std::map<TString,
|
||||
TString>::value_type(CONFIG_MAINMODULE_KEY,
|
||||
_T("JavaMainModuleName")));
|
||||
keys.insert(std::map<TString, TString>::value_type(
|
||||
CONFIG_MAINCLASSNAME_KEY, _T("JavaMainClassName")));
|
||||
keys.insert(std::map<TString, TString>::value_type(
|
||||
CONFIG_CLASSPATH_KEY, _T("JavaAppClasspath")));
|
||||
keys.insert(std::map<TString, TString>::value_type(APP_NAME_KEY,
|
||||
_T("CFBundleName")));
|
||||
keys.insert(std::map<TString, TString>::value_type(JAVA_RUNTIME_KEY,
|
||||
_T("JavaRuntime")));
|
||||
keys.insert(std::map<TString,
|
||||
TString>::value_type(JPACKAGE_APP_DATA_DIR,
|
||||
_T("CFBundleIdentifier")));
|
||||
|
||||
keys.insert(std::map<TString, TString>::value_type(CONFIG_SPLASH_KEY,
|
||||
_T("app.splash")));
|
||||
keys.insert(std::map<TString, TString>::value_type(CONFIG_APP_MEMORY,
|
||||
_T("app.memory")));
|
||||
keys.insert(std::map<TString, TString>::value_type(CONFIG_APP_DEBUG,
|
||||
_T("app.debug")));
|
||||
keys.insert(std::map<TString, TString>::value_type(
|
||||
CONFIG_APPLICATION_INSTANCE, _T("app.application.instance")));
|
||||
|
||||
keys.insert(std::map<TString, TString>::value_type(
|
||||
CONFIG_SECTION_APPLICATION, _T("Application")));
|
||||
keys.insert(std::map<TString, TString>::value_type(
|
||||
CONFIG_SECTION_JAVAOPTIONS, _T("JavaOptions")));
|
||||
keys.insert(std::map<TString, TString>::value_type(
|
||||
CONFIG_SECTION_APPCDSJAVAOPTIONS, _T("AppCDSJavaOptions")));
|
||||
keys.insert(std::map<TString, TString>::value_type(
|
||||
CONFIG_SECTION_APPCDSGENERATECACHEJAVAOPTIONS,
|
||||
_T("AppCDSGenerateCacheJavaOptions")));
|
||||
keys.insert(std::map<TString, TString>::value_type(
|
||||
CONFIG_SECTION_ARGOPTIONS, _T("ArgOptions")));
|
||||
}
|
||||
|
||||
return keys;
|
||||
}
|
@ -1,112 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#ifndef PLATFORM_DEFS_H
|
||||
#define PLATFORM_DEFS_H
|
||||
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <dlfcn.h>
|
||||
#include <libgen.h>
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
#ifndef MAC
|
||||
#define MAC
|
||||
#endif
|
||||
|
||||
#define _T(x) x
|
||||
|
||||
typedef char TCHAR;
|
||||
typedef std::string TString;
|
||||
#define StringLength strlen
|
||||
|
||||
typedef unsigned long DWORD;
|
||||
|
||||
#define TRAILING_PATHSEPARATOR '/'
|
||||
#define BAD_TRAILING_PATHSEPARATOR '\\'
|
||||
#define PATH_SEPARATOR ':'
|
||||
#define BAD_PATH_SEPARATOR ';'
|
||||
#define MAX_PATH 1000
|
||||
|
||||
typedef long TPlatformNumber;
|
||||
typedef pid_t TProcessID;
|
||||
|
||||
#define HMODULE void*
|
||||
|
||||
typedef void* Module;
|
||||
typedef void* Procedure;
|
||||
|
||||
|
||||
// StringToFileSystemString is a stack object. It's usage is
|
||||
// simply inline to convert a
|
||||
// TString to a file system string. Example:
|
||||
//
|
||||
// return dlopen(StringToFileSystemString(FileName), RTLD_LAZY);
|
||||
//
|
||||
class StringToFileSystemString {
|
||||
// Prohibit Heap-Based StringToFileSystemString
|
||||
private:
|
||||
static void *operator new(size_t size);
|
||||
static void operator delete(void *ptr);
|
||||
|
||||
private:
|
||||
TCHAR* FData;
|
||||
bool FRelease;
|
||||
|
||||
public:
|
||||
StringToFileSystemString(const TString &value);
|
||||
~StringToFileSystemString();
|
||||
|
||||
operator TCHAR* ();
|
||||
};
|
||||
|
||||
|
||||
// FileSystemStringToString is a stack object. It's usage is
|
||||
// simply inline to convert a
|
||||
// file system string to a TString. Example:
|
||||
//
|
||||
// DynamicBuffer<TCHAR> buffer(MAX_PATH);
|
||||
// if (readlink("/proc/self/exe", buffer.GetData(), MAX_PATH) != -1)
|
||||
// result = FileSystemStringToString(buffer.GetData());
|
||||
//
|
||||
class FileSystemStringToString {
|
||||
// Prohibit Heap-Based FileSystemStringToString
|
||||
private:
|
||||
static void *operator new(size_t size);
|
||||
static void operator delete(void *ptr);
|
||||
|
||||
private:
|
||||
TString FData;
|
||||
|
||||
public:
|
||||
FileSystemStringToString(const TCHAR* value);
|
||||
|
||||
operator TString ();
|
||||
};
|
||||
|
||||
#endif // PLATFORM_DEFS_H
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 2020, 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
|
||||
@ -120,12 +120,11 @@ public abstract class AbstractAppImageBuilder {
|
||||
// legacy way and the main class string must be
|
||||
// of the format com/foo/Main
|
||||
if (mainJar != null) {
|
||||
out.println("app.mainjar=" + getCfgAppDir()
|
||||
out.println("app.classpath=" + getCfgAppDir()
|
||||
+ mainJar.toPath().getFileName().toString());
|
||||
}
|
||||
if (mainClass != null) {
|
||||
out.println("app.mainclass="
|
||||
+ mainClass.replace("\\", "/"));
|
||||
out.println("app.mainclass=" + mainClass);
|
||||
}
|
||||
}
|
||||
|
||||
@ -133,26 +132,20 @@ public abstract class AbstractAppImageBuilder {
|
||||
out.println("[JavaOptions]");
|
||||
List<String> jvmargs = JAVA_OPTIONS.fetchFrom(params);
|
||||
for (String arg : jvmargs) {
|
||||
out.println(arg);
|
||||
out.println("java-options=" + arg);
|
||||
}
|
||||
Path modsDir = getAppModsDir();
|
||||
|
||||
if (modsDir != null && modsDir.toFile().exists()) {
|
||||
out.println("--module-path");
|
||||
out.println(getCfgAppDir().replace("\\","/") + "mods");
|
||||
out.println("java-options=" + "--module-path");
|
||||
out.println("java-options=" + getCfgAppDir().replace("\\","/") + "mods");
|
||||
}
|
||||
|
||||
out.println();
|
||||
out.println("[ArgOptions]");
|
||||
List<String> args = ARGUMENTS.fetchFrom(params);
|
||||
for (String arg : args) {
|
||||
if (arg.endsWith("=") &&
|
||||
(arg.indexOf("=") == arg.lastIndexOf("="))) {
|
||||
out.print(arg.substring(0, arg.length() - 1));
|
||||
out.println("\\=");
|
||||
} else {
|
||||
out.println(arg);
|
||||
}
|
||||
out.println("arguments=" + arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,283 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include "AppLauncher.h"
|
||||
#include "JvmLauncher.h"
|
||||
#include "CfgFile.h"
|
||||
#include "Log.h"
|
||||
#include "Dll.h"
|
||||
#include "Toolbox.h"
|
||||
#include "SysInfo.h"
|
||||
#include "FileUtils.h"
|
||||
|
||||
|
||||
AppLauncher::AppLauncher() {
|
||||
launcherPath = SysInfo::getProcessModulePath();
|
||||
args = SysInfo::getCommandArgs();
|
||||
}
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
struct find_jvmlib {
|
||||
find_jvmlib(const tstring& v): runtimePath(v) {
|
||||
}
|
||||
|
||||
bool operator () (const tstring& jvmLibName) const {
|
||||
const tstring path = FileUtils::mkpath() << runtimePath << jvmLibName;
|
||||
return FileUtils::isFileExists(path);
|
||||
}
|
||||
|
||||
private:
|
||||
const tstring& runtimePath;
|
||||
};
|
||||
|
||||
tstring findJvmLib(const CfgFile& cfgFile, const tstring& defaultRuntimePath,
|
||||
const tstring_array& jvmLibNames) {
|
||||
const CfgFile::Properties& appOptions = cfgFile.getProperties(
|
||||
SectionName::Application);
|
||||
|
||||
const CfgFile::Properties::const_iterator runtimePathProp = appOptions.find(
|
||||
PropertyName::runtime);
|
||||
tstring runtimePath;
|
||||
if (runtimePathProp != appOptions.end()) {
|
||||
runtimePath = CfgFile::asString(*runtimePathProp);
|
||||
} else {
|
||||
runtimePath = defaultRuntimePath;
|
||||
LOG_TRACE(tstrings::any()
|
||||
<< "Property \"" << PropertyName::runtime.name()
|
||||
<< "\" not found in \"" << SectionName::Application.name()
|
||||
<< "\" section of launcher config file."
|
||||
<< " Using Java runtime from \""
|
||||
<< runtimePath << "\" directory");
|
||||
}
|
||||
|
||||
const tstring_array::const_iterator jvmLibNameEntry = std::find_if(
|
||||
jvmLibNames.begin(),
|
||||
jvmLibNames.end(),
|
||||
find_jvmlib(runtimePath));
|
||||
|
||||
if (jvmLibNameEntry == jvmLibNames.end()) {
|
||||
JP_THROW(tstrings::any() << "Failed to find JVM in \""
|
||||
<< runtimePath
|
||||
<< "\" directory.");
|
||||
}
|
||||
|
||||
return FileUtils::mkpath() << runtimePath << *jvmLibNameEntry;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
Jvm* AppLauncher::createJvmLauncher() const {
|
||||
const tstring cfgFilePath = FileUtils::mkpath()
|
||||
<< appDirPath
|
||||
<< FileUtils::basename(FileUtils::replaceSuffix(
|
||||
launcherPath, _T(".cfg")));
|
||||
|
||||
LOG_TRACE(tstrings::any() << "Launcher config file path: \""
|
||||
<< cfgFilePath << "\"");
|
||||
|
||||
CfgFile::Macros macros;
|
||||
macros[_T("$APPDIR")] = appDirPath;
|
||||
macros[_T("$BINDIR")] = FileUtils::dirname(launcherPath);
|
||||
macros[_T("$ROOTDIR")] = imageRoot;
|
||||
|
||||
CfgFile cfgFile = CfgFile::load(cfgFilePath).expandMacros(macros);
|
||||
|
||||
if (!args.empty()) {
|
||||
// Override default launcher arguments.
|
||||
cfgFile.setPropertyValue(SectionName::ArgOptions,
|
||||
PropertyName::arguments, args);
|
||||
}
|
||||
|
||||
std::unique_ptr<Jvm> jvm(new Jvm());
|
||||
|
||||
(*jvm)
|
||||
.setPath(findJvmLib(cfgFile, defaultRuntimePath, jvmLibNames))
|
||||
.addArgument(launcherPath)
|
||||
.initFromConfigFile(cfgFile);
|
||||
|
||||
return jvm.release();
|
||||
}
|
||||
|
||||
|
||||
void AppLauncher::launch() const {
|
||||
std::unique_ptr<Jvm>(createJvmLauncher())->launch();
|
||||
}
|
||||
|
||||
|
||||
namespace {
|
||||
const std::string* theLastErrorMsg = 0;
|
||||
|
||||
NopLogAppender nopLogAppender;
|
||||
|
||||
class StandardLogAppender : public LogAppender {
|
||||
public:
|
||||
virtual void append(const LogEvent& v) {
|
||||
std::cerr << "[" << v.logLevel << "] "
|
||||
<< v.fileName
|
||||
<< ":" << v.lineNum
|
||||
<< ": " << v.message
|
||||
<< std::endl;
|
||||
}
|
||||
} standardLogAppender;
|
||||
|
||||
class LastErrorLogAppender : public LogAppender {
|
||||
public:
|
||||
virtual void append(const LogEvent& v) {
|
||||
std::cerr << AppLauncher::lastErrorMsg() << std::endl;
|
||||
}
|
||||
} lastErrorLogAppender;
|
||||
} // namespace
|
||||
|
||||
LogAppender& AppLauncher::defaultLastErrorLogAppender() {
|
||||
return lastErrorLogAppender;
|
||||
}
|
||||
|
||||
|
||||
std::string AppLauncher::lastErrorMsg() {
|
||||
if (theLastErrorMsg) {
|
||||
return *theLastErrorMsg;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
bool AppLauncher::isWithLogging() {
|
||||
// If JPACKAGE_DEBUG environment variable is set to "true"
|
||||
// logging is enabled.
|
||||
return SysInfo::getEnvVariable(
|
||||
std::nothrow, _T("JPACKAGE_DEBUG")) == _T("true");
|
||||
}
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
class ResetLastErrorMsgAtEndOfScope {
|
||||
public:
|
||||
~ResetLastErrorMsgAtEndOfScope() {
|
||||
JP_NO_THROW(theLastErrorMsg = 0);
|
||||
}
|
||||
};
|
||||
|
||||
class SetLoggerAtEndOfScope {
|
||||
public:
|
||||
SetLoggerAtEndOfScope(
|
||||
std::unique_ptr<WithExtraLogAppender>& withLogAppender,
|
||||
LogAppender* lastErrorLogAppender):
|
||||
withLogAppender(withLogAppender),
|
||||
lastErrorLogAppender(lastErrorLogAppender) {
|
||||
}
|
||||
|
||||
~SetLoggerAtEndOfScope() {
|
||||
JP_TRY;
|
||||
std::unique_ptr<WithExtraLogAppender> other(
|
||||
new WithExtraLogAppender(*lastErrorLogAppender));
|
||||
withLogAppender.swap(other);
|
||||
JP_CATCH_ALL;
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<WithExtraLogAppender>& withLogAppender;
|
||||
LogAppender* lastErrorLogAppender;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
int AppLauncher::launch(const std::nothrow_t&,
|
||||
LauncherFunc func, LogAppender* lastErrorLogAppender) {
|
||||
if (isWithLogging()) {
|
||||
Logger::defaultLogger().setAppender(standardLogAppender);
|
||||
} else {
|
||||
Logger::defaultLogger().setAppender(nopLogAppender);
|
||||
}
|
||||
|
||||
LOG_TRACE_FUNCTION();
|
||||
|
||||
if (!lastErrorLogAppender) {
|
||||
lastErrorLogAppender = &defaultLastErrorLogAppender();
|
||||
}
|
||||
std::unique_ptr<WithExtraLogAppender> withLogAppender;
|
||||
std::string errorMsg;
|
||||
const ResetLastErrorMsgAtEndOfScope resetLastErrorMsg;
|
||||
|
||||
JP_TRY;
|
||||
|
||||
// This will temporary change log appenders of the default logger
|
||||
// to save log messages in the default and additional log appenders.
|
||||
// Log appenders config of the default logger will be restored to
|
||||
// the original state at function exit automatically.
|
||||
const SetLoggerAtEndOfScope setLogger(withLogAppender, lastErrorLogAppender);
|
||||
func();
|
||||
return 0;
|
||||
|
||||
// The point of all these redefines is to save the last raw error message in
|
||||
// 'AppLauncher::theLastErrorMsg' variable.
|
||||
// By default error messages are saved in exception instances with the details
|
||||
// of error origin (source file, function name, line number).
|
||||
// We don't want these details in user error messages. However we still want to
|
||||
// save full information about the last error in the default log appender.
|
||||
#undef JP_HANDLE_ERROR
|
||||
#undef JP_HANDLE_UNKNOWN_ERROR
|
||||
#undef JP_CATCH_EXCEPTIONS
|
||||
#define JP_HANDLE_ERROR(e) \
|
||||
do { \
|
||||
errorMsg = (tstrings::any() << e.what()).str(); \
|
||||
theLastErrorMsg = &errorMsg; \
|
||||
reportError(JP_SOURCE_CODE_POS, e); \
|
||||
} while(0)
|
||||
#define JP_HANDLE_UNKNOWN_ERROR \
|
||||
do { \
|
||||
errorMsg = "Unknown error"; \
|
||||
theLastErrorMsg = &errorMsg; \
|
||||
reportUnknownError(JP_SOURCE_CODE_POS); \
|
||||
} while(0)
|
||||
#define JP_CATCH_EXCEPTIONS \
|
||||
catch (const JpErrorBase& e) { \
|
||||
errorMsg = (tstrings::any() << e.rawMessage()).str(); \
|
||||
theLastErrorMsg = &errorMsg; \
|
||||
try { \
|
||||
throw; \
|
||||
} catch (const std::runtime_error& e) { \
|
||||
reportError(JP_SOURCE_CODE_POS, e); \
|
||||
} \
|
||||
} catch (const std::runtime_error& e) { \
|
||||
errorMsg = lastCRTError(); \
|
||||
theLastErrorMsg = &errorMsg; \
|
||||
reportError(JP_SOURCE_CODE_POS, e); \
|
||||
} \
|
||||
JP_CATCH_UNKNOWN_EXCEPTION
|
||||
|
||||
JP_CATCH_ALL;
|
||||
|
||||
#undef JP_HANDLE_ERROR
|
||||
#undef JP_HANDLE_UNKNOWN_ERROR
|
||||
#undef JP_CATCH_EXCEPTIONS
|
||||
#define JP_HANDLE_ERROR(e) JP_REPORT_ERROR(e)
|
||||
#define JP_HANDLE_UNKNOWN_ERROR JP_REPORT_UNKNOWN_ERROR
|
||||
#define JP_CATCH_EXCEPTIONS JP_DEFAULT_CATCH_EXCEPTIONS
|
||||
|
||||
return 1;
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef AppLauncher_h
|
||||
#define AppLauncher_h
|
||||
|
||||
#include "tstrings.h"
|
||||
|
||||
class Jvm;
|
||||
class LogAppender;
|
||||
|
||||
class AppLauncher {
|
||||
public:
|
||||
AppLauncher();
|
||||
|
||||
AppLauncher& setImageRoot(const tstring& v) {
|
||||
imageRoot = v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
AppLauncher& setDefaultRuntimePath(const tstring& v) {
|
||||
defaultRuntimePath = v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
AppLauncher& setAppDir(const tstring& v) {
|
||||
appDirPath = v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
AppLauncher& addJvmLibName(const tstring& v) {
|
||||
jvmLibNames.push_back(v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Jvm* createJvmLauncher() const;
|
||||
|
||||
void launch() const;
|
||||
|
||||
static LogAppender& defaultLastErrorLogAppender();
|
||||
|
||||
static bool isWithLogging();
|
||||
|
||||
typedef void (*LauncherFunc) ();
|
||||
|
||||
static int launch(const std::nothrow_t&, LauncherFunc func,
|
||||
LogAppender* lastErrorLogAppender = 0);
|
||||
|
||||
static std::string lastErrorMsg();
|
||||
|
||||
private:
|
||||
tstring_array args;
|
||||
tstring launcherPath;
|
||||
tstring defaultRuntimePath;
|
||||
tstring appDirPath;
|
||||
tstring imageRoot;
|
||||
tstring_array jvmLibNames;
|
||||
};
|
||||
|
||||
#endif // AppLauncher_h
|
295
src/jdk.incubator.jpackage/share/native/applauncher/CfgFile.cpp
Normal file
295
src/jdk.incubator.jpackage/share/native/applauncher/CfgFile.cpp
Normal file
@ -0,0 +1,295 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#include "kludge_c++11.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <algorithm>
|
||||
#include "CfgFile.h"
|
||||
#include "Log.h"
|
||||
#include "Toolbox.h"
|
||||
#include "FileUtils.h"
|
||||
#include "ErrorHandling.h"
|
||||
|
||||
|
||||
const CfgFile::Properties& CfgFile::getProperties(
|
||||
const SectionName& sectionName) const {
|
||||
const PropertyMap::const_iterator entry = data.find(sectionName);
|
||||
if (entry != data.end()) {
|
||||
return entry->second;
|
||||
}
|
||||
return empty;
|
||||
}
|
||||
|
||||
|
||||
CfgFile& CfgFile::setPropertyValue(const SectionName& sectionName,
|
||||
const PropertyName& name, const tstring_array& value) {
|
||||
PropertyMap::iterator entry = data.find(sectionName);
|
||||
if (entry != data.end()) {
|
||||
entry->second[name] = value;
|
||||
} else {
|
||||
Properties props;
|
||||
props[name] = value;
|
||||
data[sectionName] = props;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
tstring expandMacros(const tstring& str, const CfgFile::Macros& macros) {
|
||||
tstring reply = str;
|
||||
CfgFile::Macros::const_iterator it = macros.begin();
|
||||
const CfgFile::Macros::const_iterator end = macros.end();
|
||||
for (; it != end; ++it) {
|
||||
reply = tstrings::replace(reply, it->first, it->second);
|
||||
}
|
||||
return reply;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
CfgFile CfgFile::expandMacros(const Macros& macros) const {
|
||||
CfgFile copyCfgFile = *this;
|
||||
|
||||
PropertyMap::iterator mapIt = copyCfgFile.data.begin();
|
||||
const PropertyMap::iterator mapEnd = copyCfgFile.data.end();
|
||||
for (; mapIt != mapEnd; ++mapIt) {
|
||||
Properties::iterator propertyIt = mapIt->second.begin();
|
||||
const Properties::iterator propertyEnd = mapIt->second.end();
|
||||
for (; propertyIt != propertyEnd; ++propertyIt) {
|
||||
tstring_array::iterator strIt = propertyIt->second.begin();
|
||||
const tstring_array::iterator strEnd = propertyIt->second.end();
|
||||
for (; strIt != strEnd; ++strIt) {
|
||||
tstring newValue;
|
||||
while ((newValue = ::expandMacros(*strIt, macros)) != *strIt) {
|
||||
strIt->swap(newValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return copyCfgFile;
|
||||
}
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
const CfgFile::SectionName* getSectionName(const tstring& str);
|
||||
const CfgFile::PropertyName* getPropertyName(const tstring& str);
|
||||
|
||||
const CfgFile::SectionName UnknownSection = CfgFile::SectionName(_T(""));
|
||||
|
||||
|
||||
class PurgeSection {
|
||||
public:
|
||||
PurgeSection(CfgFile::SectionName& sectionName,
|
||||
CfgFile::Properties& sectionData,
|
||||
CfgFile::PropertyMap& cfgFileData):
|
||||
sectionName(sectionName), sectionData(sectionData),
|
||||
cfgFileData(cfgFileData) {
|
||||
}
|
||||
|
||||
void operator ()() {
|
||||
if (sectionName != UnknownSection && !sectionData.empty()) {
|
||||
std::swap(cfgFileData[sectionName], sectionData);
|
||||
sectionName = UnknownSection;
|
||||
sectionData.clear();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
CfgFile::SectionName& sectionName;
|
||||
CfgFile::Properties& sectionData;
|
||||
CfgFile::PropertyMap& cfgFileData;
|
||||
};
|
||||
|
||||
class AddProperty {
|
||||
public:
|
||||
AddProperty(const CfgFile::SectionName& sectionName,
|
||||
CfgFile::Properties& sectionData): sectionName(sectionName),
|
||||
sectionData(sectionData) {
|
||||
}
|
||||
|
||||
void operator ()(const tstring& name, const tstring& value) {
|
||||
if (sectionName != UnknownSection) {
|
||||
const CfgFile::PropertyName *known = getPropertyName(name);
|
||||
if (known) {
|
||||
sectionData[*known].push_back(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
const CfgFile::SectionName& sectionName;
|
||||
CfgFile::Properties& sectionData;
|
||||
};
|
||||
|
||||
} // namepsace
|
||||
|
||||
CfgFile CfgFile::load(const tstring& path) {
|
||||
std::ifstream input(path.c_str());
|
||||
if (!input.good()) {
|
||||
JP_THROW(tstrings::any() << "Error opening \"" << path << "\" file: "
|
||||
<< lastCRTError());
|
||||
}
|
||||
|
||||
CfgFile cfgFile;
|
||||
|
||||
SectionName sectionName = UnknownSection;
|
||||
Properties sectionData;
|
||||
|
||||
PurgeSection purgeSection(sectionName, sectionData, cfgFile.data);
|
||||
|
||||
AddProperty addProperty(sectionName, sectionData);
|
||||
|
||||
std::string utf8line;
|
||||
int lineno = 0;
|
||||
while (std::getline(input, utf8line)) {
|
||||
++lineno;
|
||||
const tstring line = tstrings::any(utf8line).tstr();
|
||||
|
||||
if (line.empty() || _T(';') == *line.begin()) {
|
||||
// Empty line or comment, ignore.
|
||||
continue;
|
||||
}
|
||||
|
||||
if (_T('[') == *line.begin()) {
|
||||
const size_t endIdx = line.find_last_of(_T(']'));
|
||||
if (endIdx == tstring::npos) {
|
||||
JP_THROW(tstrings::any() << "Error parsing [" << path
|
||||
<< "] file at " << lineno << ": Missing ']' character");
|
||||
}
|
||||
|
||||
purgeSection();
|
||||
|
||||
// Section begin.
|
||||
const SectionName *knownName = getSectionName(line.substr(1, endIdx - 1));
|
||||
if (knownName) {
|
||||
sectionName = *knownName;
|
||||
} else {
|
||||
sectionName = UnknownSection;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
size_t sepIdx = 0;
|
||||
do {
|
||||
sepIdx = line.find_first_of(_T('='), sepIdx);
|
||||
if (sepIdx == tstring::npos) {
|
||||
addProperty(line, tstring());
|
||||
break;
|
||||
}
|
||||
|
||||
if (sepIdx != 0 && line[sepIdx - 1] == '\\') {
|
||||
sepIdx++;
|
||||
continue;
|
||||
}
|
||||
|
||||
addProperty(line.substr(0, sepIdx), line.substr(sepIdx + 1));
|
||||
break;
|
||||
} while (true);
|
||||
}
|
||||
|
||||
if (!input.eof()) {
|
||||
// Failed to process file up to the end.
|
||||
JP_THROW(tstrings::any() << "Failed to read \"" << path
|
||||
<< "\" file up to the end: " << lastCRTError());
|
||||
}
|
||||
|
||||
purgeSection();
|
||||
|
||||
return cfgFile;
|
||||
}
|
||||
|
||||
|
||||
tstring join(const tstring_array& values, const tstring::value_type delimiter) {
|
||||
return tstrings::join(values.begin(), values.end(), tstring(1, delimiter));
|
||||
}
|
||||
|
||||
tstring CfgFile::asString(Properties::const_reference property) {
|
||||
return *property.second.rbegin();
|
||||
}
|
||||
|
||||
tstring CfgFile::asPathList(Properties::const_reference property) {
|
||||
return join(property.second, FileUtils::pathSeparator);
|
||||
}
|
||||
|
||||
|
||||
#define JP_ALL_SECTIONS \
|
||||
JP_SECTION(Application); \
|
||||
JP_SECTION(JavaOptions); \
|
||||
JP_SECTION(AppCDSJavaOptions); \
|
||||
JP_SECTION(AppCDSGenerateCacheJavaOptions); \
|
||||
JP_SECTION(ArgOptions);
|
||||
|
||||
namespace SectionName {
|
||||
#define JP_SECTION(name) const CfgFile::SectionName name(_T(#name))
|
||||
JP_ALL_SECTIONS
|
||||
#undef JP_SECTION
|
||||
} // namespace SectionName
|
||||
|
||||
namespace {
|
||||
const CfgFile::SectionName* getSectionName(const tstring& str) {
|
||||
#define JP_SECTION(name) while (str == _T(#name)) { return &SectionName::name; }
|
||||
JP_ALL_SECTIONS
|
||||
#undef JP_SECTION
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#undef JP_ALL_SECTIONS
|
||||
|
||||
|
||||
#define JP_ALL_PROPERTIES \
|
||||
JP_PROPERTY(version, "app.version"); \
|
||||
JP_PROPERTY(mainjar, "app.mainjar"); \
|
||||
JP_PROPERTY(mainmodule, "app.mainmodule"); \
|
||||
JP_PROPERTY(mainclass, "app.mainclass"); \
|
||||
JP_PROPERTY(classpath, "app.classpath"); \
|
||||
JP_PROPERTY(modulepath, "app.modulepath"); \
|
||||
JP_PROPERTY(runtime, "app.runtime"); \
|
||||
JP_PROPERTY(splash, "app.splash"); \
|
||||
JP_PROPERTY(memory, "app.memory"); \
|
||||
JP_PROPERTY(arguments, "arguments"); \
|
||||
JP_PROPERTY(javaOptions, "java-options"); \
|
||||
|
||||
namespace PropertyName {
|
||||
#define JP_PROPERTY(varName, name) const CfgFile::PropertyName varName(_T(name))
|
||||
JP_ALL_PROPERTIES
|
||||
#undef JP_PROPERTY
|
||||
} // namespace PropertyName
|
||||
|
||||
namespace {
|
||||
const CfgFile::PropertyName* getPropertyName(const tstring& str) {
|
||||
#define JP_PROPERTY(varName, name) while (str == _T(name)) { return &PropertyName::varName; }
|
||||
JP_ALL_PROPERTIES
|
||||
#undef JP_PROPERTY
|
||||
return 0;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
#undef JP_ALL_PROPERTIES
|
131
src/jdk.incubator.jpackage/share/native/applauncher/CfgFile.h
Normal file
131
src/jdk.incubator.jpackage/share/native/applauncher/CfgFile.h
Normal file
@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef CfgFile_h
|
||||
#define CfgFile_h
|
||||
|
||||
#include <map>
|
||||
#include "tstrings.h"
|
||||
|
||||
|
||||
class CfgFile {
|
||||
public:
|
||||
template <class Tag> class Id {
|
||||
public:
|
||||
Id(const tstring::const_pointer str) : str(str) {
|
||||
|
||||
}
|
||||
|
||||
bool operator == (const Id& other) const {
|
||||
return tstring(str) == tstring(other.str);
|
||||
}
|
||||
|
||||
bool operator != (const Id& other) const {
|
||||
return !operator == (other);
|
||||
}
|
||||
|
||||
bool operator < (const Id& other) const {
|
||||
return tstring(str) < tstring(other.str);
|
||||
}
|
||||
|
||||
tstring name() const {
|
||||
return tstring(str);
|
||||
}
|
||||
|
||||
private:
|
||||
tstring::const_pointer str;
|
||||
};
|
||||
|
||||
class PropertyNameTag {};
|
||||
typedef Id<PropertyNameTag> PropertyName;
|
||||
|
||||
class SectionNameTag {};
|
||||
typedef Id<SectionNameTag> SectionName;
|
||||
|
||||
typedef std::map<PropertyName, tstring_array> Properties;
|
||||
|
||||
/**
|
||||
* Returns properties of the given section.
|
||||
*/
|
||||
const Properties& getProperties(const SectionName& sectionName) const;
|
||||
|
||||
/**
|
||||
* Sets new value of the given property in the given section.
|
||||
*/
|
||||
CfgFile& setPropertyValue(const SectionName& sectionName,
|
||||
const PropertyName& name, const tstring& value) {
|
||||
tstring_array ctnr;
|
||||
ctnr.push_back(value);
|
||||
return setPropertyValue(sectionName, name, ctnr);
|
||||
}
|
||||
|
||||
CfgFile& setPropertyValue(const SectionName& sectionName,
|
||||
const PropertyName& name, const tstring_array& value);
|
||||
|
||||
typedef std::map<tstring, tstring> Macros;
|
||||
|
||||
/**
|
||||
* Returns copy of this instance with the given macros expanded.
|
||||
*/
|
||||
CfgFile expandMacros(const Macros& macros) const;
|
||||
|
||||
static CfgFile load(const tstring& path);
|
||||
|
||||
static tstring asString(Properties::const_reference property);
|
||||
|
||||
static tstring asPathList(Properties::const_reference property);
|
||||
|
||||
typedef std::map<SectionName, Properties> PropertyMap;
|
||||
|
||||
private:
|
||||
PropertyMap data;
|
||||
Properties empty;
|
||||
};
|
||||
|
||||
|
||||
namespace SectionName {
|
||||
extern const CfgFile::SectionName Application;
|
||||
extern const CfgFile::SectionName JavaOptions;
|
||||
extern const CfgFile::SectionName AppCDSJavaOptions;
|
||||
extern const CfgFile::SectionName AppCDSGenerateCacheJavaOptions;
|
||||
extern const CfgFile::SectionName ArgOptions;
|
||||
} // namespace SectionName
|
||||
|
||||
namespace PropertyName {
|
||||
extern const CfgFile::PropertyName version;
|
||||
extern const CfgFile::PropertyName mainjar;
|
||||
extern const CfgFile::PropertyName mainmodule;
|
||||
extern const CfgFile::PropertyName mainclass;
|
||||
extern const CfgFile::PropertyName classpath;
|
||||
extern const CfgFile::PropertyName modulepath;
|
||||
extern const CfgFile::PropertyName runtime;
|
||||
extern const CfgFile::PropertyName splash;
|
||||
extern const CfgFile::PropertyName memory;
|
||||
extern const CfgFile::PropertyName arguments;
|
||||
extern const CfgFile::PropertyName javaOptions;
|
||||
} // namespace AppPropertyName
|
||||
|
||||
#endif // CfgFile_h
|
@ -0,0 +1,195 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#include <cstring>
|
||||
#include <jni.h>
|
||||
#include "JvmLauncher.h"
|
||||
#include "Log.h"
|
||||
#include "Dll.h"
|
||||
#include "CfgFile.h"
|
||||
#include "FileUtils.h"
|
||||
#include "Toolbox.h"
|
||||
#include "ErrorHandling.h"
|
||||
|
||||
|
||||
Jvm& Jvm::initFromConfigFile(const CfgFile& cfgFile) {
|
||||
const CfgFile::Properties& appOptions = cfgFile.getProperties(
|
||||
SectionName::Application);
|
||||
|
||||
do {
|
||||
const CfgFile::Properties::const_iterator modulepath = appOptions.find(
|
||||
PropertyName::modulepath);
|
||||
if (modulepath != appOptions.end()) {
|
||||
tstring_array::const_iterator it = modulepath->second.begin();
|
||||
const tstring_array::const_iterator end = modulepath->second.end();
|
||||
for (; it != end; ++it) {
|
||||
addArgument(_T("--module-path"));
|
||||
addArgument(*it);
|
||||
};
|
||||
}
|
||||
} while (0);
|
||||
|
||||
do {
|
||||
const CfgFile::Properties::const_iterator classpath = appOptions.find(
|
||||
PropertyName::classpath);
|
||||
if (classpath != appOptions.end()) {
|
||||
addArgument(_T("-classpath"));
|
||||
addArgument(CfgFile::asPathList(*classpath));
|
||||
}
|
||||
} while (0);
|
||||
|
||||
do {
|
||||
const CfgFile::Properties::const_iterator splash = appOptions.find(
|
||||
PropertyName::splash);
|
||||
if (splash != appOptions.end()) {
|
||||
const tstring splashPath = CfgFile::asString(*splash);
|
||||
if (FileUtils::isFileExists(splashPath)) {
|
||||
addArgument(_T("-splash"));
|
||||
addArgument(splashPath);
|
||||
} else {
|
||||
LOG_WARNING(tstrings::any()
|
||||
<< "Splash property ignored. File \""
|
||||
<< splashPath << "\" not found");
|
||||
}
|
||||
}
|
||||
} while (0);
|
||||
|
||||
do {
|
||||
const CfgFile::Properties& section = cfgFile.getProperties(
|
||||
SectionName::JavaOptions);
|
||||
const CfgFile::Properties::const_iterator javaOptions = section.find(
|
||||
PropertyName::javaOptions);
|
||||
if (javaOptions != section.end()) {
|
||||
tstring_array::const_iterator it = javaOptions->second.begin();
|
||||
const tstring_array::const_iterator end = javaOptions->second.end();
|
||||
for (; it != end; ++it) {
|
||||
addArgument(*it);
|
||||
};
|
||||
}
|
||||
} while (0);
|
||||
|
||||
// No validation of data in config file related to how Java app should be
|
||||
// launched intentionally.
|
||||
// Just read what is in config file and put on jvm's command line as is.
|
||||
|
||||
do { // Run modular app
|
||||
const CfgFile::Properties::const_iterator mainmodule = appOptions.find(
|
||||
PropertyName::mainmodule);
|
||||
if (mainmodule != appOptions.end()) {
|
||||
addArgument(_T("-m"));
|
||||
addArgument(CfgFile::asString(*mainmodule));
|
||||
}
|
||||
} while (0);
|
||||
|
||||
do { // Run main class
|
||||
const CfgFile::Properties::const_iterator mainclass = appOptions.find(
|
||||
PropertyName::mainclass);
|
||||
if (mainclass != appOptions.end()) {
|
||||
addArgument(CfgFile::asString(*mainclass));
|
||||
}
|
||||
} while (0);
|
||||
|
||||
do { // Run jar
|
||||
const CfgFile::Properties::const_iterator mainjar = appOptions.find(
|
||||
PropertyName::mainjar);
|
||||
if (mainjar != appOptions.end()) {
|
||||
addArgument(_T("-jar"));
|
||||
addArgument(CfgFile::asString(*mainjar));
|
||||
}
|
||||
} while (0);
|
||||
|
||||
do {
|
||||
const CfgFile::Properties& section = cfgFile.getProperties(
|
||||
SectionName::ArgOptions);
|
||||
const CfgFile::Properties::const_iterator arguments = section.find(
|
||||
PropertyName::arguments);
|
||||
if (arguments != section.end()) {
|
||||
tstring_array::const_iterator it = arguments->second.begin();
|
||||
const tstring_array::const_iterator end = arguments->second.end();
|
||||
for (; it != end; ++it) {
|
||||
addArgument(*it);
|
||||
};
|
||||
}
|
||||
} while (0);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
namespace {
|
||||
void convertArgs(const std::vector<std::string>& args, std::vector<char*>& argv) {
|
||||
argv.reserve(args.size() + 1);
|
||||
argv.resize(0);
|
||||
|
||||
std::vector<std::string>::const_iterator it = args.begin();
|
||||
const std::vector<std::string>::const_iterator end = args.end();
|
||||
|
||||
for (; it != end; ++it) {
|
||||
argv.push_back(const_cast<char*>(it->c_str()));
|
||||
};
|
||||
|
||||
// Add treminal '0'.
|
||||
argv.push_back(0);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void Jvm::launch() {
|
||||
typedef int (JNICALL *LaunchFuncType)(int argc, char ** argv,
|
||||
int jargc, const char** jargv,
|
||||
int appclassc, const char** appclassv,
|
||||
const char* fullversion,
|
||||
const char* dotversion,
|
||||
const char* pname,
|
||||
const char* lname,
|
||||
jboolean javaargs,
|
||||
jboolean cpwildcard,
|
||||
jboolean javaw,
|
||||
jint ergo);
|
||||
|
||||
std::vector<char*> argv;
|
||||
convertArgs(args, argv);
|
||||
|
||||
// Don't count terminal '0'.
|
||||
const int argc = (int)argv.size() - 1;
|
||||
|
||||
LOG_TRACE(tstrings::any() << "JVM library: \"" << jvmPath << "\"");
|
||||
|
||||
DllFunction<LaunchFuncType> func(Dll(jvmPath), "JLI_Launch");
|
||||
int exitStatus = func(argc, argv.data(),
|
||||
0, 0,
|
||||
0, 0,
|
||||
"",
|
||||
"",
|
||||
"java",
|
||||
"java",
|
||||
JNI_FALSE,
|
||||
JNI_FALSE,
|
||||
JNI_FALSE,
|
||||
0);
|
||||
|
||||
if (exitStatus != 0) {
|
||||
JP_THROW("Failed to launch JVM");
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 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
|
||||
@ -23,37 +23,34 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#ifndef FILEATTRIBUTE_H
|
||||
#define FILEATTRIBUTE_H
|
||||
|
||||
enum FileAttribute {
|
||||
faBlockSpecial,
|
||||
faCharacterSpecial,
|
||||
faFIFOSpecial,
|
||||
faNormal,
|
||||
faDirectory,
|
||||
faSymbolicLink,
|
||||
faSocket,
|
||||
#ifndef JvmLauncher_h
|
||||
#define JvmLauncher_h
|
||||
|
||||
// Owner
|
||||
faReadOnly,
|
||||
faWriteOnly,
|
||||
faReadWrite,
|
||||
faExecute,
|
||||
#include "tstrings.h"
|
||||
|
||||
// Group
|
||||
faGroupReadOnly,
|
||||
faGroupWriteOnly,
|
||||
faGroupReadWrite,
|
||||
faGroupExecute,
|
||||
class CfgFile;
|
||||
|
||||
// Others
|
||||
faOthersReadOnly,
|
||||
faOthersWriteOnly,
|
||||
faOthersReadWrite,
|
||||
faOthersExecute,
|
||||
|
||||
faHidden
|
||||
class Jvm {
|
||||
public:
|
||||
Jvm& initFromConfigFile(const CfgFile& cfgFile);
|
||||
|
||||
Jvm& addArgument(const tstring& value) {
|
||||
args.push_back(tstrings::any(value).str());
|
||||
return *this;
|
||||
}
|
||||
|
||||
Jvm& setPath(const tstring& v) {
|
||||
jvmPath = v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void launch();
|
||||
|
||||
private:
|
||||
tstring jvmPath;
|
||||
std::vector<std::string> args;
|
||||
};
|
||||
|
||||
#endif // FILEATTRIBUTE_H
|
||||
#endif // JvmLauncher_h
|
170
src/jdk.incubator.jpackage/share/native/common/Dll.h
Normal file
170
src/jdk.incubator.jpackage/share/native/common/Dll.h
Normal file
@ -0,0 +1,170 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#ifndef __DLL_H_INCLUDED_
|
||||
#define __DLL_H_INCLUDED_
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
typedef void* HMODULE;
|
||||
#endif
|
||||
|
||||
#include "kludge_c++11.h"
|
||||
|
||||
#include <memory>
|
||||
#include "tstrings.h"
|
||||
#include "ErrorHandling.h"
|
||||
|
||||
|
||||
//
|
||||
// Helper classes to dynamically load DLLs and call the libraries functions.
|
||||
//
|
||||
|
||||
/**
|
||||
* Library loader.
|
||||
* Usage:
|
||||
* - load a library specified by full path:
|
||||
* DLL deployLib(FileUtils::combinePath(javaHome, _T("bin\\deploy.dll"));
|
||||
*
|
||||
* Note: library should be specified by full path (due security reasons)
|
||||
*
|
||||
* - load system library (DLLs from Windows/System32 (SysWow64) directory):
|
||||
* DLL kernel32Lib("kernel32", Dll::System());
|
||||
*/
|
||||
class Dll {
|
||||
public:
|
||||
struct System {};
|
||||
|
||||
explicit Dll(const tstrings::any &libPath);
|
||||
explicit Dll(const tstrings::any &libName, const System &tag);
|
||||
|
||||
Dll(const Dll& other);
|
||||
|
||||
template <class T>
|
||||
void getFunction(const tstrings::any &name, T& addr) const {
|
||||
addr = reinterpret_cast<T>(getFunction(name.str(), true));
|
||||
}
|
||||
|
||||
// returns false & sets addr to NULL if the function not found
|
||||
template <class T>
|
||||
bool getFunction(const tstrings::any &name, T& addr, const std::nothrow_t &) const {
|
||||
addr = reinterpret_cast<T>(getFunction(name.str(), false));
|
||||
return addr != NULL;
|
||||
}
|
||||
|
||||
const tstring& path() const {
|
||||
return thePath;
|
||||
}
|
||||
|
||||
HMODULE getHandle() const {
|
||||
return handle.get();
|
||||
}
|
||||
|
||||
static void freeLibrary(HMODULE h);
|
||||
|
||||
struct LibraryReleaser {
|
||||
typedef HMODULE pointer;
|
||||
|
||||
void operator()(HMODULE h) {
|
||||
freeLibrary(h);
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::unique_ptr<HMODULE, LibraryReleaser> Handle;
|
||||
|
||||
private:
|
||||
void* getFunction(const std::string &name, bool throwIfNotFound) const;
|
||||
|
||||
tstring thePath;
|
||||
Handle handle;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* DllFunction template class helps to check is a library function available and call it.
|
||||
* Usage example:
|
||||
* // RegDeleteKeyExW function (from advapi32.dll) is available on Vista+ or on WinXP 64bit
|
||||
* // so to avoid dependency on the OS version we have to check if it's available at runtime
|
||||
*
|
||||
* // the function definition
|
||||
* typedef LONG (WINAPI *RegDeleteKeyExWFunc)(HKEY hKey, const wchar_t* lpSubKey, REGSAM samDesired, DWORD Reserved);
|
||||
*
|
||||
* DllFunction<RegDeleteKeyExWFunc> _RegDeleteKeyExW(Dll("advapi32", Dll::System()), "RegDeleteKeyExW");
|
||||
* if (_RegDeleteKeyExW.available()) {
|
||||
* // the function is available, call it
|
||||
* LONG result = _RegDeleteKeyExW(hKey, subkeyName, samDesired, 0);
|
||||
* } else {
|
||||
* // the function is not available, handle this
|
||||
* throw std::exception("RegDeleteKeyExW function is not available");
|
||||
* }
|
||||
*
|
||||
* // or we can just try to call the function.
|
||||
* // if the function is not available, exception with the corresponding description is thrown
|
||||
* DllFunction<RegDeleteKeyExWFunc> _RegDeleteKeyExW(Dll("advapi32", Dll::System()), "RegDeleteKeyExW");
|
||||
* LONG result = _RegDeleteKeyExW(hKey, subkeyName, samDesired, 0);
|
||||
*/
|
||||
template<class funcType>
|
||||
class DllFunction {
|
||||
public:
|
||||
DllFunction(const Dll& library, const tstrings::any &funcName)
|
||||
: lib(library), theName(funcName.str()) {
|
||||
lib.getFunction(funcName, funcPtr);
|
||||
}
|
||||
|
||||
DllFunction(const std::nothrow_t&, const Dll& library,
|
||||
const tstrings::any &funcName)
|
||||
: lib(library), theName(funcName.str()) {
|
||||
lib.getFunction(funcName, funcPtr, std::nothrow);
|
||||
}
|
||||
|
||||
bool available() const {
|
||||
return funcPtr != NULL;
|
||||
}
|
||||
|
||||
std::string name() const {
|
||||
return theName;
|
||||
}
|
||||
|
||||
const tstring& libPath() const {
|
||||
return lib.path();
|
||||
}
|
||||
|
||||
operator funcType() const {
|
||||
if (!available()) {
|
||||
JP_THROW(tstrings::any() << theName
|
||||
<< "() function is not available in "
|
||||
<< lib.path());
|
||||
}
|
||||
return funcPtr;
|
||||
}
|
||||
|
||||
private:
|
||||
const Dll lib;
|
||||
funcType funcPtr;
|
||||
std::string theName;
|
||||
};
|
||||
|
||||
#endif // __DLL_H_INCLUDED_
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019, 2020, 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
|
||||
@ -24,6 +24,8 @@
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <string.h>
|
||||
#include <cerrno>
|
||||
|
||||
#include "ErrorHandling.h"
|
||||
#include "Log.h"
|
||||
@ -47,7 +49,7 @@ void reportError(const SourceCodePos& pos, const tstring& msg) {
|
||||
|
||||
} // namespace
|
||||
|
||||
void reportError(const SourceCodePos& pos, const std::exception& e) {
|
||||
void reportError(const SourceCodePos& pos, const std::runtime_error& e) {
|
||||
reportError(pos, (tstrings::any() << "Exception with message \'"
|
||||
<< e.what() << "\' caught").tstr());
|
||||
}
|
||||
@ -58,7 +60,7 @@ void reportUnknownError(const SourceCodePos& pos) {
|
||||
}
|
||||
|
||||
|
||||
std::string makeMessage(const std::exception& e, const SourceCodePos& pos) {
|
||||
std::string makeMessage(const std::runtime_error& e, const SourceCodePos& pos) {
|
||||
std::ostringstream printer;
|
||||
printer << getFilename(pos) << "(" << pos.lno << ") at "
|
||||
<< pos.func << "(): "
|
||||
@ -139,3 +141,16 @@ std::string joinErrorMessages(const std::string& a, const std::string& b) {
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
std::string lastCRTError() {
|
||||
#ifndef _WIN32
|
||||
return strerror(errno);
|
||||
#else
|
||||
TCHAR buffer[2048];
|
||||
if (0 == _tcserror_s(buffer, errno)) {
|
||||
return (tstrings::any() << buffer).str();
|
||||
}
|
||||
return "";
|
||||
#endif
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019, 2020, 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
|
||||
@ -50,18 +50,26 @@
|
||||
|
||||
|
||||
// Logs std::exception caught at 'pos'.
|
||||
void reportError(const SourceCodePos& pos, const std::exception& e);
|
||||
void reportError(const SourceCodePos& pos, const std::runtime_error& e);
|
||||
// Logs unknown exception caught at 'pos'.
|
||||
// Assumed to be called from catch (...) {}
|
||||
void reportUnknownError(const SourceCodePos& pos);
|
||||
|
||||
std::string makeMessage(const std::exception& e, const SourceCodePos& pos);
|
||||
std::string makeMessage(const std::runtime_error& e, const SourceCodePos& pos);
|
||||
|
||||
std::string joinErrorMessages(const std::string& a, const std::string& b);
|
||||
|
||||
std::string lastCRTError();
|
||||
|
||||
|
||||
class JpErrorBase {
|
||||
public:
|
||||
virtual const char* rawMessage() const throw() = 0;
|
||||
};
|
||||
|
||||
|
||||
template <class Base>
|
||||
class JpError: public Base {
|
||||
class JpError: public JpErrorBase, public Base {
|
||||
public:
|
||||
JpError(const Base& e, const SourceCodePos& pos):
|
||||
Base(e), msg(::makeMessage(e, pos)) {
|
||||
@ -74,10 +82,15 @@ public:
|
||||
const char* what() const throw() {
|
||||
return msg.c_str();
|
||||
}
|
||||
|
||||
// override JpErrorBase
|
||||
const char* rawMessage() const throw() {
|
||||
return Base::what();
|
||||
}
|
||||
private:
|
||||
// Assert Base is derived from std::exception
|
||||
// Assert Base is derived from std::runtime_error
|
||||
enum { isDerivedFromStdException =
|
||||
sizeof(static_cast<std::exception*>((Base*)0)) };
|
||||
sizeof(static_cast<std::runtime_error*>((Base*)0)) };
|
||||
|
||||
std::string msg;
|
||||
};
|
||||
@ -129,7 +142,7 @@ inline JpError<std::runtime_error> makeException(
|
||||
do {} while(0)
|
||||
|
||||
#define JP_CATCH_STD_EXCEPTION \
|
||||
catch (const std::exception& e) \
|
||||
catch (const std::runtime_error& e) \
|
||||
{ \
|
||||
JP_HANDLE_ERROR(e); \
|
||||
}
|
143
src/jdk.incubator.jpackage/share/native/common/FileUtils.cpp
Normal file
143
src/jdk.incubator.jpackage/share/native/common/FileUtils.cpp
Normal file
@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#include <memory>
|
||||
#include <algorithm>
|
||||
|
||||
#include "FileUtils.h"
|
||||
|
||||
|
||||
namespace FileUtils {
|
||||
|
||||
#ifdef _WIN32
|
||||
const tstring::value_type pathSeparator = _T(';');
|
||||
#else
|
||||
const tstring::value_type pathSeparator = _T(':');
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
#ifdef _WIN32
|
||||
const tstring::value_type dirSeparator = _T('\\');
|
||||
const tstring::value_type alianDirSeparator = _T('/');
|
||||
#else
|
||||
const tstring::value_type dirSeparator = _T('/');
|
||||
const tstring::value_type alianDirSeparator = _T('\\');
|
||||
#endif
|
||||
} // namespace
|
||||
|
||||
|
||||
bool isDirSeparator(const tstring::value_type c) {
|
||||
return (c == dirSeparator || c == alianDirSeparator);
|
||||
}
|
||||
|
||||
|
||||
tstring dirname(const tstring &path) {
|
||||
tstring::size_type pos = path.find_last_of(_T("\\/"));
|
||||
if (pos != tstring::npos) {
|
||||
pos = path.find_last_not_of(_T("\\/"), pos); // skip trailing slashes
|
||||
}
|
||||
return pos == tstring::npos ? tstring() : path.substr(0, pos + 1);
|
||||
}
|
||||
|
||||
|
||||
tstring basename(const tstring &path) {
|
||||
const tstring::size_type pos = path.find_last_of(_T("\\/"));
|
||||
if (pos == tstring::npos) {
|
||||
return path;
|
||||
}
|
||||
return path.substr(pos + 1);
|
||||
}
|
||||
|
||||
|
||||
tstring suffix(const tstring &path) {
|
||||
const tstring::size_type pos = path.rfind(_T('.'));
|
||||
if (pos == tstring::npos) {
|
||||
return tstring();
|
||||
}
|
||||
const tstring::size_type dirSepPos = path.find_first_of(_T("\\/"),
|
||||
pos + 1);
|
||||
if (dirSepPos != tstring::npos) {
|
||||
return tstring();
|
||||
}
|
||||
// test for '/..' and '..' cases
|
||||
if (pos != 0 && path[pos - 1] == _T('.')
|
||||
&& (pos == 1 || isDirSeparator(path[pos - 2]))) {
|
||||
return tstring();
|
||||
}
|
||||
return path.substr(pos);
|
||||
}
|
||||
|
||||
|
||||
tstring combinePath(const tstring& parent, const tstring& child) {
|
||||
if (parent.empty()) {
|
||||
return child;
|
||||
}
|
||||
if (child.empty()) {
|
||||
return parent;
|
||||
}
|
||||
|
||||
tstring parentWOSlash = removeTrailingSlash(parent);
|
||||
// also handle the case when child contains starting slash
|
||||
bool childHasSlash = isDirSeparator(*child.begin());
|
||||
tstring childWOSlash = childHasSlash ? child.substr(1) : child;
|
||||
|
||||
return parentWOSlash.append(1, dirSeparator).append(childWOSlash);
|
||||
}
|
||||
|
||||
|
||||
tstring removeTrailingSlash(const tstring& path) {
|
||||
if (path.empty()) {
|
||||
return path;
|
||||
}
|
||||
tstring::const_reverse_iterator it = path.rbegin();
|
||||
tstring::const_reverse_iterator end = path.rend();
|
||||
|
||||
while (it != end && isDirSeparator(*it)) {
|
||||
++it;
|
||||
}
|
||||
return path.substr(0, end - it);
|
||||
}
|
||||
|
||||
|
||||
tstring normalizePath(tstring v) {
|
||||
std::replace(v.begin(), v.end(), alianDirSeparator, dirSeparator);
|
||||
#ifdef _WIN32
|
||||
return tstrings::toLower(v);
|
||||
#else
|
||||
return v;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
tstring replaceSuffix(const tstring& path, const tstring& newSuffix) {
|
||||
const tstring oldSuffix = suffix(path);
|
||||
if (oldSuffix.empty()) {
|
||||
return tstring().append(path).append(newSuffix);
|
||||
}
|
||||
|
||||
return path.substr(0, path.size() - oldSuffix.size()).append(newSuffix);
|
||||
}
|
||||
|
||||
} // namespace FileUtils
|
124
src/jdk.incubator.jpackage/share/native/common/FileUtils.h
Normal file
124
src/jdk.incubator.jpackage/share/native/common/FileUtils.h
Normal file
@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#ifndef FILEUTILS_H
|
||||
#define FILEUTILS_H
|
||||
|
||||
|
||||
#include <fstream>
|
||||
#include "SysInfo.h"
|
||||
|
||||
|
||||
namespace FileUtils {
|
||||
extern const tstring::value_type pathSeparator;
|
||||
|
||||
// Returns 'true' if the given character is a path separator.
|
||||
bool isDirSeparator(const tstring::value_type c);
|
||||
|
||||
// returns directory part of the path.
|
||||
// returns empty string if the path contains only filename.
|
||||
// if the path ends with slash/backslash,
|
||||
// returns removeTrailingSlashes(path).
|
||||
tstring dirname(const tstring &path);
|
||||
|
||||
// returns basename part of the path
|
||||
// if the path ends with slash/backslash, returns empty string.
|
||||
tstring basename(const tstring &path);
|
||||
|
||||
/**
|
||||
* Translates forward slashes to back slashes and returns lower case version
|
||||
* of the given string.
|
||||
*/
|
||||
tstring normalizePath(tstring v);
|
||||
|
||||
// Returns suffix of the path. If the given path has a suffix the first
|
||||
// character of the return value is '.'.
|
||||
// Otherwise return value if empty string.
|
||||
tstring suffix(const tstring &path);
|
||||
|
||||
// combines two strings into a path
|
||||
tstring combinePath(const tstring& parent, const tstring& child);
|
||||
|
||||
// removes trailing slashes and backslashes in the path if any
|
||||
tstring removeTrailingSlash(const tstring& path);
|
||||
|
||||
/**
|
||||
* Replace file suffix, example replaceSuffix("file/path.txt", ".csv")
|
||||
* @param path file path to replace suffix
|
||||
* @param suffix new suffix for path
|
||||
* @return return file path with new suffix
|
||||
*/
|
||||
tstring replaceSuffix(const tstring& path, const tstring& suffix=tstring());
|
||||
|
||||
/**
|
||||
* Returns absolute path of the given path.
|
||||
* If the given string is empty, returns absolute path to the current
|
||||
* directory.
|
||||
*/
|
||||
tstring toAbsolutePath(const tstring& path);
|
||||
|
||||
// Helper to construct path from multiple components.
|
||||
//
|
||||
// Sample usage:
|
||||
// Construct "c:\Program Files\Java" string from three components
|
||||
//
|
||||
// tstring path = FileUtils::mkpath() << _T("c:")
|
||||
// << _T("Program Files")
|
||||
// << _T("Java");
|
||||
//
|
||||
class mkpath {
|
||||
public:
|
||||
operator const tstring& () const {
|
||||
return path;
|
||||
}
|
||||
|
||||
mkpath& operator << (const tstring& p) {
|
||||
path = combinePath(path, p);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// mimic std::string
|
||||
const tstring::value_type* c_str() const {
|
||||
return path.c_str();
|
||||
}
|
||||
private:
|
||||
tstring path;
|
||||
};
|
||||
|
||||
// checks if the file or directory exists
|
||||
bool isFileExists(const tstring &filePath);
|
||||
|
||||
// checks is the specified file is a directory
|
||||
// returns false if the path does not exist
|
||||
bool isDirectory(const tstring &filePath);
|
||||
|
||||
// checks if the specified directory is not empty
|
||||
// returns true if the path is an existing directory and
|
||||
// it contains at least one file other than "." or "..".
|
||||
bool isDirectoryNotEmpty(const tstring &dirPath);
|
||||
|
||||
} // FileUtils
|
||||
|
||||
#endif // FILEUTILS_H
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019, 2020, 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
|
||||
@ -24,7 +24,6 @@
|
||||
*/
|
||||
|
||||
#include "Log.h"
|
||||
#include "SysInfo.h"
|
||||
#include "FileUtils.h"
|
||||
|
||||
|
||||
@ -46,12 +45,10 @@ namespace {
|
||||
// by default log everything
|
||||
const Logger::LogLevel defaultLogLevel = Logger::LOG_TRACE;
|
||||
|
||||
char defaultLogAppenderMemory[sizeof(StderrLogAppender)] = {};
|
||||
char defaultLogAppenderMemory[sizeof(StreamLogAppender)] = {};
|
||||
|
||||
char defaultLoggerMemory[sizeof(Logger)] = {};
|
||||
|
||||
NopLogAppender nopLogApender;
|
||||
|
||||
LPCTSTR getLogLevelStr(Logger::LogLevel level) {
|
||||
switch (level) {
|
||||
case Logger::LOG_TRACE:
|
||||
@ -66,26 +63,12 @@ namespace {
|
||||
return _T("UNKNOWN");
|
||||
}
|
||||
|
||||
tstring retrieveModuleName() {
|
||||
try {
|
||||
return FileUtils::basename(SysInfo::getCurrentModulePath());
|
||||
} catch (const std::exception&) {
|
||||
return _T("Unknown");
|
||||
}
|
||||
}
|
||||
|
||||
TCHAR moduleName[MAX_PATH] = { 'U', 'n', 'k', 'o', 'w', 'n', TCHAR(0) };
|
||||
|
||||
const LPCTSTR format = _T("[%04u/%02u/%02u %02u:%02u:%02u.%03u, %s (PID: %u, TID: %u), %s:%u (%s)]\n\t%s: %s\n");
|
||||
|
||||
enum State { NotInitialized, Initializing, Initialized };
|
||||
State state = NotInitialized;
|
||||
}
|
||||
|
||||
|
||||
LogEvent::LogEvent() {
|
||||
memset(this, 0, sizeof(*this));
|
||||
moduleName = tstring();
|
||||
logLevel = tstring();
|
||||
fileName = tstring();
|
||||
funcName = tstring();
|
||||
@ -93,10 +76,6 @@ LogEvent::LogEvent() {
|
||||
}
|
||||
|
||||
|
||||
StderrLogAppender::StderrLogAppender() {
|
||||
}
|
||||
|
||||
|
||||
/*static*/
|
||||
Logger& Logger::defaultLogger() {
|
||||
Logger* reply = reinterpret_cast<Logger*>(defaultLoggerMemory);
|
||||
@ -106,27 +85,17 @@ Logger& Logger::defaultLogger() {
|
||||
// object. OS will do resources clean up anyways when application
|
||||
// terminates and the default log appender should live as long as
|
||||
// application lives.
|
||||
reply->appender = new (defaultLogAppenderMemory) StderrLogAppender();
|
||||
reply->appender = new (defaultLogAppenderMemory) StreamLogAppender(
|
||||
std::cout);
|
||||
}
|
||||
|
||||
if (Initializing == state) {
|
||||
// Recursive call to Logger::defaultLogger.
|
||||
moduleName[0] = TCHAR(0);
|
||||
initializingLogging();
|
||||
|
||||
} else if (NotInitialized == state) {
|
||||
state = Initializing;
|
||||
|
||||
tstring mname = retrieveModuleName();
|
||||
mname.resize(_countof(moduleName) - 1);
|
||||
std::memcpy(moduleName, mname.c_str(), mname.size());
|
||||
moduleName[mname.size()] = TCHAR(0);
|
||||
|
||||
// if JPACKAGE_DEBUG environment variable is NOT set to "true" disable
|
||||
// logging.
|
||||
if (SysInfo::getEnvVariable(std::nothrow,
|
||||
L"JPACKAGE_DEBUG") != L"true") {
|
||||
reply->appender = &nopLogApender;
|
||||
}
|
||||
|
||||
initializeLogging();
|
||||
state = Initialized;
|
||||
}
|
||||
|
||||
@ -152,14 +121,8 @@ bool Logger::isLoggable(LogLevel logLevel) const {
|
||||
void Logger::log(LogLevel logLevel, LPCTSTR fileName, int lineNum,
|
||||
LPCTSTR funcName, const tstring& message) const {
|
||||
LogEvent logEvent;
|
||||
LogEvent::init(logEvent);
|
||||
|
||||
// [YYYY/MM/DD HH:MM:SS.ms, <module> (PID: processID, TID: threadID),
|
||||
// fileName:lineNum (funcName)] <tab>LEVEL: message
|
||||
GetLocalTime(&logEvent.ts);
|
||||
|
||||
logEvent.pid = GetCurrentProcessId();
|
||||
logEvent.tid = GetCurrentThreadId();
|
||||
logEvent.moduleName = moduleName;
|
||||
logEvent.fileName = FileUtils::basename(fileName);
|
||||
logEvent.funcName = funcName;
|
||||
logEvent.logLevel = getLogLevelStr(logLevel);
|
||||
@ -170,18 +133,20 @@ void Logger::log(LogLevel logLevel, LPCTSTR fileName, int lineNum,
|
||||
}
|
||||
|
||||
|
||||
void StderrLogAppender::append(const LogEvent& v)
|
||||
{
|
||||
const tstring out = tstrings::unsafe_format(format,
|
||||
unsigned(v.ts.wYear), unsigned(v.ts.wMonth), unsigned(v.ts.wDay),
|
||||
unsigned(v.ts.wHour), unsigned(v.ts.wMinute), unsigned(v.ts.wSecond),
|
||||
unsigned(v.ts.wMilliseconds),
|
||||
v.moduleName.c_str(), v.pid, v.tid,
|
||||
v.fileName.c_str(), v.lineNum, v.funcName.c_str(),
|
||||
v.logLevel.c_str(),
|
||||
v.message.c_str());
|
||||
void StreamLogAppender::append(const LogEvent& v) {
|
||||
tstring platformLogStr;
|
||||
LogEvent::appendFormatted(v, platformLogStr);
|
||||
|
||||
std::cerr << tstrings::toUtf8(out);
|
||||
tostringstream printer;
|
||||
printer << _T('[') << platformLogStr
|
||||
<< v.fileName << _T(':') << v.lineNum
|
||||
<< _T(" (") << v.funcName << _T(')')
|
||||
<< _T(']')
|
||||
<< _T('\n') << _T('\t')
|
||||
<< v.logLevel << _T(": ")
|
||||
<< v.message;
|
||||
|
||||
*consumer << tstrings::toUtf8(printer.str()) << std::endl;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019, 2020, 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
|
||||
@ -26,7 +26,7 @@
|
||||
#ifndef __LOG_H_INCLUDED_
|
||||
#define __LOG_H_INCLUDED_
|
||||
|
||||
#include <windows.h>
|
||||
#include "PlatformLogEvent.h"
|
||||
#include "tstrings.h"
|
||||
|
||||
|
||||
@ -45,11 +45,10 @@
|
||||
* (usually value of the TMP env. var)
|
||||
*/
|
||||
|
||||
struct LogEvent {
|
||||
SYSTEMTIME ts;
|
||||
long tid;
|
||||
long pid;
|
||||
tstring moduleName;
|
||||
class Logger;
|
||||
class StreamLogAppender;
|
||||
|
||||
struct LogEvent: public PlatformLogEvent {
|
||||
tstring logLevel;
|
||||
tstring fileName;
|
||||
int lineNum;
|
||||
@ -57,6 +56,14 @@ struct LogEvent {
|
||||
tstring message;
|
||||
|
||||
LogEvent();
|
||||
|
||||
friend class Logger;
|
||||
friend class StreamLogAppender;
|
||||
|
||||
private:
|
||||
static void init(PlatformLogEvent& logEvent);
|
||||
static void appendFormatted(const PlatformLogEvent& logEvent,
|
||||
tstring& buffer);
|
||||
};
|
||||
|
||||
|
||||
@ -96,13 +103,18 @@ private:
|
||||
|
||||
|
||||
/**
|
||||
* Writes log events to stderr.
|
||||
* Writes log events to the given std::ostream.
|
||||
* Supposed to be used with std::cout or std::cerr
|
||||
*/
|
||||
class StderrLogAppender: public LogAppender {
|
||||
class StreamLogAppender: public LogAppender {
|
||||
public:
|
||||
explicit StderrLogAppender();
|
||||
explicit StreamLogAppender(std::ostream& consumer) : consumer(&consumer) {
|
||||
}
|
||||
|
||||
virtual void append(const LogEvent& v);
|
||||
|
||||
private:
|
||||
std::ostream* consumer;
|
||||
};
|
||||
|
||||
|
||||
@ -154,19 +166,42 @@ public:
|
||||
private:
|
||||
const Logger &log;
|
||||
const LogLevel level;
|
||||
const bool needLog;
|
||||
const tstring file;
|
||||
const int line;
|
||||
const tstring func;
|
||||
const tstring scope;
|
||||
const bool needLog;
|
||||
};
|
||||
|
||||
private:
|
||||
static void initializingLogging();
|
||||
static void initializeLogging();
|
||||
|
||||
private:
|
||||
LogLevel level;
|
||||
LogAppender* appender;
|
||||
};
|
||||
|
||||
|
||||
class WithExtraLogAppender {
|
||||
public:
|
||||
WithExtraLogAppender(LogAppender& logAppender):
|
||||
oldLogAppender(Logger::defaultLogger().getAppender()),
|
||||
newLogAppender(&Logger::defaultLogger().getAppender(),
|
||||
&logAppender) {
|
||||
Logger::defaultLogger().setAppender(newLogAppender);
|
||||
}
|
||||
|
||||
virtual ~WithExtraLogAppender() {
|
||||
Logger::defaultLogger().setAppender(oldLogAppender);
|
||||
}
|
||||
|
||||
private:
|
||||
LogAppender& oldLogAppender;
|
||||
TeeLogAppender newLogAppender;
|
||||
};
|
||||
|
||||
|
||||
// base logging macro
|
||||
#define LOGGER_LOG(logger, logLevel, message) \
|
||||
do { \
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019, 2020, 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
|
||||
@ -47,7 +47,11 @@ struct SourceCodePos
|
||||
|
||||
// Initializes SourceCodePos instance with the
|
||||
// information from the point of calling.
|
||||
#define JP_SOURCE_CODE_POS SourceCodePos(__FILE__, __FUNCTION__, __LINE__)
|
||||
#ifdef THIS_FILE
|
||||
#define JP_SOURCE_CODE_POS SourceCodePos(THIS_FILE, __FUNCTION__, __LINE__)
|
||||
#else
|
||||
#define JP_SOURCE_CODE_POS SourceCodePos(__FILE__, __FUNCTION__, __LINE__)
|
||||
#endif
|
||||
|
||||
|
||||
#endif // #ifndef SourceCodePos_h
|
182
src/jdk.incubator.jpackage/share/native/common/Toolbox.h
Normal file
182
src/jdk.incubator.jpackage/share/native/common/Toolbox.h
Normal file
@ -0,0 +1,182 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#ifndef Toolbox_h
|
||||
#define Toolbox_h
|
||||
|
||||
|
||||
#include <algorithm>
|
||||
#include "tstrings.h"
|
||||
|
||||
|
||||
/**
|
||||
* Placeholder for API not falling into any particular category.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
struct deletePtr {
|
||||
template <class PtrT>
|
||||
void operator () (PtrT ptr) const {
|
||||
delete ptr;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Deletes all pointers in the given range of items.
|
||||
*/
|
||||
template <class It>
|
||||
void deleteAll(It b, It e) {
|
||||
std::for_each(b, e, deletePtr());
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes all pointers from the container.
|
||||
*/
|
||||
template <class Ctnr>
|
||||
void deleteAll(Ctnr& ctnr) {
|
||||
deleteAll(std::begin(ctnr), std::end(ctnr));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Applies std::for_each() to the given object that has begin() and end()
|
||||
* methods.
|
||||
*/
|
||||
template <class Ctnr, class Fn>
|
||||
void forEach(Ctnr& ctnr, Fn fn) {
|
||||
std::for_each(std::begin(ctnr), std::end(ctnr), fn);
|
||||
}
|
||||
|
||||
template <class Ctnr, class Fn>
|
||||
void forEach(const Ctnr& ctnr, Fn fn) {
|
||||
std::for_each(std::begin(ctnr), std::end(ctnr), fn);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Runs the given functor from destructor. Don't use directly.
|
||||
* This is just a helper for runAtEndOfScope().
|
||||
*/
|
||||
template <class Fn>
|
||||
class AtEndOfScope {
|
||||
Fn func;
|
||||
bool theAbort;
|
||||
public:
|
||||
explicit AtEndOfScope(Fn f): func(f), theAbort(false) {
|
||||
}
|
||||
~AtEndOfScope() {
|
||||
if (!theAbort) {
|
||||
JP_NO_THROW(func());
|
||||
}
|
||||
}
|
||||
void abort(bool v=true) {
|
||||
theAbort = v;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper to create AtEndOfScope instance without need to
|
||||
* specify template type explicitly. Like std::make_pair to construct
|
||||
* std::pair instance.
|
||||
*
|
||||
* Use case:
|
||||
* Say you need to call a function (foo()) at exit from another
|
||||
* function (bar()).
|
||||
* You will normally do:
|
||||
* void bar() {
|
||||
* workload();
|
||||
* foo();
|
||||
* }
|
||||
*
|
||||
* If workload() can throw exceptions things become little bit more
|
||||
* complicated:
|
||||
* void bar() {
|
||||
* JP_NO_THROW(workload());
|
||||
* foo();
|
||||
* }
|
||||
*
|
||||
* If there is branching in bar() it is little bit more complicated again:
|
||||
* int bar() {
|
||||
* if (...) {
|
||||
* JP_NO_THROW(workload());
|
||||
* foo();
|
||||
* return 0;
|
||||
* }
|
||||
* if (...) {
|
||||
* JP_NO_THROW(workload2());
|
||||
* foo();
|
||||
* return 1;
|
||||
* }
|
||||
* foo();
|
||||
* return 2;
|
||||
* }
|
||||
*
|
||||
* So for relatively complex bar() this approach will end up with
|
||||
* missing foo() call. The standard solution to avoid errors like this,
|
||||
* is to call foo() from some object's destructor, i.e. delegate
|
||||
* responsibility to ensure it is always called to compiler:
|
||||
*
|
||||
* struct FooCaller {
|
||||
* ~FooCaller() { JP_NO_THROW(foo()); }
|
||||
* };
|
||||
*
|
||||
* int bar() {
|
||||
* FooCaller fooCaller;
|
||||
* if (...) {
|
||||
* JP_NO_THROW(workload());
|
||||
* return 0;
|
||||
* }
|
||||
* if (...) {
|
||||
* JP_NO_THROW(workload2());
|
||||
* foo();
|
||||
* }
|
||||
* return 2;
|
||||
* }
|
||||
*
|
||||
* However it is annoying to explicitly create FooCaller-like types
|
||||
* for tasks like this. Use of runAtEndOfScope() saves you from this:
|
||||
*
|
||||
* int bar() {
|
||||
* const auto fooCaller = runAtEndOfScope(foo);
|
||||
* if (...) {
|
||||
* JP_NO_THROW(workload());
|
||||
* return 0;
|
||||
* }
|
||||
* if (...) {
|
||||
* JP_NO_THROW(workload2());
|
||||
* foo();
|
||||
* }
|
||||
* return 2;
|
||||
* }
|
||||
*
|
||||
*/
|
||||
template <class Fn>
|
||||
AtEndOfScope<Fn> runAtEndOfScope(Fn func) {
|
||||
return AtEndOfScope<Fn>(func);
|
||||
}
|
||||
|
||||
#endif // #ifndef Toolbox_h
|
170
src/jdk.incubator.jpackage/share/native/common/kludge_c++11.h
Normal file
170
src/jdk.incubator.jpackage/share/native/common/kludge_c++11.h
Normal file
@ -0,0 +1,170 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef kludge_cxx11_h
|
||||
#define kludge_cxx11_h
|
||||
|
||||
//
|
||||
// This file contains kludge implementation of C++11 features needed to build
|
||||
// jpackage until Open JDK moves forward from C++98 standard.
|
||||
//
|
||||
|
||||
#ifdef __GNUG__
|
||||
#ifndef __clang__
|
||||
#if __cplusplus < 201103L
|
||||
#define JP_WITH_KLUDGE_CXX11
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef JP_WITH_KLUDGE_CXX11
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
namespace std {
|
||||
|
||||
namespace impl {
|
||||
|
||||
template <typename Tp, typename Dp>
|
||||
class unique_ptr_impl {
|
||||
public:
|
||||
typedef typename Dp::pointer pointer;
|
||||
typedef Tp element_type;
|
||||
typedef Dp deleter_type;
|
||||
|
||||
unique_ptr_impl(): value(0) {
|
||||
}
|
||||
|
||||
unique_ptr_impl(pointer p): value(p) {
|
||||
}
|
||||
|
||||
pointer release() {
|
||||
const pointer retValue = value;
|
||||
value = 0;
|
||||
return retValue;
|
||||
}
|
||||
|
||||
void swap(unique_ptr_impl& other) {
|
||||
std::swap(value, other.value);
|
||||
}
|
||||
|
||||
pointer get() const {
|
||||
return value;
|
||||
}
|
||||
|
||||
private:
|
||||
unique_ptr_impl(const unique_ptr_impl&);
|
||||
unique_ptr_impl& operator= (const unique_ptr_impl&);
|
||||
|
||||
private:
|
||||
pointer value;
|
||||
};
|
||||
|
||||
} // namespace impl
|
||||
|
||||
|
||||
template <typename Tp>
|
||||
struct default_delete {
|
||||
typedef Tp* pointer;
|
||||
|
||||
void operator()(Tp* ptr) const {
|
||||
delete ptr;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Tp, typename Dp = default_delete<Tp> >
|
||||
class unique_ptr {
|
||||
typedef impl::unique_ptr_impl<Tp, Dp> impl_type;
|
||||
public:
|
||||
typedef typename impl_type::pointer pointer;
|
||||
typedef typename impl_type::element_type element_type;
|
||||
typedef typename impl_type::deleter_type deleter_type;
|
||||
|
||||
unique_ptr() {
|
||||
}
|
||||
|
||||
unique_ptr(pointer p): impl(p) {
|
||||
}
|
||||
|
||||
~unique_ptr() {
|
||||
if (get() != 0) {
|
||||
impl_type tmp;
|
||||
tmp.swap(impl);
|
||||
Dp()(tmp.get());
|
||||
}
|
||||
}
|
||||
|
||||
pointer release() {
|
||||
return impl.release();
|
||||
}
|
||||
|
||||
void swap(unique_ptr& other) {
|
||||
impl.swap(other.impl);
|
||||
}
|
||||
|
||||
pointer get() const {
|
||||
return impl.get();
|
||||
}
|
||||
|
||||
element_type& operator *() const {
|
||||
return *impl.get();
|
||||
}
|
||||
|
||||
pointer operator ->() const {
|
||||
return impl.get();
|
||||
}
|
||||
|
||||
private:
|
||||
impl_type impl;
|
||||
};
|
||||
|
||||
template <class Ctnr>
|
||||
typename Ctnr::const_iterator begin(const Ctnr& ctnr) {
|
||||
return ctnr.begin();
|
||||
}
|
||||
|
||||
template <class Ctnr>
|
||||
typename Ctnr::iterator begin(Ctnr& ctnr) {
|
||||
return ctnr.begin();
|
||||
}
|
||||
|
||||
template <class Ctnr>
|
||||
typename Ctnr::const_iterator end(const Ctnr& ctnr) {
|
||||
return ctnr.end();
|
||||
}
|
||||
|
||||
template <class Ctnr>
|
||||
typename Ctnr::iterator end(Ctnr& ctnr) {
|
||||
return ctnr.end();
|
||||
}
|
||||
|
||||
} // namespace std
|
||||
|
||||
#endif // #ifdef JP_WITH_KLUDGE_CXX11
|
||||
|
||||
#endif // #ifndef kludge_cxx11_h
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019, 2020, 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
|
||||
@ -52,8 +52,15 @@ tstring unsafe_format(tstring::const_pointer format, ...) {
|
||||
#ifdef _MSC_VER
|
||||
ret = _vsntprintf_s(&*fmtout.begin(), fmtout.size(), _TRUNCATE, format, args);
|
||||
#else
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
|
||||
#endif
|
||||
// With g++ this compiles only with '-std=gnu++0x' option
|
||||
ret = vsnprintf(&*fmtout.begin(), fmtout.size(), format, args);
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
#endif
|
||||
} while(-1 == ret);
|
||||
va_end(args);
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019, 2020, 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
|
||||
@ -198,7 +198,7 @@ namespace format_detail {
|
||||
}
|
||||
|
||||
inline str_arg_value<std::string> arg(std::string::const_pointer v) {
|
||||
return (v ? v : "(null)");
|
||||
return std::string(v ? v: "(null)");
|
||||
}
|
||||
|
||||
#ifdef TSTRINGS_WITH_WCHAR
|
||||
@ -207,7 +207,7 @@ namespace format_detail {
|
||||
}
|
||||
|
||||
inline str_arg_value<std::wstring> arg(std::wstring::const_pointer v) {
|
||||
return (v ? v : L"(null)");
|
||||
return std::wstring(v ? v : L"(null)");
|
||||
}
|
||||
#else
|
||||
void arg(const std::wstring&); // Compilation error by design.
|
@ -1,81 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2019, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#ifndef FILEPATH_H
|
||||
#define FILEPATH_H
|
||||
|
||||
#include "Platform.h"
|
||||
#include "PlatformString.h"
|
||||
#include "FileAttribute.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
class FileAttributes {
|
||||
private:
|
||||
TString FFileName;
|
||||
bool FFollowLink;
|
||||
std::vector<FileAttribute> FAttributes;
|
||||
|
||||
bool WriteAttributes();
|
||||
bool ReadAttributes();
|
||||
bool Valid(const FileAttribute Value);
|
||||
|
||||
public:
|
||||
FileAttributes(const TString FileName, bool FollowLink = true);
|
||||
|
||||
void Append(const FileAttribute Value);
|
||||
bool Contains(const FileAttribute Value);
|
||||
void Remove(const FileAttribute Value);
|
||||
};
|
||||
|
||||
class FilePath {
|
||||
private:
|
||||
FilePath(void) {}
|
||||
~FilePath(void) {}
|
||||
|
||||
public:
|
||||
static bool FileExists(const TString FileName);
|
||||
static bool DirectoryExists(const TString DirectoryName);
|
||||
|
||||
static bool DeleteFile(const TString FileName);
|
||||
static bool DeleteDirectory(const TString DirectoryName);
|
||||
|
||||
static TString ExtractFilePath(TString Path);
|
||||
static TString ExtractFileExt(TString Path);
|
||||
static TString ExtractFileName(TString Path);
|
||||
static TString ChangeFileExt(TString Path, TString Extension);
|
||||
|
||||
static TString IncludeTrailingSeparator(const TString value);
|
||||
static TString IncludeTrailingSeparator(const char* value);
|
||||
static TString IncludeTrailingSeparator(const wchar_t* value);
|
||||
static TString FixPathForPlatform(TString Path);
|
||||
static TString FixPathSeparatorForPlatform(TString Path);
|
||||
static TString PathSeparator();
|
||||
|
||||
static bool CreateDirectory(TString Path, bool ownerOnly);
|
||||
static void ChangePermissions(TString FileName, bool ownerOnly);
|
||||
};
|
||||
|
||||
#endif //FILEPATH_H
|
@ -1,240 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2019, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#include "Helpers.h"
|
||||
#include "PlatformString.h"
|
||||
#include "PropertyFile.h"
|
||||
|
||||
|
||||
bool Helpers::SplitOptionIntoNameValue(
|
||||
TString option, TString& Name, TString& Value) {
|
||||
bool hasValue = false;
|
||||
Name = _T("");
|
||||
Value = _T("");
|
||||
unsigned int index = 0;
|
||||
|
||||
for (; index < option.length(); index++) {
|
||||
TCHAR c = option[index];
|
||||
|
||||
switch (c) {
|
||||
case '=': {
|
||||
index++;
|
||||
hasValue = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case '\\': {
|
||||
if (index + 1 < option.length()) {
|
||||
c = option[index + 1];
|
||||
|
||||
switch (c) {
|
||||
case '\\': {
|
||||
index++;
|
||||
Name += '\\';
|
||||
break;
|
||||
}
|
||||
|
||||
case '=': {
|
||||
index++;
|
||||
Name += '=';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
default: {
|
||||
Name += c;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (hasValue) {
|
||||
Value = option.substr(index, index - option.length());
|
||||
}
|
||||
|
||||
return (option.length() > 0);
|
||||
}
|
||||
|
||||
|
||||
TString Helpers::ReplaceString(TString subject, const TString& search,
|
||||
const TString& replace) {
|
||||
size_t pos = 0;
|
||||
while((pos = subject.find(search, pos)) != TString::npos) {
|
||||
subject.replace(pos, search.length(), replace);
|
||||
pos += replace.length();
|
||||
}
|
||||
return subject;
|
||||
}
|
||||
|
||||
TString Helpers::ConvertIdToFilePath(TString Value) {
|
||||
TString search;
|
||||
search = '.';
|
||||
TString replace;
|
||||
replace = '/';
|
||||
TString result = ReplaceString(Value, search, replace);
|
||||
return result;
|
||||
}
|
||||
|
||||
TString Helpers::ConvertIdToJavaPath(TString Value) {
|
||||
TString search;
|
||||
search = '.';
|
||||
TString replace;
|
||||
replace = '/';
|
||||
TString result = ReplaceString(Value, search, replace);
|
||||
search = '\\';
|
||||
result = ReplaceString(result, search, replace);
|
||||
return result;
|
||||
}
|
||||
|
||||
TString Helpers::ConvertJavaPathToId(TString Value) {
|
||||
TString search;
|
||||
search = '/';
|
||||
TString replace;
|
||||
replace = '.';
|
||||
TString result = ReplaceString(Value, search, replace);
|
||||
return result;
|
||||
}
|
||||
|
||||
OrderedMap<TString, TString>
|
||||
Helpers::GetJavaOptionsFromConfig(IPropertyContainer* config) {
|
||||
OrderedMap<TString, TString> result;
|
||||
|
||||
for (unsigned int index = 0; index < config->GetCount(); index++) {
|
||||
TString argname =
|
||||
TString(_T("jvmarg.")) + PlatformString(index + 1).toString();
|
||||
TString argvalue;
|
||||
|
||||
if (config->GetValue(argname, argvalue) == false) {
|
||||
break;
|
||||
}
|
||||
else if (argvalue.empty() == false) {
|
||||
TString name;
|
||||
TString value;
|
||||
if (Helpers::SplitOptionIntoNameValue(argvalue, name, value)) {
|
||||
result.Append(name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::list<TString> Helpers::GetArgsFromConfig(IPropertyContainer* config) {
|
||||
std::list<TString> result;
|
||||
|
||||
for (unsigned int index = 0; index < config->GetCount(); index++) {
|
||||
TString argname = TString(_T("arg."))
|
||||
+ PlatformString(index + 1).toString();
|
||||
TString argvalue;
|
||||
|
||||
if (config->GetValue(argname, argvalue) == false) {
|
||||
break;
|
||||
}
|
||||
else if (argvalue.empty() == false) {
|
||||
result.push_back((argvalue));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::list<TString>
|
||||
Helpers::MapToNameValueList(OrderedMap<TString, TString> Map) {
|
||||
std::list<TString> result;
|
||||
std::vector<TString> keys = Map.GetKeys();
|
||||
|
||||
for (OrderedMap<TString, TString>::const_iterator iterator = Map.begin();
|
||||
iterator != Map.end(); iterator++) {
|
||||
JPPair<TString, TString> *item = *iterator;
|
||||
TString key = item->first;
|
||||
TString value = item->second;
|
||||
|
||||
if (value.length() == 0) {
|
||||
result.push_back(key);
|
||||
} else {
|
||||
result.push_back(key + _T('=') + value);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
TString Helpers::NameValueToString(TString name, TString value) {
|
||||
TString result;
|
||||
|
||||
if (value.empty() == true) {
|
||||
result = name;
|
||||
}
|
||||
else {
|
||||
result = name + TString(_T("=")) + value;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::list<TString> Helpers::StringToArray(TString Value) {
|
||||
std::list<TString> result;
|
||||
TString line;
|
||||
|
||||
for (unsigned int index = 0; index < Value.length(); index++) {
|
||||
TCHAR c = Value[index];
|
||||
|
||||
switch (c) {
|
||||
case '\n': {
|
||||
result.push_back(line);
|
||||
line = _T("");
|
||||
break;
|
||||
}
|
||||
|
||||
case '\r': {
|
||||
result.push_back(line);
|
||||
line = _T("");
|
||||
|
||||
if (Value[index + 1] == '\n')
|
||||
index++;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
line += c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The buffer may not have ended with a Carriage Return/Line Feed.
|
||||
if (line.length() > 0) {
|
||||
result.push_back(line);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2019, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#ifndef HELPERS_H
|
||||
#define HELPERS_H
|
||||
|
||||
#include "Platform.h"
|
||||
#include "OrderedMap.h"
|
||||
#include "IniFile.h"
|
||||
|
||||
|
||||
class Helpers {
|
||||
private:
|
||||
Helpers(void) {}
|
||||
~Helpers(void) {}
|
||||
|
||||
public:
|
||||
// Supports two formats for option:
|
||||
// Example 1:
|
||||
// foo=bar
|
||||
//
|
||||
// Example 2:
|
||||
// <name=foo=, value=goo>
|
||||
static bool SplitOptionIntoNameValue(TString option,
|
||||
TString& Name, TString& Value);
|
||||
static TString ReplaceString(TString subject, const TString& search,
|
||||
const TString& replace);
|
||||
static TString ConvertIdToFilePath(TString Value);
|
||||
static TString ConvertIdToJavaPath(TString Value);
|
||||
static TString ConvertJavaPathToId(TString Value);
|
||||
|
||||
static OrderedMap<TString, TString>
|
||||
GetJavaOptionsFromConfig(IPropertyContainer* config);
|
||||
static std::list<TString> GetArgsFromConfig(IPropertyContainer* config);
|
||||
|
||||
static std::list<TString>
|
||||
MapToNameValueList(OrderedMap<TString, TString> Map);
|
||||
|
||||
static TString NameValueToString(TString name, TString value);
|
||||
|
||||
static std::list<TString> StringToArray(TString Value);
|
||||
};
|
||||
|
||||
#endif // HELPERS_H
|
@ -1,261 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2019, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#include "IniFile.h"
|
||||
#include "Helpers.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
|
||||
IniFile::IniFile() : ISectionalPropertyContainer() {
|
||||
}
|
||||
|
||||
IniFile::~IniFile() {
|
||||
for (OrderedMap<TString, IniSectionData*>::iterator iterator =
|
||||
FMap.begin(); iterator != FMap.end(); iterator++) {
|
||||
JPPair<TString, IniSectionData*> *item = *iterator;
|
||||
delete item->second;
|
||||
}
|
||||
}
|
||||
|
||||
bool IniFile::LoadFromFile(const TString FileName) {
|
||||
bool result = false;
|
||||
Platform& platform = Platform::GetInstance();
|
||||
|
||||
std::list<TString> contents = platform.LoadFromFile(FileName);
|
||||
|
||||
if (contents.empty() == false) {
|
||||
bool found = false;
|
||||
|
||||
// Determine the if file is an INI file or property file.
|
||||
// Assign FDefaultSection if it is
|
||||
// an INI file. Otherwise FDefaultSection is NULL.
|
||||
for (std::list<TString>::const_iterator iterator = contents.begin();
|
||||
iterator != contents.end(); iterator++) {
|
||||
TString line = *iterator;
|
||||
|
||||
if (line[0] == ';') {
|
||||
// Semicolon is a comment so ignore the line.
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
if (line[0] == '[') {
|
||||
found = true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found == true) {
|
||||
TString sectionName;
|
||||
|
||||
for (std::list<TString>::const_iterator iterator = contents.begin();
|
||||
iterator != contents.end(); iterator++) {
|
||||
TString line = *iterator;
|
||||
|
||||
if (line[0] == ';') {
|
||||
// Semicolon is a comment so ignore the line.
|
||||
continue;
|
||||
}
|
||||
else if (line[0] == '[' && line[line.length() - 1] == ']') {
|
||||
sectionName = line.substr(1, line.size() - 2);
|
||||
}
|
||||
else if (sectionName.empty() == false) {
|
||||
TString name;
|
||||
TString value;
|
||||
|
||||
if (Helpers::SplitOptionIntoNameValue(
|
||||
line, name, value) == true) {
|
||||
Append(sectionName, name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool IniFile::SaveToFile(const TString FileName, bool ownerOnly) {
|
||||
bool result = false;
|
||||
|
||||
std::list<TString> contents;
|
||||
std::vector<TString> keys = FMap.GetKeys();
|
||||
|
||||
for (unsigned int index = 0; index < keys.size(); index++) {
|
||||
TString name = keys[index];
|
||||
IniSectionData *section = NULL;
|
||||
|
||||
if (FMap.GetValue(name, section) == true && section != NULL) {
|
||||
contents.push_back(_T("[") + name + _T("]"));
|
||||
std::list<TString> lines = section->GetLines();
|
||||
contents.insert(contents.end(), lines.begin(), lines.end());
|
||||
contents.push_back(_T(""));
|
||||
}
|
||||
}
|
||||
|
||||
Platform& platform = Platform::GetInstance();
|
||||
platform.SaveToFile(FileName, contents, ownerOnly);
|
||||
result = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
void IniFile::Append(const TString SectionName,
|
||||
const TString Key, TString Value) {
|
||||
if (FMap.ContainsKey(SectionName) == true) {
|
||||
IniSectionData* section = NULL;
|
||||
|
||||
if (FMap.GetValue(SectionName, section) == true && section != NULL) {
|
||||
section->SetValue(Key, Value);
|
||||
}
|
||||
}
|
||||
else {
|
||||
IniSectionData *section = new IniSectionData();
|
||||
section->SetValue(Key, Value);
|
||||
FMap.Append(SectionName, section);
|
||||
}
|
||||
}
|
||||
|
||||
void IniFile::AppendSection(const TString SectionName,
|
||||
OrderedMap<TString, TString> Values) {
|
||||
if (FMap.ContainsKey(SectionName) == true) {
|
||||
IniSectionData* section = NULL;
|
||||
|
||||
if (FMap.GetValue(SectionName, section) == true && section != NULL) {
|
||||
section->Append(Values);
|
||||
}
|
||||
}
|
||||
else {
|
||||
IniSectionData *section = new IniSectionData(Values);
|
||||
FMap.Append(SectionName, section);
|
||||
}
|
||||
}
|
||||
|
||||
bool IniFile::GetValue(const TString SectionName,
|
||||
const TString Key, TString& Value) {
|
||||
bool result = false;
|
||||
IniSectionData* section = NULL;
|
||||
|
||||
if (FMap.GetValue(SectionName, section) == true && section != NULL) {
|
||||
result = section->GetValue(Key, Value);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool IniFile::SetValue(const TString SectionName,
|
||||
const TString Key, TString Value) {
|
||||
bool result = false;
|
||||
IniSectionData* section = NULL;
|
||||
|
||||
if (FMap.GetValue(SectionName, section) && section != NULL) {
|
||||
result = section->SetValue(Key, Value);
|
||||
}
|
||||
else {
|
||||
Append(SectionName, Key, Value);
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool IniFile::GetSection(const TString SectionName,
|
||||
OrderedMap<TString, TString> &Data) {
|
||||
bool result = false;
|
||||
|
||||
if (FMap.ContainsKey(SectionName) == true) {
|
||||
IniSectionData* section = NULL;
|
||||
|
||||
if (FMap.GetValue(SectionName, section) == true && section != NULL) {
|
||||
OrderedMap<TString, TString> data = section->GetData();
|
||||
Data.Append(data);
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool IniFile::ContainsSection(const TString SectionName) {
|
||||
return FMap.ContainsKey(SectionName);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
IniSectionData::IniSectionData() {
|
||||
FMap.SetAllowDuplicates(true);
|
||||
}
|
||||
|
||||
IniSectionData::IniSectionData(OrderedMap<TString, TString> Values) {
|
||||
FMap = Values;
|
||||
}
|
||||
|
||||
std::vector<TString> IniSectionData::GetKeys() {
|
||||
return FMap.GetKeys();
|
||||
}
|
||||
|
||||
std::list<TString> IniSectionData::GetLines() {
|
||||
std::list<TString> result;
|
||||
std::vector<TString> keys = FMap.GetKeys();
|
||||
|
||||
for (unsigned int index = 0; index < keys.size(); index++) {
|
||||
TString name = keys[index];
|
||||
TString value;
|
||||
|
||||
if (FMap.GetValue(name, value) == true) {
|
||||
name = Helpers::ReplaceString(name, _T("="), _T("\\="));
|
||||
value = Helpers::ReplaceString(value, _T("="), _T("\\="));
|
||||
|
||||
TString line = name + _T('=') + value;
|
||||
result.push_back(line);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
OrderedMap<TString, TString> IniSectionData::GetData() {
|
||||
OrderedMap<TString, TString> result = FMap;
|
||||
return result;
|
||||
}
|
||||
|
||||
bool IniSectionData::GetValue(const TString Key, TString& Value) {
|
||||
return FMap.GetValue(Key, Value);
|
||||
}
|
||||
|
||||
bool IniSectionData::SetValue(const TString Key, TString Value) {
|
||||
return FMap.SetValue(Key, Value);
|
||||
}
|
||||
|
||||
void IniSectionData::Append(OrderedMap<TString, TString> Values) {
|
||||
FMap.Append(Values);
|
||||
}
|
||||
|
||||
size_t IniSectionData::GetCount() {
|
||||
return FMap.Count();
|
||||
}
|
@ -1,82 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2019, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#ifndef INIFILE_H
|
||||
#define INIFILE_H
|
||||
|
||||
#include "Platform.h"
|
||||
#include "OrderedMap.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
|
||||
class IniSectionData : public IPropertyContainer {
|
||||
private:
|
||||
OrderedMap<TString, TString> FMap;
|
||||
|
||||
public:
|
||||
IniSectionData();
|
||||
IniSectionData(OrderedMap<TString, TString> Values);
|
||||
|
||||
std::vector<TString> GetKeys();
|
||||
std::list<TString> GetLines();
|
||||
OrderedMap<TString, TString> GetData();
|
||||
|
||||
bool SetValue(const TString Key, TString Value);
|
||||
void Append(OrderedMap<TString, TString> Values);
|
||||
|
||||
virtual bool GetValue(const TString Key, TString& Value);
|
||||
virtual size_t GetCount();
|
||||
};
|
||||
|
||||
|
||||
class IniFile : public ISectionalPropertyContainer {
|
||||
private:
|
||||
OrderedMap<TString, IniSectionData*> FMap;
|
||||
|
||||
public:
|
||||
IniFile();
|
||||
virtual ~IniFile();
|
||||
|
||||
void internalTest();
|
||||
|
||||
bool LoadFromFile(const TString FileName);
|
||||
bool SaveToFile(const TString FileName, bool ownerOnly = true);
|
||||
|
||||
void Append(const TString SectionName, const TString Key, TString Value);
|
||||
void AppendSection(const TString SectionName,
|
||||
OrderedMap<TString, TString> Values);
|
||||
bool SetValue(const TString SectionName,
|
||||
const TString Key, TString Value);
|
||||
|
||||
// ISectionalPropertyContainer
|
||||
virtual bool GetSection(const TString SectionName,
|
||||
OrderedMap<TString, TString> &Data);
|
||||
virtual bool ContainsSection(const TString SectionName);
|
||||
virtual bool GetValue(const TString SectionName,
|
||||
const TString Key, TString& Value);
|
||||
};
|
||||
|
||||
#endif // INIFILE_H
|
@ -1,318 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2019, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#include "JavaVirtualMachine.h"
|
||||
#include "Platform.h"
|
||||
#include "PlatformString.h"
|
||||
#include "FilePath.h"
|
||||
#include "Package.h"
|
||||
#include "Helpers.h"
|
||||
#include "Messages.h"
|
||||
#include "Macros.h"
|
||||
|
||||
#include "jni.h"
|
||||
|
||||
#include <map>
|
||||
#include <list>
|
||||
#include <sstream>
|
||||
|
||||
|
||||
bool RunVM() {
|
||||
JavaVirtualMachine javavm;
|
||||
|
||||
bool result = javavm.StartJVM();
|
||||
|
||||
if (!result) {
|
||||
Platform& platform = Platform::GetInstance();
|
||||
platform.ShowMessage(_T("Failed to launch JVM\n"));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
JavaOptions::JavaOptions(): FOptions(NULL) {
|
||||
}
|
||||
|
||||
JavaOptions::~JavaOptions() {
|
||||
if (FOptions != NULL) {
|
||||
for (unsigned int index = 0; index < GetCount(); index++) {
|
||||
delete[] FOptions[index].optionString;
|
||||
}
|
||||
|
||||
delete[] FOptions;
|
||||
}
|
||||
}
|
||||
|
||||
void JavaOptions::AppendValue(const TString Key, TString Value, void* Extra) {
|
||||
JavaOptionItem item;
|
||||
item.name = Key;
|
||||
item.value = Value;
|
||||
item.extraInfo = Extra;
|
||||
FItems.push_back(item);
|
||||
}
|
||||
|
||||
void JavaOptions::AppendValue(const TString Key, TString Value) {
|
||||
AppendValue(Key, Value, NULL);
|
||||
}
|
||||
|
||||
void JavaOptions::AppendValue(const TString Key) {
|
||||
AppendValue(Key, _T(""), NULL);
|
||||
}
|
||||
|
||||
void JavaOptions::AppendValues(OrderedMap<TString, TString> Values) {
|
||||
if (Values.GetAllowDuplicates()) {
|
||||
for (int i = 0; i < (int)Values.Count(); i++) {
|
||||
TString name, value;
|
||||
|
||||
bool bResult = Values.GetKey(i, name);
|
||||
bResult &= Values.GetValue(i, value);
|
||||
|
||||
if (bResult) {
|
||||
AppendValue(name, value);
|
||||
}
|
||||
}
|
||||
} else { // In case we asked to add values from OrderedMap with allow
|
||||
// duplicates set to false. Not used now, but should avoid possible
|
||||
// bugs.
|
||||
std::vector<TString> orderedKeys = Values.GetKeys();
|
||||
|
||||
for (std::vector<TString>::const_iterator iterator = orderedKeys.begin();
|
||||
iterator != orderedKeys.end(); iterator++) {
|
||||
TString name = *iterator;
|
||||
TString value;
|
||||
|
||||
if (Values.GetValue(name, value) == true) {
|
||||
AppendValue(name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JavaOptions::ReplaceValue(const TString Key, TString Value) {
|
||||
for (std::list<JavaOptionItem>::iterator iterator = FItems.begin();
|
||||
iterator != FItems.end(); iterator++) {
|
||||
|
||||
TString lkey = iterator->name;
|
||||
|
||||
if (lkey == Key) {
|
||||
JavaOptionItem item = *iterator;
|
||||
item.value = Value;
|
||||
iterator = FItems.erase(iterator);
|
||||
FItems.insert(iterator, item);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::list<TString> JavaOptions::ToList() {
|
||||
std::list<TString> result;
|
||||
Macros& macros = Macros::GetInstance();
|
||||
|
||||
for (std::list<JavaOptionItem>::const_iterator iterator = FItems.begin();
|
||||
iterator != FItems.end(); iterator++) {
|
||||
TString key = iterator->name;
|
||||
TString value = iterator->value;
|
||||
TString option = Helpers::NameValueToString(key, value);
|
||||
option = macros.ExpandMacros(option);
|
||||
result.push_back(option);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t JavaOptions::GetCount() {
|
||||
return FItems.size();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
JavaVirtualMachine::JavaVirtualMachine() {
|
||||
}
|
||||
|
||||
JavaVirtualMachine::~JavaVirtualMachine(void) {
|
||||
}
|
||||
|
||||
bool JavaVirtualMachine::StartJVM() {
|
||||
Platform& platform = Platform::GetInstance();
|
||||
Package& package = Package::GetInstance();
|
||||
|
||||
TString classpath = package.GetClassPath();
|
||||
TString modulepath = package.GetModulePath();
|
||||
JavaOptions options;
|
||||
|
||||
if (modulepath.empty() == false) {
|
||||
options.AppendValue(_T("-Djava.module.path"), modulepath);
|
||||
}
|
||||
|
||||
options.AppendValue(_T("-Djava.library.path"),
|
||||
package.GetPackageAppDirectory() + FilePath::PathSeparator()
|
||||
+ package.GetPackageLauncherDirectory());
|
||||
options.AppendValue(
|
||||
_T("-Djava.launcher.path"), package.GetPackageLauncherDirectory());
|
||||
options.AppendValues(package.GetJavaOptions());
|
||||
|
||||
#ifdef DEBUG
|
||||
if (package.Debugging() == dsJava) {
|
||||
options.AppendValue(_T("-Xdebug"), _T(""));
|
||||
options.AppendValue(
|
||||
_T("-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=localhost:5005"),
|
||||
_T(""));
|
||||
platform.ShowMessage(_T("localhost:5005"));
|
||||
}
|
||||
#endif // DEBUG
|
||||
|
||||
TString maxHeapSizeOption;
|
||||
TString minHeapSizeOption;
|
||||
|
||||
|
||||
if (package.GetMemoryState() == PackageBootFields::msAuto) {
|
||||
TPlatformNumber memorySize = package.GetMemorySize();
|
||||
TString memory =
|
||||
PlatformString((size_t)memorySize).toString() + _T("m");
|
||||
maxHeapSizeOption = TString(_T("-Xmx")) + memory;
|
||||
options.AppendValue(maxHeapSizeOption, _T(""));
|
||||
|
||||
if (memorySize > 256)
|
||||
minHeapSizeOption = _T("-Xms256m");
|
||||
else
|
||||
minHeapSizeOption = _T("-Xms") + memory;
|
||||
|
||||
options.AppendValue(minHeapSizeOption, _T(""));
|
||||
}
|
||||
|
||||
TString mainClassName = package.GetMainClassName();
|
||||
TString mainModule = package.GetMainModule();
|
||||
|
||||
if (mainClassName.empty() == true && mainModule.empty() == true) {
|
||||
Messages& messages = Messages::GetInstance();
|
||||
platform.ShowMessage(messages.GetMessage(NO_MAIN_CLASS_SPECIFIED));
|
||||
return false;
|
||||
}
|
||||
|
||||
configureLibrary();
|
||||
|
||||
// Initialize the arguments to JLI_Launch()
|
||||
//
|
||||
// On Mac OS X JLI_Launch spawns a new thread that actually starts the JVM.
|
||||
// This new thread simply re-runs main(argc, argv). Therefore we do not
|
||||
// want to add new args if we are still in the original main thread so we
|
||||
// will treat them as command line args provided by the user ...
|
||||
// Only propagate original set of args first time.
|
||||
|
||||
options.AppendValue(_T("-classpath"));
|
||||
options.AppendValue(classpath);
|
||||
|
||||
std::list<TString> vmargs;
|
||||
vmargs.push_back(package.GetCommandName());
|
||||
|
||||
if (package.HasSplashScreen() == true) {
|
||||
options.AppendValue(TString(_T("-splash:"))
|
||||
+ package.GetSplashScreenFileName(), _T(""));
|
||||
}
|
||||
|
||||
if (mainModule.empty() == true) {
|
||||
options.AppendValue(Helpers::ConvertJavaPathToId(mainClassName),
|
||||
_T(""));
|
||||
} else {
|
||||
options.AppendValue(_T("-m"));
|
||||
options.AppendValue(mainModule);
|
||||
}
|
||||
|
||||
return launchVM(options, vmargs);
|
||||
}
|
||||
|
||||
void JavaVirtualMachine::configureLibrary() {
|
||||
Platform& platform = Platform::GetInstance();
|
||||
Package& package = Package::GetInstance();
|
||||
TString libName = package.GetJavaLibraryFileName();
|
||||
platform.addPlatformDependencies(&javaLibrary);
|
||||
javaLibrary.Load(libName);
|
||||
}
|
||||
|
||||
bool JavaVirtualMachine::launchVM(JavaOptions& options,
|
||||
std::list<TString>& vmargs) {
|
||||
Platform& platform = Platform::GetInstance();
|
||||
Package& package = Package::GetInstance();
|
||||
|
||||
#ifdef MAC
|
||||
// Mac adds a ProcessSerialNumber to args when launched from .app
|
||||
// filter out the psn since they it's not expected in the app
|
||||
if (platform.IsMainThread() == false) {
|
||||
std::list<TString> loptions = options.ToList();
|
||||
vmargs.splice(vmargs.end(), loptions,
|
||||
loptions.begin(), loptions.end());
|
||||
}
|
||||
#else
|
||||
std::list<TString> loptions = options.ToList();
|
||||
vmargs.splice(vmargs.end(), loptions, loptions.begin(), loptions.end());
|
||||
#endif
|
||||
|
||||
std::list<TString> largs = package.GetArgs();
|
||||
vmargs.splice(vmargs.end(), largs, largs.begin(), largs.end());
|
||||
|
||||
size_t argc = vmargs.size();
|
||||
DynamicBuffer<char*> argv(argc + 1);
|
||||
if (argv.GetData() == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int index = 0;
|
||||
for (std::list<TString>::const_iterator iterator = vmargs.begin();
|
||||
iterator != vmargs.end(); iterator++) {
|
||||
TString item = *iterator;
|
||||
std::string arg = PlatformString(item).toStdString();
|
||||
#ifdef DEBUG
|
||||
printf("%i %s\n", index, arg.c_str());
|
||||
#endif // DEBUG
|
||||
argv[index] = PlatformString::duplicate(arg.c_str());
|
||||
index++;
|
||||
}
|
||||
|
||||
argv[argc] = NULL;
|
||||
|
||||
// On Mac we can only free the boot fields if the calling thread is
|
||||
// not the main thread.
|
||||
#ifdef MAC
|
||||
if (platform.IsMainThread() == false) {
|
||||
package.FreeBootFields();
|
||||
}
|
||||
#else
|
||||
package.FreeBootFields();
|
||||
#endif // MAC
|
||||
|
||||
if (javaLibrary.JavaVMCreate(argc, argv.GetData()) == true) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (index = 0; index < argc; index++) {
|
||||
if (argv[index] != NULL) {
|
||||
delete[] argv[index];
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2019, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#ifndef JAVAVIRTUALMACHINE_H
|
||||
#define JAVAVIRTUALMACHINE_H
|
||||
|
||||
|
||||
#include "jni.h"
|
||||
#include "Platform.h"
|
||||
#include "Library.h"
|
||||
|
||||
struct JavaOptionItem {
|
||||
TString name;
|
||||
TString value;
|
||||
void* extraInfo;
|
||||
};
|
||||
|
||||
class JavaOptions {
|
||||
private:
|
||||
std::list<JavaOptionItem> FItems;
|
||||
JavaVMOption* FOptions;
|
||||
|
||||
public:
|
||||
JavaOptions();
|
||||
~JavaOptions();
|
||||
|
||||
void AppendValue(const TString Key, TString Value, void* Extra);
|
||||
void AppendValue(const TString Key, TString Value);
|
||||
void AppendValue(const TString Key);
|
||||
void AppendValues(OrderedMap<TString, TString> Values);
|
||||
void ReplaceValue(const TString Key, TString Value);
|
||||
std::list<TString> ToList();
|
||||
size_t GetCount();
|
||||
};
|
||||
|
||||
class JavaVirtualMachine {
|
||||
private:
|
||||
JavaLibrary javaLibrary;
|
||||
|
||||
void configureLibrary();
|
||||
bool launchVM(JavaOptions& options, std::list<TString>& vmargs);
|
||||
public:
|
||||
JavaVirtualMachine();
|
||||
~JavaVirtualMachine(void);
|
||||
|
||||
bool StartJVM();
|
||||
};
|
||||
|
||||
bool RunVM();
|
||||
|
||||
#endif // JAVAVIRTUALMACHINE_H
|
@ -1,188 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2019, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#include "Library.h"
|
||||
#include "Platform.h"
|
||||
#include "Messages.h"
|
||||
#include "PlatformString.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <locale>
|
||||
|
||||
Library::Library() {
|
||||
Initialize();
|
||||
}
|
||||
|
||||
Library::Library(const TString &FileName) {
|
||||
Initialize();
|
||||
Load(FileName);
|
||||
}
|
||||
|
||||
Library::~Library() {
|
||||
Unload();
|
||||
}
|
||||
|
||||
void Library::Initialize() {
|
||||
FModule = NULL;
|
||||
FDependentLibraryNames = NULL;
|
||||
FDependenciesLibraries = NULL;
|
||||
}
|
||||
|
||||
void Library::InitializeDependencies() {
|
||||
if (FDependentLibraryNames == NULL) {
|
||||
FDependentLibraryNames = new std::vector<TString>();
|
||||
}
|
||||
|
||||
if (FDependenciesLibraries == NULL) {
|
||||
FDependenciesLibraries = new std::vector<Library*>();
|
||||
}
|
||||
}
|
||||
|
||||
void Library::LoadDependencies() {
|
||||
if (FDependentLibraryNames != NULL && FDependenciesLibraries != NULL) {
|
||||
for (std::vector<TString>::const_iterator iterator =
|
||||
FDependentLibraryNames->begin();
|
||||
iterator != FDependentLibraryNames->end(); iterator++) {
|
||||
Library* library = new Library();
|
||||
|
||||
if (library->Load(*iterator) == true) {
|
||||
FDependenciesLibraries->push_back(library);
|
||||
}
|
||||
}
|
||||
|
||||
delete FDependentLibraryNames;
|
||||
FDependentLibraryNames = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void Library::UnloadDependencies() {
|
||||
if (FDependenciesLibraries != NULL) {
|
||||
for (std::vector<Library*>::const_iterator iterator =
|
||||
FDependenciesLibraries->begin();
|
||||
iterator != FDependenciesLibraries->end(); iterator++) {
|
||||
Library* library = *iterator;
|
||||
|
||||
if (library != NULL) {
|
||||
library->Unload();
|
||||
delete library;
|
||||
}
|
||||
}
|
||||
|
||||
delete FDependenciesLibraries;
|
||||
FDependenciesLibraries = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
Procedure Library::GetProcAddress(const std::string& MethodName) const {
|
||||
Platform& platform = Platform::GetInstance();
|
||||
return platform.GetProcAddress(FModule, MethodName);
|
||||
}
|
||||
|
||||
bool Library::Load(const TString &FileName) {
|
||||
bool result = true;
|
||||
|
||||
if (FModule == NULL) {
|
||||
LoadDependencies();
|
||||
Platform& platform = Platform::GetInstance();
|
||||
FModule = platform.LoadLibrary(FileName);
|
||||
|
||||
if (FModule == NULL) {
|
||||
Messages& messages = Messages::GetInstance();
|
||||
platform.ShowMessage(messages.GetMessage(LIBRARY_NOT_FOUND),
|
||||
FileName);
|
||||
result = false;
|
||||
} else {
|
||||
fname = PlatformString(FileName).toStdString();
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Library::Unload() {
|
||||
bool result = false;
|
||||
|
||||
if (FModule != NULL) {
|
||||
Platform& platform = Platform::GetInstance();
|
||||
platform.FreeLibrary(FModule);
|
||||
FModule = NULL;
|
||||
UnloadDependencies();
|
||||
result = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void Library::AddDependency(const TString &FileName) {
|
||||
InitializeDependencies();
|
||||
|
||||
if (FDependentLibraryNames != NULL) {
|
||||
FDependentLibraryNames->push_back(FileName);
|
||||
}
|
||||
}
|
||||
|
||||
void Library::AddDependencies(const std::vector<TString> &Dependencies) {
|
||||
if (Dependencies.size() > 0) {
|
||||
InitializeDependencies();
|
||||
|
||||
if (FDependentLibraryNames != NULL) {
|
||||
for (std::vector<TString>::const_iterator iterator =
|
||||
FDependentLibraryNames->begin();
|
||||
iterator != FDependentLibraryNames->end(); iterator++) {
|
||||
TString fileName = *iterator;
|
||||
AddDependency(fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JavaLibrary::JavaLibrary() : Library(), FCreateProc(NULL) {
|
||||
}
|
||||
|
||||
bool JavaLibrary::JavaVMCreate(size_t argc, char *argv[]) {
|
||||
if (FCreateProc == NULL) {
|
||||
FCreateProc = (JAVA_CREATE) GetProcAddress(LAUNCH_FUNC);
|
||||
}
|
||||
|
||||
if (FCreateProc == NULL) {
|
||||
Platform& platform = Platform::GetInstance();
|
||||
Messages& messages = Messages::GetInstance();
|
||||
platform.ShowMessage(
|
||||
messages.GetMessage(FAILED_LOCATING_JVM_ENTRY_POINT));
|
||||
return false;
|
||||
}
|
||||
|
||||
return FCreateProc((int) argc, argv,
|
||||
0, NULL,
|
||||
0, NULL,
|
||||
"",
|
||||
"",
|
||||
"java",
|
||||
"java",
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
0) == 0;
|
||||
}
|
@ -1,106 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2019, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#ifndef LIBRARY_H
|
||||
#define LIBRARY_H
|
||||
|
||||
#include "PlatformDefs.h"
|
||||
//#include "Platform.h"
|
||||
#include "OrderedMap.h"
|
||||
|
||||
#include "jni.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
// Private typedef for function pointer casting
|
||||
|
||||
#if defined(_WIN32) && !defined(_WIN64)
|
||||
#define LAUNCH_FUNC "_JLI_Launch@56"
|
||||
#else
|
||||
#define LAUNCH_FUNC "JLI_Launch"
|
||||
#endif
|
||||
|
||||
|
||||
typedef int (JNICALL *JAVA_CREATE)(int argc, char ** argv,
|
||||
int jargc, const char** jargv,
|
||||
int appclassc, const char** appclassv,
|
||||
const char* fullversion,
|
||||
const char* dotversion,
|
||||
const char* pname,
|
||||
const char* lname,
|
||||
jboolean javaargs,
|
||||
jboolean cpwildcard,
|
||||
jboolean javaw,
|
||||
jint ergo);
|
||||
|
||||
class Library {
|
||||
private:
|
||||
std::vector<TString> *FDependentLibraryNames;
|
||||
std::vector<Library*> *FDependenciesLibraries;
|
||||
Module FModule;
|
||||
std::string fname;
|
||||
|
||||
void Initialize();
|
||||
void InitializeDependencies();
|
||||
void LoadDependencies();
|
||||
void UnloadDependencies();
|
||||
|
||||
public:
|
||||
void* GetProcAddress(const std::string& MethodName) const;
|
||||
|
||||
public:
|
||||
Library();
|
||||
Library(const TString &FileName);
|
||||
~Library();
|
||||
|
||||
bool Load(const TString &FileName);
|
||||
bool Unload();
|
||||
|
||||
const std::string& GetName() const {
|
||||
return fname;
|
||||
}
|
||||
|
||||
void AddDependency(const TString &FileName);
|
||||
void AddDependencies(const std::vector<TString> &Dependencies);
|
||||
};
|
||||
|
||||
class JavaLibrary : public Library {
|
||||
JAVA_CREATE FCreateProc;
|
||||
JavaLibrary(const TString &FileName);
|
||||
public:
|
||||
JavaLibrary();
|
||||
bool JavaVMCreate(size_t argc, char *argv[]);
|
||||
};
|
||||
|
||||
#endif // LIBRARY_H
|
||||
|
@ -1,74 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2019, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#include "Macros.h"
|
||||
#include "Package.h"
|
||||
#include "Helpers.h"
|
||||
|
||||
|
||||
Macros::Macros(void) {
|
||||
}
|
||||
|
||||
Macros::~Macros(void) {
|
||||
}
|
||||
|
||||
void Macros::Initialize() {
|
||||
Package& package = Package::GetInstance();
|
||||
Macros& macros = Macros::GetInstance();
|
||||
|
||||
// Public macros.
|
||||
macros.AddMacro(_T("$ROOTDIR"), package.GetPackageRootDirectory());
|
||||
macros.AddMacro(_T("$APPDIR"), package.GetPackageAppDirectory());
|
||||
macros.AddMacro(_T("$BINDIR"), package.GetPackageLauncherDirectory());
|
||||
}
|
||||
|
||||
Macros& Macros::GetInstance() {
|
||||
static Macros instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
TString Macros::ExpandMacros(TString Value) {
|
||||
TString result = Value;
|
||||
|
||||
for (std::map<TString, TString>::iterator iterator = FData.begin();
|
||||
iterator != FData.end();
|
||||
iterator++) {
|
||||
|
||||
TString name = iterator->first;
|
||||
|
||||
if (Value.find(name) != TString::npos) {
|
||||
TString lvalue = iterator->second;
|
||||
result = Helpers::ReplaceString(Value, name, lvalue);
|
||||
result = ExpandMacros(result);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void Macros::AddMacro(TString Key, TString Value) {
|
||||
FData.insert(std::map<TString, TString>::value_type(Key, Value));
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2019, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#include "Messages.h"
|
||||
#include "Platform.h"
|
||||
#include "FilePath.h"
|
||||
#include "Helpers.h"
|
||||
#include "Macros.h"
|
||||
#include "JavaVirtualMachine.h"
|
||||
|
||||
Messages::Messages(void) {
|
||||
FMessages.SetReadOnly(false);
|
||||
FMessages.SetValue(LIBRARY_NOT_FOUND, _T("Failed to find library."));
|
||||
FMessages.SetValue(FAILED_CREATING_JVM, _T("Failed to create JVM"));
|
||||
FMessages.SetValue(FAILED_LOCATING_JVM_ENTRY_POINT,
|
||||
_T("Failed to locate JLI_Launch"));
|
||||
FMessages.SetValue(NO_MAIN_CLASS_SPECIFIED, _T("No main class specified"));
|
||||
FMessages.SetValue(METHOD_NOT_FOUND, _T("No method %s in class %s."));
|
||||
FMessages.SetValue(CLASS_NOT_FOUND, _T("Class %s not found."));
|
||||
FMessages.SetValue(ERROR_INVOKING_METHOD, _T("Error invoking method."));
|
||||
FMessages.SetValue(APPCDS_CACHE_FILE_NOT_FOUND,
|
||||
_T("Error: AppCDS cache does not exists:\n%s\n"));
|
||||
}
|
||||
|
||||
Messages& Messages::GetInstance() {
|
||||
static Messages instance;
|
||||
// Guaranteed to be destroyed. Instantiated on first use.
|
||||
return instance;
|
||||
}
|
||||
|
||||
Messages::~Messages(void) {
|
||||
}
|
||||
|
||||
TString Messages::GetMessage(const TString Key) {
|
||||
TString result;
|
||||
FMessages.GetValue(Key, result);
|
||||
Macros& macros = Macros::GetInstance();
|
||||
result = macros.ExpandMacros(result);
|
||||
return result;
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2019, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#ifndef MESSAGES_H
|
||||
#define MESSAGES_H
|
||||
|
||||
#include "PropertyFile.h"
|
||||
|
||||
#define LIBRARY_NOT_FOUND _T("library.not.found")
|
||||
#define FAILED_CREATING_JVM _T("failed.creating.jvm")
|
||||
#define FAILED_LOCATING_JVM_ENTRY_POINT _T("failed.locating.jvm.entry.point")
|
||||
#define NO_MAIN_CLASS_SPECIFIED _T("no.main.class.specified")
|
||||
|
||||
#define METHOD_NOT_FOUND _T("method.not.found")
|
||||
#define CLASS_NOT_FOUND _T("class.not.found")
|
||||
#define ERROR_INVOKING_METHOD _T("error.invoking.method")
|
||||
|
||||
#define CONFIG_FILE_NOT_FOUND _T("config.file.not.found")
|
||||
|
||||
#define BUNDLED_JVM_NOT_FOUND _T("bundled.jvm.not.found")
|
||||
|
||||
#define APPCDS_CACHE_FILE_NOT_FOUND _T("appcds.cache.file.not.found")
|
||||
|
||||
class Messages {
|
||||
private:
|
||||
PropertyFile FMessages;
|
||||
|
||||
Messages(void);
|
||||
public:
|
||||
static Messages& GetInstance();
|
||||
~Messages(void);
|
||||
|
||||
TString GetMessage(const TString Key);
|
||||
};
|
||||
|
||||
#endif // MESSAGES_H
|
@ -1,271 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2019, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#ifndef ORDEREDMAP_H
|
||||
#define ORDEREDMAP_H
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <assert.h>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
template <typename _T1, typename _T2>
|
||||
struct JPPair
|
||||
{
|
||||
typedef _T1 first_type;
|
||||
typedef _T2 second_type;
|
||||
|
||||
first_type first;
|
||||
second_type second;
|
||||
|
||||
JPPair(first_type Value1, second_type Value2) {
|
||||
first = Value1;
|
||||
second = Value2;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename TKey, typename TValue>
|
||||
class OrderedMap {
|
||||
public:
|
||||
typedef TKey key_type;
|
||||
typedef TValue mapped_type;
|
||||
typedef JPPair<key_type, mapped_type> container_type;
|
||||
typedef typename std::vector<container_type*>::iterator iterator;
|
||||
typedef typename std::vector<container_type*>::const_iterator const_iterator;
|
||||
|
||||
private:
|
||||
typedef std::map<key_type, container_type*> map_type;
|
||||
typedef std::vector<container_type*> list_type;
|
||||
|
||||
map_type FMap;
|
||||
list_type FList;
|
||||
bool FAllowDuplicates;
|
||||
|
||||
typename list_type::iterator FindListItem(const key_type Key) {
|
||||
typename list_type::iterator result = FList.end();
|
||||
|
||||
for (typename list_type::iterator iterator =
|
||||
FList.begin(); iterator != FList.end(); iterator++) {
|
||||
container_type *item = *iterator;
|
||||
|
||||
if (item->first == Key) {
|
||||
result = iterator;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public:
|
||||
OrderedMap() {
|
||||
FAllowDuplicates = false;
|
||||
}
|
||||
|
||||
OrderedMap(const OrderedMap<key_type, mapped_type> &Value) {
|
||||
Append(Value);
|
||||
FAllowDuplicates = Value.GetAllowDuplicates();
|
||||
}
|
||||
|
||||
~OrderedMap() {
|
||||
Clear();
|
||||
}
|
||||
|
||||
void SetAllowDuplicates(bool Value) {
|
||||
FAllowDuplicates = Value;
|
||||
}
|
||||
|
||||
bool GetAllowDuplicates() const {
|
||||
return FAllowDuplicates;
|
||||
}
|
||||
|
||||
iterator begin() {
|
||||
return FList.begin();
|
||||
}
|
||||
|
||||
const_iterator begin() const {
|
||||
return FList.begin();
|
||||
}
|
||||
|
||||
iterator end() {
|
||||
return FList.end();
|
||||
}
|
||||
|
||||
const_iterator end() const {
|
||||
return FList.end();
|
||||
}
|
||||
|
||||
void Clear() {
|
||||
for (typename list_type::iterator iterator =
|
||||
FList.begin(); iterator != FList.end(); iterator++) {
|
||||
container_type *item = *iterator;
|
||||
|
||||
if (item != NULL) {
|
||||
delete item;
|
||||
item = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
FMap.clear();
|
||||
FList.clear();
|
||||
}
|
||||
|
||||
bool ContainsKey(key_type Key) {
|
||||
bool result = false;
|
||||
|
||||
if (FMap.find(Key) != FMap.end()) {
|
||||
result = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<key_type> GetKeys() {
|
||||
std::vector<key_type> result;
|
||||
|
||||
for (typename list_type::const_iterator iterator = FList.begin();
|
||||
iterator != FList.end(); iterator++) {
|
||||
container_type *item = *iterator;
|
||||
result.push_back(item->first);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void Assign(const OrderedMap<key_type, mapped_type> &Value) {
|
||||
Clear();
|
||||
Append(Value);
|
||||
}
|
||||
|
||||
void Append(const OrderedMap<key_type, mapped_type> &Value) {
|
||||
for (size_t index = 0; index < Value.FList.size(); index++) {
|
||||
container_type *item = Value.FList[index];
|
||||
Append(item->first, item->second);
|
||||
}
|
||||
}
|
||||
|
||||
void Append(key_type Key, mapped_type Value) {
|
||||
container_type *item = new container_type(Key, Value);
|
||||
FMap.insert(std::pair<key_type, container_type*>(Key, item));
|
||||
FList.push_back(item);
|
||||
}
|
||||
|
||||
bool RemoveByKey(key_type Key) {
|
||||
bool result = false;
|
||||
typename list_type::iterator iterator = FindListItem(Key);
|
||||
|
||||
if (iterator != FList.end()) {
|
||||
FMap.erase(Key);
|
||||
FList.erase(iterator);
|
||||
result = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool GetValue(key_type Key, mapped_type &Value) {
|
||||
bool result = false;
|
||||
container_type* item = FMap[Key];
|
||||
|
||||
if (item != NULL) {
|
||||
Value = item->second;
|
||||
result = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool SetValue(key_type Key, mapped_type &Value) {
|
||||
bool result = false;
|
||||
|
||||
if ((FAllowDuplicates == false) && (ContainsKey(Key) == true)) {
|
||||
container_type *item = FMap[Key];
|
||||
|
||||
if (item != NULL) {
|
||||
item->second = Value;
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Append(Key, Value);
|
||||
result = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool GetKey(int index, key_type &Value) {
|
||||
if (index < 0 || index >= (int)FList.size()) {
|
||||
return false;
|
||||
}
|
||||
container_type *item = FList.at(index);
|
||||
if (item != NULL) {
|
||||
Value = item->first;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GetValue(int index, mapped_type &Value) {
|
||||
if (index < 0 || index >= (int)FList.size()) {
|
||||
return false;
|
||||
}
|
||||
container_type *item = FList.at(index);
|
||||
if (item != NULL) {
|
||||
Value = item->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
mapped_type &operator[](key_type Key) {
|
||||
container_type* item = FMap[Key];
|
||||
assert(item != NULL);
|
||||
|
||||
if (item != NULL) {
|
||||
return item->second;
|
||||
}
|
||||
|
||||
throw std::invalid_argument("Key not found");
|
||||
}
|
||||
|
||||
OrderedMap& operator= (OrderedMap &Value) {
|
||||
Clear();
|
||||
FAllowDuplicates = Value.GetAllowDuplicates();
|
||||
Append(Value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
size_t Count() {
|
||||
return FList.size();
|
||||
}
|
||||
};
|
||||
|
||||
#endif // ORDEREDMAP_H
|
@ -1,557 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2019, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#include "Package.h"
|
||||
#include "Helpers.h"
|
||||
#include "Macros.h"
|
||||
#include "IniFile.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
Package::Package(void) {
|
||||
FInitialized = false;
|
||||
Initialize();
|
||||
}
|
||||
|
||||
TPlatformNumber StringToPercentageOfNumber(TString Value,
|
||||
TPlatformNumber Number) {
|
||||
TPlatformNumber result = 0;
|
||||
size_t percentage = atoi(PlatformString(Value.c_str()));
|
||||
|
||||
if (percentage > 0 && Number > 0) {
|
||||
result = Number * percentage / 100;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void Package::Initialize() {
|
||||
if (FInitialized == true) {
|
||||
return;
|
||||
}
|
||||
|
||||
Platform& platform = Platform::GetInstance();
|
||||
|
||||
FBootFields = new PackageBootFields();
|
||||
FDebugging = dsNone;
|
||||
|
||||
// Allow duplicates for Java options, so we can have multiple --add-exports
|
||||
// or similar args.
|
||||
FBootFields->FJavaOptions.SetAllowDuplicates(true);
|
||||
FBootFields->FPackageRootDirectory = platform.GetPackageRootDirectory();
|
||||
FBootFields->FPackageAppDirectory = platform.GetPackageAppDirectory();
|
||||
FBootFields->FPackageLauncherDirectory =
|
||||
platform.GetPackageLauncherDirectory();
|
||||
FBootFields->FAppDataDirectory = platform.GetAppDataDirectory();
|
||||
|
||||
std::map<TString, TString> keys = platform.GetKeys();
|
||||
|
||||
// Read from configure.cfg/Info.plist
|
||||
AutoFreePtr<ISectionalPropertyContainer> config =
|
||||
platform.GetConfigFile(platform.GetConfigFileName());
|
||||
|
||||
config->GetValue(keys[CONFIG_SECTION_APPLICATION],
|
||||
keys[JPACKAGE_APP_DATA_DIR], FBootFields->FPackageAppDataDirectory);
|
||||
FBootFields->FPackageAppDataDirectory =
|
||||
FilePath::FixPathForPlatform(FBootFields->FPackageAppDataDirectory);
|
||||
|
||||
// Main JAR.
|
||||
config->GetValue(keys[CONFIG_SECTION_APPLICATION],
|
||||
keys[CONFIG_MAINJAR_KEY], FBootFields->FMainJar);
|
||||
FBootFields->FMainJar = FilePath::FixPathForPlatform(FBootFields->FMainJar);
|
||||
|
||||
// Main Module.
|
||||
config->GetValue(keys[CONFIG_SECTION_APPLICATION],
|
||||
keys[CONFIG_MAINMODULE_KEY], FBootFields->FMainModule);
|
||||
|
||||
// Classpath.
|
||||
// 1. If the provided class path contains main jar then only use
|
||||
// provided class path.
|
||||
// 2. If class path provided by config file is empty then add main jar.
|
||||
// 3. If main jar is not in provided class path then add it.
|
||||
config->GetValue(keys[CONFIG_SECTION_APPLICATION],
|
||||
keys[CONFIG_CLASSPATH_KEY], FBootFields->FClassPath);
|
||||
FBootFields->FClassPath =
|
||||
FilePath::FixPathSeparatorForPlatform(FBootFields->FClassPath);
|
||||
|
||||
if (FBootFields->FClassPath.empty() == true) {
|
||||
FBootFields->FClassPath = GetMainJar();
|
||||
} else if (FBootFields->FClassPath.find(GetMainJar()) == TString::npos) {
|
||||
FBootFields->FClassPath = GetMainJar()
|
||||
+ FilePath::PathSeparator() + FBootFields->FClassPath;
|
||||
}
|
||||
|
||||
// Modulepath.
|
||||
config->GetValue(keys[CONFIG_SECTION_APPLICATION],
|
||||
keys[CONFIG_MODULEPATH_KEY], FBootFields->FModulePath);
|
||||
FBootFields->FModulePath =
|
||||
FilePath::FixPathSeparatorForPlatform(FBootFields->FModulePath);
|
||||
|
||||
// Main Class.
|
||||
config->GetValue(keys[CONFIG_SECTION_APPLICATION],
|
||||
keys[CONFIG_MAINCLASSNAME_KEY], FBootFields->FMainClassName);
|
||||
|
||||
// Splash Screen.
|
||||
if (config->GetValue(keys[CONFIG_SECTION_APPLICATION],
|
||||
keys[CONFIG_SPLASH_KEY],
|
||||
FBootFields->FSplashScreenFileName) == true) {
|
||||
FBootFields->FSplashScreenFileName =
|
||||
FilePath::IncludeTrailingSeparator(GetPackageAppDirectory())
|
||||
+ FilePath::FixPathForPlatform(FBootFields->FSplashScreenFileName);
|
||||
|
||||
if (FilePath::FileExists(FBootFields->FSplashScreenFileName) == false) {
|
||||
FBootFields->FSplashScreenFileName = _T("");
|
||||
}
|
||||
}
|
||||
|
||||
// Runtime.
|
||||
config->GetValue(keys[CONFIG_SECTION_APPLICATION],
|
||||
keys[JAVA_RUNTIME_KEY], FBootFields->FJavaRuntimeDirectory);
|
||||
|
||||
// Read jvmargs.
|
||||
PromoteAppCDSState(config);
|
||||
ReadJavaOptions(config);
|
||||
|
||||
// Read args if none were passed in.
|
||||
if (FBootFields->FArgs.size() == 0) {
|
||||
OrderedMap<TString, TString> args;
|
||||
|
||||
if (config->GetSection(keys[CONFIG_SECTION_ARGOPTIONS], args) == true) {
|
||||
FBootFields->FArgs = Helpers::MapToNameValueList(args);
|
||||
}
|
||||
}
|
||||
|
||||
// Auto Memory.
|
||||
TString autoMemory;
|
||||
|
||||
if (config->GetValue(keys[CONFIG_SECTION_APPLICATION],
|
||||
keys[CONFIG_APP_MEMORY], autoMemory) == true) {
|
||||
if (autoMemory == _T("auto") || autoMemory == _T("100%")) {
|
||||
FBootFields->FMemoryState = PackageBootFields::msAuto;
|
||||
FBootFields->FMemorySize = platform.GetMemorySize();
|
||||
} else if (autoMemory.length() == 2 && isdigit(autoMemory[0]) &&
|
||||
autoMemory[1] == '%') {
|
||||
FBootFields->FMemoryState = PackageBootFields::msAuto;
|
||||
FBootFields->FMemorySize =
|
||||
StringToPercentageOfNumber(autoMemory.substr(0, 1),
|
||||
platform.GetMemorySize());
|
||||
} else if (autoMemory.length() == 3 && isdigit(autoMemory[0]) &&
|
||||
isdigit(autoMemory[1]) && autoMemory[2] == '%') {
|
||||
FBootFields->FMemoryState = PackageBootFields::msAuto;
|
||||
FBootFields->FMemorySize =
|
||||
StringToPercentageOfNumber(autoMemory.substr(0, 2),
|
||||
platform.GetMemorySize());
|
||||
} else {
|
||||
FBootFields->FMemoryState = PackageBootFields::msManual;
|
||||
FBootFields->FMemorySize = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Debug
|
||||
TString debug;
|
||||
if (config->GetValue(keys[CONFIG_SECTION_APPLICATION],
|
||||
keys[CONFIG_APP_DEBUG], debug) == true) {
|
||||
FBootFields->FArgs.push_back(debug);
|
||||
}
|
||||
}
|
||||
|
||||
void Package::Clear() {
|
||||
FreeBootFields();
|
||||
FInitialized = false;
|
||||
}
|
||||
|
||||
// This is the only location that the AppCDS state should be modified except
|
||||
// by command line arguments provided by the user.
|
||||
//
|
||||
// The state of AppCDS is as follows:
|
||||
//
|
||||
// -> cdsUninitialized
|
||||
// -> cdsGenCache If -Xappcds:generatecache
|
||||
// -> cdsDisabled If -Xappcds:off
|
||||
// -> cdsEnabled If "AppCDSJavaOptions" section is present
|
||||
// -> cdsAuto If "AppCDSJavaOptions" section is present and
|
||||
// app.appcds.cache=auto
|
||||
// -> cdsDisabled Default
|
||||
//
|
||||
void Package::PromoteAppCDSState(ISectionalPropertyContainer* Config) {
|
||||
Platform& platform = Platform::GetInstance();
|
||||
std::map<TString, TString> keys = platform.GetKeys();
|
||||
|
||||
// The AppCDS state can change at this point.
|
||||
switch (platform.GetAppCDSState()) {
|
||||
case cdsEnabled:
|
||||
case cdsAuto:
|
||||
case cdsDisabled:
|
||||
case cdsGenCache: {
|
||||
// Do nothing.
|
||||
break;
|
||||
}
|
||||
|
||||
case cdsUninitialized: {
|
||||
if (Config->ContainsSection(
|
||||
keys[CONFIG_SECTION_APPCDSJAVAOPTIONS]) == true) {
|
||||
// If the AppCDS section is present then enable AppCDS.
|
||||
TString appCDSCacheValue;
|
||||
|
||||
// If running with AppCDS enabled, and the configuration has
|
||||
// been setup so "auto" is enabled, then
|
||||
// the launcher will attempt to generate the cache file
|
||||
// automatically and run the application.
|
||||
if (Config->GetValue(keys[CONFIG_SECTION_APPLICATION],
|
||||
_T("app.appcds.cache"), appCDSCacheValue) == true &&
|
||||
appCDSCacheValue == _T("auto")) {
|
||||
platform.SetAppCDSState(cdsAuto);
|
||||
}
|
||||
else {
|
||||
platform.SetAppCDSState(cdsEnabled);
|
||||
}
|
||||
} else {
|
||||
|
||||
platform.SetAppCDSState(cdsDisabled);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Package::ReadJavaOptions(ISectionalPropertyContainer* Config) {
|
||||
Platform& platform = Platform::GetInstance();
|
||||
std::map<TString, TString> keys = platform.GetKeys();
|
||||
|
||||
// Evaluate based on the current AppCDS state.
|
||||
switch (platform.GetAppCDSState()) {
|
||||
case cdsUninitialized: {
|
||||
throw Exception(_T("Internal Error"));
|
||||
}
|
||||
|
||||
case cdsDisabled: {
|
||||
Config->GetSection(keys[CONFIG_SECTION_JAVAOPTIONS],
|
||||
FBootFields->FJavaOptions);
|
||||
break;
|
||||
}
|
||||
|
||||
case cdsGenCache: {
|
||||
Config->GetSection(keys[
|
||||
CONFIG_SECTION_APPCDSGENERATECACHEJAVAOPTIONS],
|
||||
FBootFields->FJavaOptions);
|
||||
break;
|
||||
}
|
||||
|
||||
case cdsAuto:
|
||||
case cdsEnabled: {
|
||||
if (Config->GetValue(keys[CONFIG_SECTION_APPCDSJAVAOPTIONS],
|
||||
_T( "-XX:SharedArchiveFile"),
|
||||
FBootFields->FAppCDSCacheFileName) == true) {
|
||||
// File names may contain the incorrect path separators.
|
||||
// The cache file name must be corrected at this point.
|
||||
if (FBootFields->FAppCDSCacheFileName.empty() == false) {
|
||||
IniFile* iniConfig = dynamic_cast<IniFile*>(Config);
|
||||
|
||||
if (iniConfig != NULL) {
|
||||
FBootFields->FAppCDSCacheFileName =
|
||||
FilePath::FixPathForPlatform(
|
||||
FBootFields->FAppCDSCacheFileName);
|
||||
iniConfig->SetValue(keys[
|
||||
CONFIG_SECTION_APPCDSJAVAOPTIONS],
|
||||
_T( "-XX:SharedArchiveFile"),
|
||||
FBootFields->FAppCDSCacheFileName);
|
||||
}
|
||||
}
|
||||
|
||||
Config->GetSection(keys[CONFIG_SECTION_APPCDSJAVAOPTIONS],
|
||||
FBootFields->FJavaOptions);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Package::SetCommandLineArguments(int argc, TCHAR* argv[]) {
|
||||
if (argc > 0) {
|
||||
std::list<TString> args;
|
||||
|
||||
// Prepare app arguments. Skip value at index 0 -
|
||||
// this is path to executable.
|
||||
FBootFields->FCommandName = argv[0];
|
||||
|
||||
// Path to executable is at 0 index so start at index 1.
|
||||
for (int index = 1; index < argc; index++) {
|
||||
TString arg = argv[index];
|
||||
|
||||
#ifdef DEBUG
|
||||
if (arg == _T("-debug")) {
|
||||
FDebugging = dsNative;
|
||||
}
|
||||
|
||||
if (arg == _T("-javadebug")) {
|
||||
FDebugging = dsJava;
|
||||
}
|
||||
#endif //DEBUG
|
||||
#ifdef MAC
|
||||
if (arg.find(_T("-psn_"), 0) != TString::npos) {
|
||||
Platform& platform = Platform::GetInstance();
|
||||
|
||||
if (platform.IsMainThread() == true) {
|
||||
#ifdef DEBUG
|
||||
printf("%s\n", arg.c_str());
|
||||
#endif //DEBUG
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (arg == _T("-NSDocumentRevisionsDebugMode")) {
|
||||
// Ignore -NSDocumentRevisionsDebugMode and
|
||||
// the following YES/NO
|
||||
index++;
|
||||
continue;
|
||||
}
|
||||
#endif //MAC
|
||||
|
||||
args.push_back(arg);
|
||||
}
|
||||
|
||||
if (args.size() > 0) {
|
||||
FBootFields->FArgs = args;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Package& Package::GetInstance() {
|
||||
static Package instance;
|
||||
// Guaranteed to be destroyed. Instantiated on first use.
|
||||
return instance;
|
||||
}
|
||||
|
||||
Package::~Package(void) {
|
||||
FreeBootFields();
|
||||
}
|
||||
|
||||
void Package::FreeBootFields() {
|
||||
if (FBootFields != NULL) {
|
||||
delete FBootFields;
|
||||
FBootFields = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
OrderedMap<TString, TString> Package::GetJavaOptions() {
|
||||
return FBootFields->FJavaOptions;
|
||||
}
|
||||
|
||||
std::vector<TString> GetKeysThatAreNotDuplicates(OrderedMap<TString,
|
||||
TString> &Defaults, OrderedMap<TString, TString> &Overrides) {
|
||||
std::vector<TString> result;
|
||||
std::vector<TString> overrideKeys = Overrides.GetKeys();
|
||||
|
||||
for (size_t index = 0; index < overrideKeys.size(); index++) {
|
||||
TString overridesKey = overrideKeys[index];
|
||||
TString overridesValue;
|
||||
TString defaultValue;
|
||||
|
||||
if ((Defaults.ContainsKey(overridesKey) == false) ||
|
||||
(Defaults.GetValue(overridesKey, defaultValue) == true &&
|
||||
Overrides.GetValue(overridesKey, overridesValue) == true &&
|
||||
defaultValue != overridesValue)) {
|
||||
result.push_back(overridesKey);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
OrderedMap<TString, TString> CreateOrderedMapFromKeyList(OrderedMap<TString,
|
||||
TString> &Map, std::vector<TString> &Keys) {
|
||||
OrderedMap<TString, TString> result;
|
||||
|
||||
for (size_t index = 0; index < Keys.size(); index++) {
|
||||
TString key = Keys[index];
|
||||
TString value;
|
||||
|
||||
if (Map.GetValue(key, value) == true) {
|
||||
result.Append(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<TString> GetKeysThatAreNotOverridesOfDefaultValues(
|
||||
OrderedMap<TString, TString> &Defaults, OrderedMap<TString,
|
||||
TString> &Overrides) {
|
||||
std::vector<TString> result;
|
||||
std::vector<TString> keys = Overrides.GetKeys();
|
||||
|
||||
for (unsigned int index = 0; index< keys.size(); index++) {
|
||||
TString key = keys[index];
|
||||
|
||||
if (Defaults.ContainsKey(key) == true) {
|
||||
try {
|
||||
TString value = Overrides[key];
|
||||
Defaults[key] = value;
|
||||
}
|
||||
catch (std::out_of_range &) {
|
||||
}
|
||||
}
|
||||
else {
|
||||
result.push_back(key);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::list<TString> Package::GetArgs() {
|
||||
assert(FBootFields != NULL);
|
||||
return FBootFields->FArgs;
|
||||
}
|
||||
|
||||
TString Package::GetPackageRootDirectory() {
|
||||
assert(FBootFields != NULL);
|
||||
return FBootFields->FPackageRootDirectory;
|
||||
}
|
||||
|
||||
TString Package::GetPackageAppDirectory() {
|
||||
assert(FBootFields != NULL);
|
||||
return FBootFields->FPackageAppDirectory;
|
||||
}
|
||||
|
||||
TString Package::GetPackageLauncherDirectory() {
|
||||
assert(FBootFields != NULL);
|
||||
return FBootFields->FPackageLauncherDirectory;
|
||||
}
|
||||
|
||||
TString Package::GetAppDataDirectory() {
|
||||
assert(FBootFields != NULL);
|
||||
return FBootFields->FAppDataDirectory;
|
||||
}
|
||||
|
||||
TString Package::GetAppCDSCacheDirectory() {
|
||||
if (FAppCDSCacheDirectory.empty()) {
|
||||
Platform& platform = Platform::GetInstance();
|
||||
FAppCDSCacheDirectory = FilePath::IncludeTrailingSeparator(
|
||||
platform.GetAppDataDirectory())
|
||||
+ FilePath::IncludeTrailingSeparator(
|
||||
GetPackageAppDataDirectory()) + _T("cache");
|
||||
|
||||
Macros& macros = Macros::GetInstance();
|
||||
FAppCDSCacheDirectory = macros.ExpandMacros(FAppCDSCacheDirectory);
|
||||
FAppCDSCacheDirectory =
|
||||
FilePath::FixPathForPlatform(FAppCDSCacheDirectory);
|
||||
}
|
||||
|
||||
return FAppCDSCacheDirectory;
|
||||
}
|
||||
|
||||
TString Package::GetAppCDSCacheFileName() {
|
||||
assert(FBootFields != NULL);
|
||||
|
||||
if (FBootFields->FAppCDSCacheFileName.empty() == false) {
|
||||
Macros& macros = Macros::GetInstance();
|
||||
FBootFields->FAppCDSCacheFileName =
|
||||
macros.ExpandMacros(FBootFields->FAppCDSCacheFileName);
|
||||
FBootFields->FAppCDSCacheFileName =
|
||||
FilePath::FixPathForPlatform(FBootFields->FAppCDSCacheFileName);
|
||||
}
|
||||
|
||||
return FBootFields->FAppCDSCacheFileName;
|
||||
}
|
||||
|
||||
TString Package::GetPackageAppDataDirectory() {
|
||||
assert(FBootFields != NULL);
|
||||
return FBootFields->FPackageAppDataDirectory;
|
||||
}
|
||||
|
||||
TString Package::GetClassPath() {
|
||||
assert(FBootFields != NULL);
|
||||
return FBootFields->FClassPath;
|
||||
}
|
||||
|
||||
TString Package::GetModulePath() {
|
||||
assert(FBootFields != NULL);
|
||||
return FBootFields->FModulePath;
|
||||
}
|
||||
|
||||
TString Package::GetMainJar() {
|
||||
assert(FBootFields != NULL);
|
||||
return FBootFields->FMainJar;
|
||||
}
|
||||
|
||||
TString Package::GetMainModule() {
|
||||
assert(FBootFields != NULL);
|
||||
return FBootFields->FMainModule;
|
||||
}
|
||||
|
||||
TString Package::GetMainClassName() {
|
||||
assert(FBootFields != NULL);
|
||||
return FBootFields->FMainClassName;
|
||||
}
|
||||
|
||||
TString Package::GetJavaLibraryFileName() {
|
||||
assert(FBootFields != NULL);
|
||||
|
||||
if (FBootFields->FJavaLibraryFileName.empty() == true) {
|
||||
Platform& platform = Platform::GetInstance();
|
||||
Macros& macros = Macros::GetInstance();
|
||||
TString jvmRuntimePath = macros.ExpandMacros(GetJavaRuntimeDirectory());
|
||||
FBootFields->FJavaLibraryFileName =
|
||||
platform.GetBundledJavaLibraryFileName(jvmRuntimePath);
|
||||
}
|
||||
|
||||
return FBootFields->FJavaLibraryFileName;
|
||||
}
|
||||
|
||||
TString Package::GetJavaRuntimeDirectory() {
|
||||
assert(FBootFields != NULL);
|
||||
return FBootFields->FJavaRuntimeDirectory;
|
||||
}
|
||||
|
||||
TString Package::GetSplashScreenFileName() {
|
||||
assert(FBootFields != NULL);
|
||||
return FBootFields->FSplashScreenFileName;
|
||||
}
|
||||
|
||||
bool Package::HasSplashScreen() {
|
||||
assert(FBootFields != NULL);
|
||||
return FilePath::FileExists(FBootFields->FSplashScreenFileName);
|
||||
}
|
||||
|
||||
TString Package::GetCommandName() {
|
||||
assert(FBootFields != NULL);
|
||||
return FBootFields->FCommandName;
|
||||
}
|
||||
|
||||
TPlatformNumber Package::GetMemorySize() {
|
||||
assert(FBootFields != NULL);
|
||||
return FBootFields->FMemorySize;
|
||||
}
|
||||
|
||||
PackageBootFields::MemoryState Package::GetMemoryState() {
|
||||
assert(FBootFields != NULL);
|
||||
return FBootFields->FMemoryState;
|
||||
}
|
||||
|
||||
DebugState Package::Debugging() {
|
||||
return FDebugging;
|
||||
}
|
@ -1,126 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2019, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#ifndef PACKAGE_H
|
||||
#define PACKAGE_H
|
||||
|
||||
|
||||
#include "Platform.h"
|
||||
#include "PlatformString.h"
|
||||
#include "FilePath.h"
|
||||
#include "PropertyFile.h"
|
||||
|
||||
#include <map>
|
||||
#include <list>
|
||||
|
||||
class PackageBootFields {
|
||||
public:
|
||||
enum MemoryState {msManual, msAuto};
|
||||
|
||||
public:
|
||||
OrderedMap<TString, TString> FJavaOptions;
|
||||
std::list<TString> FArgs;
|
||||
|
||||
TString FPackageRootDirectory;
|
||||
TString FPackageAppDirectory;
|
||||
TString FPackageLauncherDirectory;
|
||||
TString FAppDataDirectory;
|
||||
TString FPackageAppDataDirectory;
|
||||
TString FClassPath;
|
||||
TString FModulePath;
|
||||
TString FMainJar;
|
||||
TString FMainModule;
|
||||
TString FMainClassName;
|
||||
TString FJavaRuntimeDirectory;
|
||||
TString FJavaLibraryFileName;
|
||||
TString FSplashScreenFileName;
|
||||
bool FUseJavaPreferences;
|
||||
TString FCommandName;
|
||||
|
||||
TString FAppCDSCacheFileName;
|
||||
|
||||
TPlatformNumber FMemorySize;
|
||||
MemoryState FMemoryState;
|
||||
};
|
||||
|
||||
|
||||
class Package {
|
||||
private:
|
||||
Package(Package const&); // Don't Implement.
|
||||
void operator=(Package const&); // Don't implement
|
||||
|
||||
private:
|
||||
bool FInitialized;
|
||||
PackageBootFields* FBootFields;
|
||||
TString FAppCDSCacheDirectory;
|
||||
|
||||
DebugState FDebugging;
|
||||
|
||||
Package(void);
|
||||
|
||||
TString GetMainJar();
|
||||
void ReadJavaOptions(ISectionalPropertyContainer* Config);
|
||||
void PromoteAppCDSState(ISectionalPropertyContainer* Config);
|
||||
|
||||
public:
|
||||
static Package& GetInstance();
|
||||
~Package(void);
|
||||
|
||||
void Initialize();
|
||||
void Clear();
|
||||
void FreeBootFields();
|
||||
|
||||
void SetCommandLineArguments(int argc, TCHAR* argv[]);
|
||||
|
||||
OrderedMap<TString, TString> GetJavaOptions();
|
||||
TString GetMainModule();
|
||||
|
||||
std::list<TString> GetArgs();
|
||||
|
||||
TString GetPackageRootDirectory();
|
||||
TString GetPackageAppDirectory();
|
||||
TString GetPackageLauncherDirectory();
|
||||
TString GetAppDataDirectory();
|
||||
|
||||
TString GetAppCDSCacheDirectory();
|
||||
TString GetAppCDSCacheFileName();
|
||||
|
||||
TString GetPackageAppDataDirectory();
|
||||
TString GetClassPath();
|
||||
TString GetModulePath();
|
||||
TString GetMainClassName();
|
||||
TString GetJavaLibraryFileName();
|
||||
TString GetJavaRuntimeDirectory();
|
||||
TString GetSplashScreenFileName();
|
||||
bool HasSplashScreen();
|
||||
TString GetCommandName();
|
||||
|
||||
TPlatformNumber GetMemorySize();
|
||||
PackageBootFields::MemoryState GetMemoryState();
|
||||
|
||||
DebugState Debugging();
|
||||
};
|
||||
|
||||
#endif // PACKAGE_H
|
@ -1,173 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2019, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#include "Platform.h"
|
||||
#include "Messages.h"
|
||||
#include "PlatformString.h"
|
||||
#include "FilePath.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <locale>
|
||||
|
||||
#ifdef WINDOWS
|
||||
#include "WindowsPlatform.h"
|
||||
#endif // WINDOWS
|
||||
#ifdef LINUX
|
||||
#include "LinuxPlatform.h"
|
||||
#endif // LINUX
|
||||
#ifdef MAC
|
||||
#include "MacPlatform.h"
|
||||
#endif // MAC
|
||||
|
||||
Platform& Platform::GetInstance() {
|
||||
#ifdef WINDOWS
|
||||
static WindowsPlatform instance;
|
||||
#endif // WINDOWS
|
||||
|
||||
#ifdef LINUX
|
||||
static LinuxPlatform instance;
|
||||
#endif // LINUX
|
||||
|
||||
#ifdef MAC
|
||||
static MacPlatform instance;
|
||||
#endif // MAC
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
TString Platform::GetConfigFileName() {
|
||||
TString result;
|
||||
TString basedir = GetPackageAppDirectory();
|
||||
|
||||
if (basedir.empty() == false) {
|
||||
basedir = FilePath::IncludeTrailingSeparator(basedir);
|
||||
TString appConfig = basedir + GetAppName() + _T(".cfg");
|
||||
|
||||
if (FilePath::FileExists(appConfig) == true) {
|
||||
result = appConfig;
|
||||
}
|
||||
else {
|
||||
result = basedir + _T("package.cfg");
|
||||
|
||||
if (FilePath::FileExists(result) == false) {
|
||||
result = _T("");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::list<TString> Platform::LoadFromFile(TString FileName) {
|
||||
std::list<TString> result;
|
||||
|
||||
if (FilePath::FileExists(FileName) == true) {
|
||||
std::wifstream stream(FileName.data());
|
||||
InitStreamLocale(&stream);
|
||||
|
||||
if (stream.is_open() == true) {
|
||||
while (stream.eof() == false) {
|
||||
std::wstring line;
|
||||
std::getline(stream, line);
|
||||
|
||||
// # at the first character will comment out the line.
|
||||
if (line.empty() == false && line[0] != '#') {
|
||||
result.push_back(PlatformString(line).toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void Platform::SaveToFile(TString FileName, std::list<TString> Contents, bool ownerOnly) {
|
||||
TString path = FilePath::ExtractFilePath(FileName);
|
||||
|
||||
if (FilePath::DirectoryExists(path) == false) {
|
||||
FilePath::CreateDirectory(path, ownerOnly);
|
||||
}
|
||||
|
||||
std::wofstream stream(FileName.data());
|
||||
InitStreamLocale(&stream);
|
||||
|
||||
FilePath::ChangePermissions(FileName.data(), ownerOnly);
|
||||
|
||||
if (stream.is_open() == true) {
|
||||
for (std::list<TString>::const_iterator iterator =
|
||||
Contents.begin(); iterator != Contents.end(); iterator++) {
|
||||
TString line = *iterator;
|
||||
stream << PlatformString(line).toUnicodeString() << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::map<TString, TString> Platform::GetKeys() {
|
||||
std::map<TString, TString> keys;
|
||||
keys.insert(std::map<TString, TString>::value_type(CONFIG_VERSION,
|
||||
_T("app.version")));
|
||||
keys.insert(std::map<TString, TString>::value_type(CONFIG_MAINJAR_KEY,
|
||||
_T("app.mainjar")));
|
||||
keys.insert(std::map<TString, TString>::value_type(CONFIG_MAINMODULE_KEY,
|
||||
_T("app.mainmodule")));
|
||||
keys.insert(std::map<TString, TString>::value_type(CONFIG_MAINCLASSNAME_KEY,
|
||||
_T("app.mainclass")));
|
||||
keys.insert(std::map<TString, TString>::value_type(CONFIG_CLASSPATH_KEY,
|
||||
_T("app.classpath")));
|
||||
keys.insert(std::map<TString, TString>::value_type(CONFIG_MODULEPATH_KEY,
|
||||
_T("app.modulepath")));
|
||||
keys.insert(std::map<TString, TString>::value_type(APP_NAME_KEY,
|
||||
_T("app.name")));
|
||||
keys.insert(std::map<TString, TString>::value_type(JAVA_RUNTIME_KEY,
|
||||
_T("app.runtime")));
|
||||
keys.insert(std::map<TString, TString>::value_type(JPACKAGE_APP_DATA_DIR,
|
||||
_T("app.identifier")));
|
||||
keys.insert(std::map<TString, TString>::value_type(CONFIG_SPLASH_KEY,
|
||||
_T("app.splash")));
|
||||
keys.insert(std::map<TString, TString>::value_type(CONFIG_APP_MEMORY,
|
||||
_T("app.memory")));
|
||||
keys.insert(std::map<TString, TString>::value_type(CONFIG_APP_DEBUG,
|
||||
_T("app.debug")));
|
||||
keys.insert(std::map<TString,
|
||||
TString>::value_type(CONFIG_APPLICATION_INSTANCE,
|
||||
_T("app.application.instance")));
|
||||
keys.insert(std::map<TString,
|
||||
TString>::value_type(CONFIG_SECTION_APPLICATION,
|
||||
_T("Application")));
|
||||
keys.insert(std::map<TString,
|
||||
TString>::value_type(CONFIG_SECTION_JAVAOPTIONS,
|
||||
_T("JavaOptions")));
|
||||
keys.insert(std::map<TString,
|
||||
TString>::value_type(CONFIG_SECTION_APPCDSJAVAOPTIONS,
|
||||
_T("AppCDSJavaOptions")));
|
||||
keys.insert(std::map<TString,
|
||||
TString>::value_type(CONFIG_SECTION_APPCDSGENERATECACHEJAVAOPTIONS,
|
||||
_T("AppCDSGenerateCacheJavaOptions")));
|
||||
keys.insert(std::map<TString,
|
||||
TString>::value_type(CONFIG_SECTION_ARGOPTIONS,
|
||||
_T("ArgOptions")));
|
||||
|
||||
return keys;
|
||||
}
|
@ -1,264 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2019, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#ifndef PLATFORM_H
|
||||
#define PLATFORM_H
|
||||
|
||||
#include "PlatformDefs.h"
|
||||
#include "Properties.h"
|
||||
#include "OrderedMap.h"
|
||||
#include "Library.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
// Config file sections
|
||||
#define CONFIG_SECTION_APPLICATION _T("CONFIG_SECTION_APPLICATION")
|
||||
#define CONFIG_SECTION_JAVAOPTIONS _T("CONFIG_SECTION_JAVAOPTIONS")
|
||||
#define CONFIG_SECTION_APPCDSJAVAOPTIONS _T("CONFIG_SECTION_APPCDSJAVAOPTIONS")
|
||||
#define CONFIG_SECTION_ARGOPTIONS _T("CONFIG_SECTION_ARGOPTIONS")
|
||||
#define CONFIG_SECTION_APPCDSGENERATECACHEJAVAOPTIONS \
|
||||
_T("CONFIG_SECTION_APPCDSGENERATECACHEJAVAOPTIONS")
|
||||
|
||||
// Config file keys.
|
||||
#define CONFIG_VERSION _T("CONFIG_VERSION")
|
||||
#define CONFIG_MAINJAR_KEY _T("CONFIG_MAINJAR_KEY")
|
||||
#define CONFIG_MAINMODULE_KEY _T("CONFIG_MAINMODULE_KEY")
|
||||
#define CONFIG_MAINCLASSNAME_KEY _T("CONFIG_MAINCLASSNAME_KEY")
|
||||
#define CONFIG_CLASSPATH_KEY _T("CONFIG_CLASSPATH_KEY")
|
||||
#define CONFIG_MODULEPATH_KEY _T("CONFIG_MODULEPATH_KEY")
|
||||
#define APP_NAME_KEY _T("APP_NAME_KEY")
|
||||
#define CONFIG_SPLASH_KEY _T("CONFIG_SPLASH_KEY")
|
||||
#define CONFIG_APP_MEMORY _T("CONFIG_APP_MEMORY")
|
||||
#define CONFIG_APP_DEBUG _T("CONFIG_APP_DEBUG")
|
||||
#define CONFIG_APPLICATION_INSTANCE _T("CONFIG_APPLICATION_INSTANCE")
|
||||
|
||||
#define JAVA_RUNTIME_KEY _T("JAVA_RUNTIME_KEY")
|
||||
#define JPACKAGE_APP_DATA_DIR _T("CONFIG_APP_IDENTIFIER")
|
||||
|
||||
struct WideString {
|
||||
size_t length;
|
||||
wchar_t* data;
|
||||
|
||||
WideString() { length = 0; data = NULL; }
|
||||
};
|
||||
|
||||
struct MultibyteString {
|
||||
size_t length;
|
||||
char* data;
|
||||
|
||||
MultibyteString() { length = 0; data = NULL; }
|
||||
};
|
||||
|
||||
class Process {
|
||||
protected:
|
||||
std::list<TString> FOutput;
|
||||
|
||||
public:
|
||||
Process() {
|
||||
Output.SetInstance(this);
|
||||
Input.SetInstance(this);
|
||||
}
|
||||
|
||||
virtual ~Process() {}
|
||||
|
||||
virtual bool IsRunning() = 0;
|
||||
virtual bool Terminate() = 0;
|
||||
virtual bool Execute(const TString Application,
|
||||
const std::vector<TString> Arguments, bool AWait = false) = 0;
|
||||
virtual bool Wait() = 0;
|
||||
virtual TProcessID GetProcessID() = 0;
|
||||
|
||||
virtual std::list<TString> GetOutput() { return FOutput; }
|
||||
virtual void SetInput(TString Value) = 0;
|
||||
|
||||
ReadProperty<Process, std::list<TString>, &Process::GetOutput> Output;
|
||||
WriteProperty<Process, TString, &Process::SetInput> Input;
|
||||
};
|
||||
|
||||
|
||||
template <typename T>
|
||||
class AutoFreePtr {
|
||||
private:
|
||||
T* FObject;
|
||||
|
||||
public:
|
||||
AutoFreePtr() {
|
||||
FObject = NULL;
|
||||
}
|
||||
|
||||
AutoFreePtr(T* Value) {
|
||||
FObject = Value;
|
||||
}
|
||||
|
||||
~AutoFreePtr() {
|
||||
if (FObject != NULL) {
|
||||
delete FObject;
|
||||
}
|
||||
}
|
||||
|
||||
operator T* () const {
|
||||
return FObject;
|
||||
}
|
||||
|
||||
T& operator* () const {
|
||||
return *FObject;
|
||||
}
|
||||
|
||||
T* operator->() const {
|
||||
return FObject;
|
||||
}
|
||||
|
||||
T** operator&() {
|
||||
return &FObject;
|
||||
}
|
||||
|
||||
T* operator=(const T * rhs) {
|
||||
FObject = rhs;
|
||||
return FObject;
|
||||
}
|
||||
};
|
||||
|
||||
enum DebugState {dsNone, dsNative, dsJava};
|
||||
enum MessageResponse {mrOK, mrCancel};
|
||||
enum AppCDSState {cdsUninitialized, cdsDisabled,
|
||||
cdsEnabled, cdsAuto, cdsGenCache};
|
||||
|
||||
class Platform {
|
||||
private:
|
||||
AppCDSState FAppCDSState;
|
||||
|
||||
protected:
|
||||
Platform(void): FAppCDSState(cdsUninitialized) {
|
||||
}
|
||||
|
||||
public:
|
||||
AppCDSState GetAppCDSState() { return FAppCDSState; }
|
||||
void SetAppCDSState(AppCDSState Value) { FAppCDSState = Value; }
|
||||
|
||||
static Platform& GetInstance();
|
||||
|
||||
virtual ~Platform(void) {}
|
||||
|
||||
public:
|
||||
virtual void ShowMessage(TString title, TString description) = 0;
|
||||
virtual void ShowMessage(TString description) = 0;
|
||||
virtual MessageResponse ShowResponseMessage(TString title,
|
||||
TString description) = 0;
|
||||
|
||||
// Caller must free result using delete[].
|
||||
virtual TCHAR* ConvertStringToFileSystemString(TCHAR* Source,
|
||||
bool &release) = 0;
|
||||
|
||||
// Caller must free result using delete[].
|
||||
virtual TCHAR* ConvertFileSystemStringToString(TCHAR* Source,
|
||||
bool &release) = 0;
|
||||
|
||||
// Returns:
|
||||
// Windows=C:\Users\<username>\AppData\Local
|
||||
// Linux=~/.local
|
||||
// Mac=~/Library/Application Support
|
||||
virtual TString GetAppDataDirectory() = 0;
|
||||
|
||||
virtual TString GetPackageAppDirectory() = 0;
|
||||
virtual TString GetPackageLauncherDirectory() = 0;
|
||||
virtual TString GetPackageRuntimeBinDirectory() = 0;
|
||||
virtual TString GetAppName() = 0;
|
||||
|
||||
virtual TString GetConfigFileName();
|
||||
|
||||
virtual TString GetBundledJavaLibraryFileName(TString RuntimePath) = 0;
|
||||
|
||||
// Caller must free result.
|
||||
virtual ISectionalPropertyContainer* GetConfigFile(TString FileName) = 0;
|
||||
|
||||
virtual TString GetModuleFileName() = 0;
|
||||
virtual TString GetPackageRootDirectory() = 0;
|
||||
|
||||
virtual Module LoadLibrary(TString FileName) = 0;
|
||||
virtual void FreeLibrary(Module Module) = 0;
|
||||
virtual Procedure GetProcAddress(Module Module, std::string MethodName) = 0;
|
||||
|
||||
// Caller must free result.
|
||||
virtual Process* CreateProcess() = 0;
|
||||
|
||||
virtual bool IsMainThread() = 0;
|
||||
|
||||
// Returns megabytes.
|
||||
virtual TPlatformNumber GetMemorySize() = 0;
|
||||
|
||||
virtual std::map<TString, TString> GetKeys();
|
||||
|
||||
virtual void InitStreamLocale(wios *stream) = 0;
|
||||
virtual std::list<TString> LoadFromFile(TString FileName);
|
||||
virtual void SaveToFile(TString FileName,
|
||||
std::list<TString> Contents, bool ownerOnly);
|
||||
|
||||
virtual TString GetTempDirectory() = 0;
|
||||
|
||||
virtual void addPlatformDependencies(JavaLibrary *pJavaLibrary) = 0;
|
||||
|
||||
public:
|
||||
// String helpers
|
||||
// Caller must free result using delete[].
|
||||
static void CopyString(char *Destination,
|
||||
size_t NumberOfElements, const char *Source);
|
||||
|
||||
// Caller must free result using delete[].
|
||||
static void CopyString(wchar_t *Destination,
|
||||
size_t NumberOfElements, const wchar_t *Source);
|
||||
|
||||
static WideString MultibyteStringToWideString(const char* value);
|
||||
static MultibyteString WideStringToMultibyteString(const wchar_t* value);
|
||||
};
|
||||
|
||||
class Exception: public std::exception {
|
||||
private:
|
||||
TString FMessage;
|
||||
|
||||
protected:
|
||||
void SetMessage(const TString Message) {
|
||||
FMessage = Message;
|
||||
}
|
||||
|
||||
public:
|
||||
explicit Exception() : exception() {}
|
||||
explicit Exception(const TString Message) : exception() {
|
||||
SetMessage(Message);
|
||||
}
|
||||
virtual ~Exception() throw() {}
|
||||
|
||||
TString GetMessage() { return FMessage; }
|
||||
};
|
||||
|
||||
#endif // PLATFORM_H
|
@ -1,227 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2019, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#include "PlatformString.h"
|
||||
|
||||
#include "Helpers.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
#include <sstream>
|
||||
#include <string.h>
|
||||
|
||||
#include "jni.h"
|
||||
|
||||
void PlatformString::initialize() {
|
||||
FWideTStringToFree = NULL;
|
||||
FLength = 0;
|
||||
FData = NULL;
|
||||
}
|
||||
|
||||
PlatformString::PlatformString(void) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
PlatformString::~PlatformString(void) {
|
||||
if (FData != NULL) {
|
||||
delete[] FData;
|
||||
}
|
||||
|
||||
if (FWideTStringToFree != NULL) {
|
||||
delete[] FWideTStringToFree;
|
||||
}
|
||||
}
|
||||
|
||||
PlatformString::PlatformString(const PlatformString &value) {
|
||||
initialize();
|
||||
FLength = value.FLength;
|
||||
FData = new char[FLength + 1];
|
||||
Platform::CopyString(FData, FLength + 1, value.FData);
|
||||
}
|
||||
|
||||
PlatformString::PlatformString(const char* value) {
|
||||
initialize();
|
||||
FLength = strlen(value);
|
||||
FData = new char[FLength + 1];
|
||||
Platform::CopyString(FData, FLength + 1, value);
|
||||
}
|
||||
|
||||
PlatformString::PlatformString(size_t Value) {
|
||||
initialize();
|
||||
|
||||
std::stringstream ss;
|
||||
std::string s;
|
||||
ss << Value;
|
||||
s = ss.str();
|
||||
|
||||
FLength = strlen(s.c_str());
|
||||
FData = new char[FLength + 1];
|
||||
Platform::CopyString(FData, FLength + 1, s.c_str());
|
||||
}
|
||||
|
||||
PlatformString::PlatformString(const wchar_t* value) {
|
||||
initialize();
|
||||
MultibyteString temp = Platform::WideStringToMultibyteString(value);
|
||||
FLength = temp.length;
|
||||
FData = temp.data;
|
||||
}
|
||||
|
||||
PlatformString::PlatformString(const std::string &value) {
|
||||
initialize();
|
||||
const char* lvalue = value.data();
|
||||
FLength = value.size();
|
||||
FData = new char[FLength + 1];
|
||||
Platform::CopyString(FData, FLength + 1, lvalue);
|
||||
}
|
||||
|
||||
PlatformString::PlatformString(const std::wstring &value) {
|
||||
initialize();
|
||||
const wchar_t* lvalue = value.data();
|
||||
MultibyteString temp = Platform::WideStringToMultibyteString(lvalue);
|
||||
FLength = temp.length;
|
||||
FData = temp.data;
|
||||
}
|
||||
|
||||
TString PlatformString::Format(const TString value, ...) {
|
||||
TString result = value;
|
||||
|
||||
va_list arglist;
|
||||
va_start(arglist, value);
|
||||
|
||||
while (1) {
|
||||
size_t pos = result.find(_T("%s"), 0);
|
||||
|
||||
if (pos == TString::npos) {
|
||||
break;
|
||||
}
|
||||
else {
|
||||
TCHAR* arg = va_arg(arglist, TCHAR*);
|
||||
|
||||
if (arg == NULL) {
|
||||
break;
|
||||
}
|
||||
else {
|
||||
result.replace(pos, StringLength(_T("%s")), arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
va_end(arglist);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t PlatformString::length() {
|
||||
return FLength;
|
||||
}
|
||||
|
||||
char* PlatformString::c_str() {
|
||||
return FData;
|
||||
}
|
||||
|
||||
char* PlatformString::toMultibyte() {
|
||||
return FData;
|
||||
}
|
||||
|
||||
wchar_t* PlatformString::toWideString() {
|
||||
WideString result = Platform::MultibyteStringToWideString(FData);
|
||||
|
||||
if (result.data != NULL) {
|
||||
if (FWideTStringToFree != NULL) {
|
||||
delete [] FWideTStringToFree;
|
||||
}
|
||||
|
||||
FWideTStringToFree = result.data;
|
||||
}
|
||||
|
||||
return result.data;
|
||||
}
|
||||
|
||||
std::wstring PlatformString::toUnicodeString() {
|
||||
std::wstring result;
|
||||
wchar_t* data = toWideString();
|
||||
|
||||
if (FLength != 0 && data != NULL) {
|
||||
// NOTE: Cleanup of result is handled by PlatformString destructor.
|
||||
result = data;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string PlatformString::toStdString() {
|
||||
std::string result;
|
||||
char* data = toMultibyte();
|
||||
|
||||
if (FLength > 0 && data != NULL) {
|
||||
result = data;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
TCHAR* PlatformString::toPlatformString() {
|
||||
#ifdef _UNICODE
|
||||
return toWideString();
|
||||
#else
|
||||
return c_str();
|
||||
#endif //_UNICODE
|
||||
}
|
||||
|
||||
TString PlatformString::toString() {
|
||||
#ifdef _UNICODE
|
||||
return toUnicodeString();
|
||||
#else
|
||||
return toStdString();
|
||||
#endif //_UNICODE
|
||||
}
|
||||
|
||||
PlatformString::operator char* () {
|
||||
return c_str();
|
||||
}
|
||||
|
||||
PlatformString::operator wchar_t* () {
|
||||
return toWideString();
|
||||
}
|
||||
|
||||
PlatformString::operator std::wstring () {
|
||||
return toUnicodeString();
|
||||
}
|
||||
|
||||
char* PlatformString::duplicate(const char* Value) {
|
||||
size_t length = strlen(Value);
|
||||
char* result = new char[length + 1];
|
||||
Platform::CopyString(result, length + 1, Value);
|
||||
return result;
|
||||
}
|
||||
|
||||
wchar_t* PlatformString::duplicate(const wchar_t* Value) {
|
||||
size_t length = wcslen(Value);
|
||||
wchar_t* result = new wchar_t[length + 1];
|
||||
Platform::CopyString(result, length + 1, Value);
|
||||
return result;
|
||||
}
|
@ -1,136 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2019, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#ifndef PLATFORMSTRING_H
|
||||
#define PLATFORMSTRING_H
|
||||
|
||||
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "jni.h"
|
||||
#include "Platform.h"
|
||||
|
||||
|
||||
template <typename T>
|
||||
class DynamicBuffer {
|
||||
private:
|
||||
T* FData;
|
||||
size_t FSize;
|
||||
|
||||
public:
|
||||
DynamicBuffer(size_t Size) {
|
||||
FSize = 0;
|
||||
FData = NULL;
|
||||
Resize(Size);
|
||||
}
|
||||
|
||||
~DynamicBuffer() {
|
||||
delete[] FData;
|
||||
}
|
||||
|
||||
T* GetData() { return FData; }
|
||||
size_t GetSize() { return FSize; }
|
||||
|
||||
bool Resize(size_t Size) {
|
||||
FSize = Size;
|
||||
|
||||
if (FData != NULL) {
|
||||
delete[] FData;
|
||||
FData = NULL;
|
||||
}
|
||||
|
||||
if (FSize != 0) {
|
||||
FData = new T[FSize];
|
||||
if (FData != NULL) {
|
||||
Zero();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Zero() {
|
||||
memset(FData, 0, FSize * sizeof(T));
|
||||
}
|
||||
|
||||
T& operator[](size_t index) {
|
||||
return FData[index];
|
||||
}
|
||||
};
|
||||
|
||||
class PlatformString {
|
||||
private:
|
||||
char* FData; // Stored as UTF-8
|
||||
size_t FLength;
|
||||
wchar_t* FWideTStringToFree;
|
||||
|
||||
void initialize();
|
||||
|
||||
// Prohibit Heap-Based PlatformStrings
|
||||
private:
|
||||
static void *operator new(size_t size);
|
||||
static void operator delete(void *ptr);
|
||||
|
||||
public:
|
||||
PlatformString(void);
|
||||
PlatformString(const PlatformString &value);
|
||||
PlatformString(const char* value);
|
||||
PlatformString(const wchar_t* value);
|
||||
PlatformString(const std::string &value);
|
||||
PlatformString(const std::wstring &value);
|
||||
PlatformString(size_t Value);
|
||||
|
||||
static TString Format(const TString value, ...);
|
||||
|
||||
~PlatformString(void);
|
||||
|
||||
size_t length();
|
||||
|
||||
char* c_str();
|
||||
char* toMultibyte();
|
||||
wchar_t* toWideString();
|
||||
std::wstring toUnicodeString();
|
||||
std::string toStdString();
|
||||
TCHAR* toPlatformString();
|
||||
TString toString();
|
||||
|
||||
operator char* ();
|
||||
operator wchar_t* ();
|
||||
operator std::wstring ();
|
||||
|
||||
// Caller must free result using delete[].
|
||||
static char* duplicate(const char* Value);
|
||||
|
||||
// Caller must free result using delete[].
|
||||
static wchar_t* duplicate(const wchar_t* Value);
|
||||
};
|
||||
|
||||
|
||||
#endif // PLATFORMSTRING_H
|
@ -1,184 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2019, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#ifndef PROPERTIES_H
|
||||
#define PROPERTIES_H
|
||||
|
||||
#include "PlatformDefs.h"
|
||||
#include "OrderedMap.h"
|
||||
|
||||
//#include <stdio.h>
|
||||
//#include <stdlib.h>
|
||||
//#include <memory.h>
|
||||
//#include <string>
|
||||
//#include <map>
|
||||
//#include <list>
|
||||
//#include <vector>
|
||||
//#include <fstream>
|
||||
|
||||
//using namespace std;
|
||||
|
||||
template <typename ObjectType, typename ValueType,
|
||||
ValueType (ObjectType::*getter)(void),
|
||||
void (ObjectType::*setter)(ValueType)>
|
||||
class Property {
|
||||
private:
|
||||
ObjectType* FObject;
|
||||
|
||||
public:
|
||||
Property() {
|
||||
FObject = NULL;
|
||||
}
|
||||
|
||||
void SetInstance(ObjectType* Value) {
|
||||
FObject = Value;
|
||||
}
|
||||
|
||||
// To set the value using the set method.
|
||||
ValueType operator =(const ValueType& Value) {
|
||||
assert(FObject != NULL);
|
||||
(FObject->*setter)(Value);
|
||||
return Value;
|
||||
}
|
||||
|
||||
// The Property class is treated as the internal type.
|
||||
operator ValueType() {
|
||||
assert(FObject != NULL);
|
||||
return (FObject->*getter)();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ObjectType, typename ValueType,
|
||||
ValueType (ObjectType::*getter)(void)>
|
||||
class ReadProperty {
|
||||
private:
|
||||
ObjectType* FObject;
|
||||
|
||||
public:
|
||||
ReadProperty() {
|
||||
FObject = NULL;
|
||||
}
|
||||
|
||||
void SetInstance(ObjectType* Value) {
|
||||
FObject = Value;
|
||||
}
|
||||
|
||||
// The Property class is treated as the internal type.
|
||||
operator ValueType() {
|
||||
assert(FObject != NULL);
|
||||
return (FObject->*getter)();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ObjectType, typename ValueType,
|
||||
void (ObjectType::*setter)(ValueType)>
|
||||
class WriteProperty {
|
||||
private:
|
||||
ObjectType* FObject;
|
||||
|
||||
public:
|
||||
WriteProperty() {
|
||||
FObject = NULL;
|
||||
}
|
||||
|
||||
void SetInstance(ObjectType* Value) {
|
||||
FObject = Value;
|
||||
}
|
||||
|
||||
// To set the value using the set method.
|
||||
ValueType operator =(const ValueType& Value) {
|
||||
assert(FObject != NULL);
|
||||
(FObject->*setter)(Value);
|
||||
return Value;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ValueType,
|
||||
ValueType (*getter)(void), void (*setter)(ValueType)>
|
||||
class StaticProperty {
|
||||
public:
|
||||
StaticProperty() {
|
||||
}
|
||||
|
||||
// To set the value using the set method.
|
||||
ValueType operator =(const ValueType& Value) {
|
||||
(*getter)(Value);
|
||||
return Value;
|
||||
}
|
||||
|
||||
// The Property class is treated as the internal type which is the getter.
|
||||
operator ValueType() {
|
||||
return (*setter)();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ValueType, ValueType (*getter)(void)>
|
||||
class StaticReadProperty {
|
||||
public:
|
||||
StaticReadProperty() {
|
||||
}
|
||||
|
||||
// The Property class is treated as the internal type which is the getter.
|
||||
operator ValueType() {
|
||||
return (*getter)();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ValueType, void (*setter)(ValueType)>
|
||||
class StaticWriteProperty {
|
||||
public:
|
||||
StaticWriteProperty() {
|
||||
}
|
||||
|
||||
// To set the value using the set method.
|
||||
ValueType operator =(const ValueType& Value) {
|
||||
(*setter)(Value);
|
||||
return Value;
|
||||
}
|
||||
};
|
||||
|
||||
class IPropertyContainer {
|
||||
public:
|
||||
IPropertyContainer(void) {}
|
||||
virtual ~IPropertyContainer(void) {}
|
||||
|
||||
virtual bool GetValue(const TString Key, TString& Value) = 0;
|
||||
virtual size_t GetCount() = 0;
|
||||
};
|
||||
|
||||
class ISectionalPropertyContainer {
|
||||
public:
|
||||
ISectionalPropertyContainer(void) {}
|
||||
virtual ~ISectionalPropertyContainer(void) {}
|
||||
|
||||
virtual bool GetValue(const TString SectionName,
|
||||
const TString Key, TString& Value) = 0;
|
||||
virtual bool ContainsSection(const TString SectionName) = 0;
|
||||
virtual bool GetSection(const TString SectionName,
|
||||
OrderedMap<TString, TString> &Data) = 0;
|
||||
};
|
||||
|
||||
#endif // PROPERTIES_H
|
||||
|
@ -1,168 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2019, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#include "PropertyFile.h"
|
||||
|
||||
#include "Helpers.h"
|
||||
#include "FilePath.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
|
||||
PropertyFile::PropertyFile(void) : IPropertyContainer() {
|
||||
FReadOnly = false;
|
||||
FModified = false;
|
||||
}
|
||||
|
||||
PropertyFile::PropertyFile(const TString FileName) : IPropertyContainer() {
|
||||
FReadOnly = true;
|
||||
FModified = false;
|
||||
LoadFromFile(FileName);
|
||||
}
|
||||
|
||||
PropertyFile::PropertyFile(OrderedMap<TString, TString> Value) {
|
||||
FData.Append(Value);
|
||||
}
|
||||
|
||||
PropertyFile::PropertyFile(PropertyFile &Value) {
|
||||
FData = Value.FData;
|
||||
FReadOnly = Value.FReadOnly;
|
||||
FModified = Value.FModified;
|
||||
}
|
||||
|
||||
PropertyFile::~PropertyFile(void) {
|
||||
FData.Clear();
|
||||
}
|
||||
|
||||
void PropertyFile::SetModified(bool Value) {
|
||||
FModified = Value;
|
||||
}
|
||||
|
||||
bool PropertyFile::IsModified() {
|
||||
return FModified;
|
||||
}
|
||||
|
||||
bool PropertyFile::GetReadOnly() {
|
||||
return FReadOnly;
|
||||
}
|
||||
|
||||
void PropertyFile::SetReadOnly(bool Value) {
|
||||
FReadOnly = Value;
|
||||
}
|
||||
|
||||
bool PropertyFile::LoadFromFile(const TString FileName) {
|
||||
bool result = false;
|
||||
Platform& platform = Platform::GetInstance();
|
||||
|
||||
std::list<TString> contents = platform.LoadFromFile(FileName);
|
||||
|
||||
if (contents.empty() == false) {
|
||||
for (std::list<TString>::const_iterator iterator = contents.begin();
|
||||
iterator != contents.end(); iterator++) {
|
||||
TString line = *iterator;
|
||||
TString name;
|
||||
TString value;
|
||||
|
||||
if (Helpers::SplitOptionIntoNameValue(line, name, value) == true) {
|
||||
FData.Append(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
SetModified(false);
|
||||
result = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool PropertyFile::SaveToFile(const TString FileName, bool ownerOnly) {
|
||||
bool result = false;
|
||||
|
||||
if (GetReadOnly() == false && IsModified()) {
|
||||
std::list<TString> contents;
|
||||
std::vector<TString> keys = FData.GetKeys();
|
||||
|
||||
for (size_t index = 0; index < keys.size(); index++) {
|
||||
TString name = keys[index];
|
||||
|
||||
try {
|
||||
TString value;// = FData[index];
|
||||
|
||||
if (FData.GetValue(name, value) == true) {
|
||||
TString line = name + _T('=') + value;
|
||||
contents.push_back(line);
|
||||
}
|
||||
}
|
||||
catch (std::out_of_range &) {
|
||||
}
|
||||
}
|
||||
|
||||
Platform& platform = Platform::GetInstance();
|
||||
platform.SaveToFile(FileName, contents, ownerOnly);
|
||||
|
||||
SetModified(false);
|
||||
result = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool PropertyFile::GetValue(const TString Key, TString& Value) {
|
||||
return FData.GetValue(Key, Value);
|
||||
}
|
||||
|
||||
bool PropertyFile::SetValue(const TString Key, TString Value) {
|
||||
bool result = false;
|
||||
|
||||
if (GetReadOnly() == false) {
|
||||
FData.SetValue(Key, Value);
|
||||
SetModified(true);
|
||||
result = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool PropertyFile::RemoveKey(const TString Key) {
|
||||
bool result = false;
|
||||
|
||||
if (GetReadOnly() == false) {
|
||||
result = FData.RemoveByKey(Key);
|
||||
|
||||
if (result == true) {
|
||||
SetModified(true);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t PropertyFile::GetCount() {
|
||||
return FData.Count();
|
||||
}
|
||||
|
||||
OrderedMap<TString, TString> PropertyFile::GetData() {
|
||||
return FData;
|
||||
}
|
@ -1,65 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2019, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#ifndef PROPERTYFILE_H
|
||||
#define PROPERTYFILE_H
|
||||
|
||||
#include "Platform.h"
|
||||
#include "Helpers.h"
|
||||
|
||||
|
||||
class PropertyFile : public IPropertyContainer {
|
||||
private:
|
||||
bool FReadOnly;
|
||||
bool FModified;
|
||||
OrderedMap<TString, TString> FData;
|
||||
|
||||
void SetModified(bool Value);
|
||||
|
||||
public:
|
||||
PropertyFile(void);
|
||||
PropertyFile(const TString FileName);
|
||||
PropertyFile(OrderedMap<TString, TString> Value);
|
||||
PropertyFile(PropertyFile &Value);
|
||||
virtual ~PropertyFile(void);
|
||||
|
||||
bool IsModified();
|
||||
bool GetReadOnly();
|
||||
void SetReadOnly(bool Value);
|
||||
|
||||
bool LoadFromFile(const TString FileName);
|
||||
bool SaveToFile(const TString FileName, bool ownerOnly = true);
|
||||
|
||||
bool SetValue(const TString Key, TString Value);
|
||||
bool RemoveKey(const TString Key);
|
||||
|
||||
OrderedMap<TString, TString> GetData();
|
||||
|
||||
// IPropertyContainer
|
||||
virtual bool GetValue(const TString Key, TString& Value);
|
||||
virtual size_t GetCount();
|
||||
};
|
||||
|
||||
#endif // PROPERTYFILE_H
|
@ -1,180 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2019, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#include "Platform.h"
|
||||
#include "PlatformString.h"
|
||||
#include "FilePath.h"
|
||||
#include "PropertyFile.h"
|
||||
#include "JavaVirtualMachine.h"
|
||||
#include "Package.h"
|
||||
#include "Macros.h"
|
||||
#include "Messages.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/*
|
||||
This is the app launcher program for application packaging on Windows, Mac,
|
||||
and Linux.
|
||||
|
||||
Basic approach:
|
||||
- Launcher (jpackageapplauncher) is executable that loads
|
||||
applauncher.dll/libapplauncher.dylib/libapplauncher.so
|
||||
and calls start_launcher below.
|
||||
- Reads app/package.cfg or Info.plist or app/<appname>.cfg for application
|
||||
launch configuration (package.cfg is property file).
|
||||
- Load Java with requested Java settings (bundled client Java if availble,
|
||||
server or installed Java otherwise).
|
||||
- Wait for Java to exit and then exit from Main
|
||||
- To debug application by passing command line argument.
|
||||
- Application folder is added to the library path (so LoadLibrary()) works.
|
||||
|
||||
Limitations and future work:
|
||||
- Running Java code in primordial thread may cause problems
|
||||
(example: can not use custom stack size).
|
||||
Solution used by java launcher is to create a new thread to invoke Java.
|
||||
See CR 6316197 for more information.
|
||||
*/
|
||||
|
||||
extern "C" {
|
||||
|
||||
JNIEXPORT bool start_launcher(int argc, TCHAR* argv[]) {
|
||||
bool result = false;
|
||||
bool parentProcess = true;
|
||||
|
||||
// Platform must be initialize first.
|
||||
Platform& platform = Platform::GetInstance();
|
||||
|
||||
try {
|
||||
for (int index = 0; index < argc; index++) {
|
||||
TString argument = argv[index];
|
||||
|
||||
if (argument == _T("-Xappcds:generatecache")) {
|
||||
platform.SetAppCDSState(cdsGenCache);
|
||||
}
|
||||
else if (argument == _T("-Xappcds:off")) {
|
||||
platform.SetAppCDSState(cdsDisabled);
|
||||
}
|
||||
else if (argument == _T("-Xapp:child")) {
|
||||
parentProcess = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Package must be initialized after Platform is fully initialized.
|
||||
Package& package = Package::GetInstance();
|
||||
Macros::Initialize();
|
||||
package.SetCommandLineArguments(argc, argv);
|
||||
|
||||
switch (platform.GetAppCDSState()) {
|
||||
case cdsDisabled:
|
||||
case cdsUninitialized:
|
||||
case cdsEnabled: {
|
||||
break;
|
||||
}
|
||||
|
||||
case cdsGenCache: {
|
||||
TString cacheDirectory = package.GetAppCDSCacheDirectory();
|
||||
|
||||
if (FilePath::DirectoryExists(cacheDirectory) == false) {
|
||||
FilePath::CreateDirectory(cacheDirectory, true);
|
||||
} else {
|
||||
TString cacheFileName =
|
||||
package.GetAppCDSCacheFileName();
|
||||
if (FilePath::FileExists(cacheFileName) == true) {
|
||||
FilePath::DeleteFile(cacheFileName);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case cdsAuto: {
|
||||
TString cacheFileName = package.GetAppCDSCacheFileName();
|
||||
|
||||
if (parentProcess == true &&
|
||||
FilePath::FileExists(cacheFileName) == false) {
|
||||
AutoFreePtr<Process> process = platform.CreateProcess();
|
||||
std::vector<TString> args;
|
||||
args.push_back(_T("-Xappcds:generatecache"));
|
||||
args.push_back(_T("-Xapp:child"));
|
||||
process->Execute(
|
||||
platform.GetModuleFileName(), args, true);
|
||||
|
||||
if (FilePath::FileExists(cacheFileName) == false) {
|
||||
// Cache does not exist after trying to generate it,
|
||||
// so run without cache.
|
||||
platform.SetAppCDSState(cdsDisabled);
|
||||
package.Clear();
|
||||
package.Initialize();
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Validation
|
||||
switch (platform.GetAppCDSState()) {
|
||||
case cdsDisabled:
|
||||
case cdsGenCache: {
|
||||
// Do nothing.
|
||||
break;
|
||||
}
|
||||
|
||||
case cdsEnabled:
|
||||
case cdsAuto: {
|
||||
TString cacheFileName =
|
||||
package.GetAppCDSCacheFileName();
|
||||
|
||||
if (FilePath::FileExists(cacheFileName) == false) {
|
||||
Messages& messages = Messages::GetInstance();
|
||||
TString message = PlatformString::Format(
|
||||
messages.GetMessage(
|
||||
APPCDS_CACHE_FILE_NOT_FOUND),
|
||||
cacheFileName.data());
|
||||
throw Exception(message);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case cdsUninitialized: {
|
||||
platform.ShowMessage(_T("Internal Error"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Run App
|
||||
result = RunVM();
|
||||
} catch (Exception &e) {
|
||||
platform.ShowMessage(e.GetMessage());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
JNIEXPORT void stop_launcher() {
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 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
|
||||
@ -23,27 +23,22 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#ifndef MACROS_H
|
||||
#define MACROS_H
|
||||
|
||||
#include "Platform.h"
|
||||
|
||||
#include <map>
|
||||
#include "PlatformLogEvent.h"
|
||||
#include "Log.h"
|
||||
|
||||
|
||||
class Macros {
|
||||
private:
|
||||
std::map<TString, TString> FData;
|
||||
void LogEvent::init(PlatformLogEvent& logEvent) {
|
||||
}
|
||||
|
||||
Macros(void);
|
||||
|
||||
public:
|
||||
static Macros& GetInstance();
|
||||
static void Initialize();
|
||||
~Macros(void);
|
||||
void LogEvent::appendFormatted(const PlatformLogEvent& logEvent,
|
||||
tstring& buffer) {
|
||||
}
|
||||
|
||||
TString ExpandMacros(TString Value);
|
||||
void AddMacro(TString Key, TString Value);
|
||||
};
|
||||
|
||||
#endif // MACROS_H
|
||||
void Logger::initializingLogging() {
|
||||
}
|
||||
|
||||
|
||||
void Logger::initializeLogging() {
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 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
|
||||
@ -23,13 +23,11 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
#ifndef PlatformLogEvent_h
|
||||
#define PlatformLogEvent_h
|
||||
|
||||
extern "C" {
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason,
|
||||
LPVOID lpvReserved) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
struct PlatformLogEvent {
|
||||
};
|
||||
|
||||
#endif // PlatformLogEvent_h
|
68
src/jdk.incubator.jpackage/unix/native/common/UnixDll.cpp
Normal file
68
src/jdk.incubator.jpackage/unix/native/common/UnixDll.cpp
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include "Dll.h"
|
||||
#include "FileUtils.h"
|
||||
#include "ErrorHandling.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
HMODULE loadLibrary(const tstring& path) {
|
||||
HMODULE h = dlopen(path.c_str(), RTLD_LAZY);
|
||||
if (!h) {
|
||||
JP_THROW(tstrings::any() << "dlopen(" << path
|
||||
<< ") failed. Error: " << dlerror());
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
} // namesace
|
||||
|
||||
Dll::Dll(const tstrings::any &libPath): thePath(libPath.tstr()),
|
||||
handle(loadLibrary(thePath)) {
|
||||
}
|
||||
|
||||
Dll::Dll(const Dll& other): thePath(other.thePath),
|
||||
handle(loadLibrary(thePath)) {
|
||||
}
|
||||
|
||||
void* Dll::getFunction(const std::string &name, bool throwIfNotFound) const {
|
||||
void *ptr = dlsym(handle.get(), name.c_str());
|
||||
if (throwIfNotFound && !ptr) {
|
||||
JP_THROW(tstrings::any() << "dlsym(" << thePath
|
||||
<< ", " << name << ") failed. Error: " << dlerror());
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void Dll::freeLibrary(HMODULE h) {
|
||||
if (h) {
|
||||
dlclose(h);
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 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
|
||||
@ -23,45 +23,43 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#ifndef PLATFORM_DEFS_H
|
||||
#define PLATFORM_DEFS_H
|
||||
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
#include <sys/stat.h>
|
||||
#include <dlfcn.h>
|
||||
#include <libgen.h>
|
||||
#include <string>
|
||||
#include <unistd.h>
|
||||
#include "FileUtils.h"
|
||||
#include "ErrorHandling.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
#ifndef LINUX
|
||||
#define LINUX
|
||||
#endif
|
||||
namespace FileUtils {
|
||||
|
||||
#define _T(x) x
|
||||
bool isFileExists(const tstring &filePath) {
|
||||
struct stat statBuffer;
|
||||
return (stat(filePath.c_str(), &statBuffer) != -1);
|
||||
}
|
||||
|
||||
typedef char TCHAR;
|
||||
typedef std::string TString;
|
||||
#define StringLength strlen
|
||||
|
||||
typedef unsigned long DWORD;
|
||||
tstring toAbsolutePath(const tstring& path) {
|
||||
if (path.empty()) {
|
||||
char buffer[PATH_MAX] = { 0 };
|
||||
char* buf = getcwd(buffer, sizeof(buffer));
|
||||
if (buf) {
|
||||
tstring result(buf);
|
||||
if (result.empty()) {
|
||||
JP_THROW(tstrings::any() << "getcwd() returned empty string");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#define TRAILING_PATHSEPARATOR '/'
|
||||
#define BAD_TRAILING_PATHSEPARATOR '\\'
|
||||
#define PATH_SEPARATOR ':'
|
||||
#define BAD_PATH_SEPARATOR ';'
|
||||
#define MAX_PATH 1000
|
||||
JP_THROW(tstrings::any() << "getcwd() failed. Error: "
|
||||
<< lastCRTError());
|
||||
}
|
||||
|
||||
typedef long TPlatformNumber;
|
||||
typedef pid_t TProcessID;
|
||||
if (isDirSeparator(path[0])) {
|
||||
return path;
|
||||
}
|
||||
|
||||
#define HMODULE void*
|
||||
return mkpath() << toAbsolutePath("") << path;
|
||||
}
|
||||
|
||||
typedef void* Module;
|
||||
typedef void* Procedure;
|
||||
|
||||
#define StringToFileSystemString PlatformString
|
||||
#define FileSystemStringToString PlatformString
|
||||
|
||||
#endif // PLATFORM_DEFS_H
|
||||
} // namespace FileUtils
|
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "SysInfo.h"
|
||||
#include "UnixSysInfo.h"
|
||||
#include "ErrorHandling.h"
|
||||
|
||||
namespace SysInfo {
|
||||
|
||||
tstring getEnvVariable(const tstring& name) {
|
||||
char *value = ::getenv(name.c_str());
|
||||
if (!value) {
|
||||
JP_THROW(tstrings::any() << "getenv("
|
||||
<< name
|
||||
<< ") failed. Variable not set");
|
||||
}
|
||||
return tstring(value);
|
||||
}
|
||||
|
||||
|
||||
tstring getEnvVariable(const std::nothrow_t&, const tstring& name,
|
||||
const tstring& defValue) {
|
||||
char *value = ::getenv(name.c_str());
|
||||
if (value) {
|
||||
return tstring(value);
|
||||
}
|
||||
return defValue;
|
||||
}
|
||||
|
||||
|
||||
bool isEnvVariableSet(const tstring& name) {
|
||||
return ::getenv(name.c_str()) != 0;
|
||||
}
|
||||
|
||||
|
||||
tstring_array getCommandArgs(CommandArgProgramNameMode progNameMode) {
|
||||
tstring_array result;
|
||||
for (int i = progNameMode == ExcludeProgramName ? 1 : 0; i < argc; i++) {
|
||||
result.push_back(argv[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
int argc = 0;
|
||||
char** argv = 0;
|
||||
|
||||
} // end of namespace SysInfo
|
35
src/jdk.incubator.jpackage/unix/native/common/UnixSysInfo.h
Normal file
35
src/jdk.incubator.jpackage/unix/native/common/UnixSysInfo.h
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#ifndef UnixSysInfo_h
|
||||
#define UnixSysInfo_h
|
||||
|
||||
|
||||
namespace SysInfo {
|
||||
extern int argc;
|
||||
extern char** argv;
|
||||
} // UnixSysInfo
|
||||
|
||||
#endif // UnixSysInfo_h
|
@ -1,331 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2019, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#include "FileAttributes.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <list>
|
||||
#include <sys/stat.h>
|
||||
|
||||
FileAttributes::FileAttributes(const TString FileName, bool FollowLink) {
|
||||
FFileName = FileName;
|
||||
FFollowLink = FollowLink;
|
||||
ReadAttributes();
|
||||
}
|
||||
|
||||
bool FileAttributes::WriteAttributes() {
|
||||
bool result = false;
|
||||
|
||||
mode_t attributes = 0;
|
||||
|
||||
for (std::vector<FileAttribute>::const_iterator iterator =
|
||||
FAttributes.begin();
|
||||
iterator != FAttributes.end(); iterator++) {
|
||||
switch (*iterator) {
|
||||
case faBlockSpecial:
|
||||
{
|
||||
attributes |= S_IFBLK;
|
||||
break;
|
||||
}
|
||||
case faCharacterSpecial:
|
||||
{
|
||||
attributes |= S_IFCHR;
|
||||
break;
|
||||
}
|
||||
case faFIFOSpecial:
|
||||
{
|
||||
attributes |= S_IFIFO;
|
||||
break;
|
||||
}
|
||||
case faNormal:
|
||||
{
|
||||
attributes |= S_IFREG;
|
||||
break;
|
||||
}
|
||||
case faDirectory:
|
||||
{
|
||||
attributes |= S_IFDIR;
|
||||
break;
|
||||
}
|
||||
case faSymbolicLink:
|
||||
{
|
||||
attributes |= S_IFLNK;
|
||||
break;
|
||||
}
|
||||
case faSocket:
|
||||
{
|
||||
attributes |= S_IFSOCK;
|
||||
break;
|
||||
}
|
||||
|
||||
// Owner
|
||||
case faReadOnly:
|
||||
{
|
||||
attributes |= S_IRUSR;
|
||||
break;
|
||||
}
|
||||
case faWriteOnly:
|
||||
{
|
||||
attributes |= S_IWUSR;
|
||||
break;
|
||||
}
|
||||
case faReadWrite:
|
||||
{
|
||||
attributes |= S_IRUSR;
|
||||
attributes |= S_IWUSR;
|
||||
break;
|
||||
}
|
||||
case faExecute:
|
||||
{
|
||||
attributes |= S_IXUSR;
|
||||
break;
|
||||
}
|
||||
|
||||
// Group
|
||||
case faGroupReadOnly:
|
||||
{
|
||||
attributes |= S_IRGRP;
|
||||
break;
|
||||
}
|
||||
case faGroupWriteOnly:
|
||||
{
|
||||
attributes |= S_IWGRP;
|
||||
break;
|
||||
}
|
||||
case faGroupReadWrite:
|
||||
{
|
||||
attributes |= S_IRGRP;
|
||||
attributes |= S_IWGRP;
|
||||
break;
|
||||
}
|
||||
case faGroupExecute:
|
||||
{
|
||||
attributes |= S_IXGRP;
|
||||
break;
|
||||
}
|
||||
|
||||
// Others
|
||||
case faOthersReadOnly:
|
||||
{
|
||||
attributes |= S_IROTH;
|
||||
break;
|
||||
}
|
||||
case faOthersWriteOnly:
|
||||
{
|
||||
attributes |= S_IWOTH;
|
||||
break;
|
||||
}
|
||||
case faOthersReadWrite:
|
||||
{
|
||||
attributes |= S_IROTH;
|
||||
attributes |= S_IWOTH;
|
||||
break;
|
||||
}
|
||||
case faOthersExecute:
|
||||
{
|
||||
attributes |= S_IXOTH;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (chmod(FFileName.data(), attributes) == 0) {
|
||||
result = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#define S_ISRUSR(m) (((m) & S_IRWXU) == S_IRUSR)
|
||||
#define S_ISWUSR(m) (((m) & S_IRWXU) == S_IWUSR)
|
||||
#define S_ISXUSR(m) (((m) & S_IRWXU) == S_IXUSR)
|
||||
|
||||
#define S_ISRGRP(m) (((m) & S_IRWXG) == S_IRGRP)
|
||||
#define S_ISWGRP(m) (((m) & S_IRWXG) == S_IWGRP)
|
||||
#define S_ISXGRP(m) (((m) & S_IRWXG) == S_IXGRP)
|
||||
|
||||
#define S_ISROTH(m) (((m) & S_IRWXO) == S_IROTH)
|
||||
#define S_ISWOTH(m) (((m) & S_IRWXO) == S_IWOTH)
|
||||
#define S_ISXOTH(m) (((m) & S_IRWXO) == S_IXOTH)
|
||||
|
||||
bool FileAttributes::ReadAttributes() {
|
||||
bool result = false;
|
||||
|
||||
struct stat status;
|
||||
|
||||
if (stat(StringToFileSystemString(FFileName), &status) == 0) {
|
||||
result = true;
|
||||
|
||||
if (S_ISBLK(status.st_mode) != 0) {
|
||||
FAttributes.push_back(faBlockSpecial);
|
||||
}
|
||||
if (S_ISCHR(status.st_mode) != 0) {
|
||||
FAttributes.push_back(faCharacterSpecial);
|
||||
}
|
||||
if (S_ISFIFO(status.st_mode) != 0) {
|
||||
FAttributes.push_back(faFIFOSpecial);
|
||||
}
|
||||
if (S_ISREG(status.st_mode) != 0) {
|
||||
FAttributes.push_back(faNormal);
|
||||
}
|
||||
if (S_ISDIR(status.st_mode) != 0) {
|
||||
FAttributes.push_back(faDirectory);
|
||||
}
|
||||
if (S_ISLNK(status.st_mode) != 0) {
|
||||
FAttributes.push_back(faSymbolicLink);
|
||||
}
|
||||
if (S_ISSOCK(status.st_mode) != 0) {
|
||||
FAttributes.push_back(faSocket);
|
||||
}
|
||||
|
||||
// Owner
|
||||
if (S_ISRUSR(status.st_mode) != 0) {
|
||||
if (S_ISWUSR(status.st_mode) != 0) {
|
||||
FAttributes.push_back(faReadWrite);
|
||||
} else {
|
||||
FAttributes.push_back(faReadOnly);
|
||||
}
|
||||
} else if (S_ISWUSR(status.st_mode) != 0) {
|
||||
FAttributes.push_back(faWriteOnly);
|
||||
}
|
||||
|
||||
if (S_ISXUSR(status.st_mode) != 0) {
|
||||
FAttributes.push_back(faExecute);
|
||||
}
|
||||
|
||||
// Group
|
||||
if (S_ISRGRP(status.st_mode) != 0) {
|
||||
if (S_ISWGRP(status.st_mode) != 0) {
|
||||
FAttributes.push_back(faGroupReadWrite);
|
||||
} else {
|
||||
FAttributes.push_back(faGroupReadOnly);
|
||||
}
|
||||
} else if (S_ISWGRP(status.st_mode) != 0) {
|
||||
FAttributes.push_back(faGroupWriteOnly);
|
||||
}
|
||||
|
||||
if (S_ISXGRP(status.st_mode) != 0) {
|
||||
FAttributes.push_back(faGroupExecute);
|
||||
}
|
||||
|
||||
|
||||
// Others
|
||||
if (S_ISROTH(status.st_mode) != 0) {
|
||||
if (S_ISWOTH(status.st_mode) != 0) {
|
||||
FAttributes.push_back(faOthersReadWrite);
|
||||
} else {
|
||||
FAttributes.push_back(faOthersReadOnly);
|
||||
}
|
||||
} else if (S_ISWOTH(status.st_mode) != 0) {
|
||||
FAttributes.push_back(faOthersWriteOnly);
|
||||
}
|
||||
|
||||
if (S_ISXOTH(status.st_mode) != 0) {
|
||||
FAttributes.push_back(faOthersExecute);
|
||||
}
|
||||
|
||||
if (FFileName.size() > 0 && FFileName[0] == '.') {
|
||||
FAttributes.push_back(faHidden);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool FileAttributes::Valid(const FileAttribute Value) {
|
||||
bool result = false;
|
||||
|
||||
switch (Value) {
|
||||
case faReadWrite:
|
||||
case faWriteOnly:
|
||||
case faExecute:
|
||||
|
||||
case faGroupReadWrite:
|
||||
case faGroupWriteOnly:
|
||||
case faGroupReadOnly:
|
||||
case faGroupExecute:
|
||||
|
||||
case faOthersReadWrite:
|
||||
case faOthersWriteOnly:
|
||||
case faOthersReadOnly:
|
||||
case faOthersExecute:
|
||||
|
||||
case faReadOnly:
|
||||
result = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void FileAttributes::Append(FileAttribute Value) {
|
||||
if (Valid(Value) == true) {
|
||||
if ((Value == faReadOnly && Contains(faWriteOnly) == true) ||
|
||||
(Value == faWriteOnly && Contains(faReadOnly) == true)) {
|
||||
Value = faReadWrite;
|
||||
}
|
||||
|
||||
FAttributes.push_back(Value);
|
||||
WriteAttributes();
|
||||
}
|
||||
}
|
||||
|
||||
bool FileAttributes::Contains(FileAttribute Value) {
|
||||
bool result = false;
|
||||
|
||||
std::vector<FileAttribute>::const_iterator iterator =
|
||||
std::find(FAttributes.begin(), FAttributes.end(), Value);
|
||||
|
||||
if (iterator != FAttributes.end()) {
|
||||
result = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void FileAttributes::Remove(FileAttribute Value) {
|
||||
if (Valid(Value) == true) {
|
||||
if (Value == faReadOnly && Contains(faReadWrite) == true) {
|
||||
Append(faWriteOnly);
|
||||
Remove(faReadWrite);
|
||||
} else if (Value == faWriteOnly && Contains(faReadWrite) == true) {
|
||||
Append(faReadOnly);
|
||||
Remove(faReadWrite);
|
||||
}
|
||||
|
||||
std::vector<FileAttribute>::iterator iterator =
|
||||
std::find(FAttributes.begin(), FAttributes.end(), Value);
|
||||
|
||||
if (iterator != FAttributes.end()) {
|
||||
FAttributes.erase(iterator);
|
||||
WriteAttributes();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,197 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2019, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#include "PlatformDefs.h"
|
||||
#include "FilePath.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <list>
|
||||
#include <sys/stat.h>
|
||||
|
||||
bool FilePath::FileExists(const TString FileName) {
|
||||
bool result = false;
|
||||
struct stat buf;
|
||||
|
||||
if ((stat(StringToFileSystemString(FileName), &buf) == 0) &&
|
||||
(S_ISREG(buf.st_mode) != 0)) {
|
||||
result = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool FilePath::DirectoryExists(const TString DirectoryName) {
|
||||
bool result = false;
|
||||
|
||||
struct stat buf;
|
||||
|
||||
if ((stat(StringToFileSystemString(DirectoryName), &buf) == 0) &&
|
||||
(S_ISDIR(buf.st_mode) != 0)) {
|
||||
result = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool FilePath::DeleteFile(const TString FileName) {
|
||||
bool result = false;
|
||||
|
||||
if (FileExists(FileName) == true) {
|
||||
if (unlink(StringToFileSystemString(FileName)) == 0) {
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool FilePath::DeleteDirectory(const TString DirectoryName) {
|
||||
bool result = false;
|
||||
|
||||
if (DirectoryExists(DirectoryName) == true) {
|
||||
if (unlink(StringToFileSystemString(DirectoryName)) == 0) {
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
TString FilePath::IncludeTrailingSeparator(const TString value) {
|
||||
TString result = value;
|
||||
|
||||
if (value.size() > 0) {
|
||||
TString::iterator i = result.end();
|
||||
i--;
|
||||
|
||||
if (*i != TRAILING_PATHSEPARATOR) {
|
||||
result += TRAILING_PATHSEPARATOR;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
TString FilePath::IncludeTrailingSeparator(const char* value) {
|
||||
TString lvalue = PlatformString(value).toString();
|
||||
return IncludeTrailingSeparator(lvalue);
|
||||
}
|
||||
|
||||
TString FilePath::IncludeTrailingSeparator(const wchar_t* value) {
|
||||
TString lvalue = PlatformString(value).toString();
|
||||
return IncludeTrailingSeparator(lvalue);
|
||||
}
|
||||
|
||||
TString FilePath::ExtractFilePath(TString Path) {
|
||||
return dirname(StringToFileSystemString(Path));
|
||||
}
|
||||
|
||||
TString FilePath::ExtractFileExt(TString Path) {
|
||||
TString result;
|
||||
size_t dot = Path.find_last_of('.');
|
||||
|
||||
if (dot != TString::npos) {
|
||||
result = Path.substr(dot, Path.size() - dot);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
TString FilePath::ExtractFileName(TString Path) {
|
||||
return basename(StringToFileSystemString(Path));
|
||||
}
|
||||
|
||||
TString FilePath::ChangeFileExt(TString Path, TString Extension) {
|
||||
TString result;
|
||||
size_t dot = Path.find_last_of('.');
|
||||
|
||||
if (dot != TString::npos) {
|
||||
result = Path.substr(0, dot) + Extension;
|
||||
}
|
||||
|
||||
if (result.empty() == true) {
|
||||
result = Path;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
TString FilePath::FixPathForPlatform(TString Path) {
|
||||
TString result = Path;
|
||||
std::replace(result.begin(), result.end(),
|
||||
BAD_TRAILING_PATHSEPARATOR, TRAILING_PATHSEPARATOR);
|
||||
return result;
|
||||
}
|
||||
|
||||
TString FilePath::FixPathSeparatorForPlatform(TString Path) {
|
||||
TString result = Path;
|
||||
std::replace(result.begin(), result.end(),
|
||||
BAD_PATH_SEPARATOR, PATH_SEPARATOR);
|
||||
return result;
|
||||
}
|
||||
|
||||
TString FilePath::PathSeparator() {
|
||||
TString result;
|
||||
result = PATH_SEPARATOR;
|
||||
return result;
|
||||
}
|
||||
|
||||
bool FilePath::CreateDirectory(TString Path, bool ownerOnly) {
|
||||
bool result = false;
|
||||
|
||||
std::list<TString> paths;
|
||||
TString lpath = Path;
|
||||
|
||||
while (lpath.empty() == false && DirectoryExists(lpath) == false) {
|
||||
paths.push_front(lpath);
|
||||
lpath = ExtractFilePath(lpath);
|
||||
}
|
||||
|
||||
for (std::list<TString>::iterator iterator = paths.begin();
|
||||
iterator != paths.end(); iterator++) {
|
||||
lpath = *iterator;
|
||||
|
||||
mode_t mode = S_IRWXU;
|
||||
if (!ownerOnly) {
|
||||
mode |= S_IRWXG | S_IROTH | S_IXOTH;
|
||||
}
|
||||
if (mkdir(StringToFileSystemString(lpath), mode) == 0) {
|
||||
result = true;
|
||||
} else {
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void FilePath::ChangePermissions(TString FileName, bool ownerOnly) {
|
||||
mode_t mode = S_IRWXU;
|
||||
if (!ownerOnly) {
|
||||
mode |= S_IRWXG | S_IROTH | S_IXOTH;
|
||||
}
|
||||
chmod(FileName.data(), mode);
|
||||
}
|
@ -1,313 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2019, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#include "PosixPlatform.h"
|
||||
|
||||
#include "PlatformString.h"
|
||||
#include "FilePath.h"
|
||||
#include "Helpers.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <pwd.h>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <dlfcn.h>
|
||||
#include <signal.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
PosixPlatform::PosixPlatform(void) {
|
||||
}
|
||||
|
||||
PosixPlatform::~PosixPlatform(void) {
|
||||
}
|
||||
|
||||
TString PosixPlatform::GetTempDirectory() {
|
||||
struct passwd* pw = getpwuid(getuid());
|
||||
TString homedir(pw->pw_dir);
|
||||
homedir += getTmpDirString();
|
||||
if (!FilePath::DirectoryExists(homedir)) {
|
||||
if (!FilePath::CreateDirectory(homedir, false)) {
|
||||
homedir.clear();
|
||||
}
|
||||
}
|
||||
|
||||
return homedir;
|
||||
}
|
||||
|
||||
TString PosixPlatform::fixName(const TString& name) {
|
||||
TString fixedName(name);
|
||||
const TString chars("?:*<>/\\");
|
||||
for (TString::const_iterator it = chars.begin(); it != chars.end(); it++) {
|
||||
fixedName.erase(std::remove(fixedName.begin(),
|
||||
fixedName.end(), *it), fixedName.end());
|
||||
}
|
||||
return fixedName;
|
||||
}
|
||||
|
||||
MessageResponse PosixPlatform::ShowResponseMessage(TString title,
|
||||
TString description) {
|
||||
MessageResponse result = mrCancel;
|
||||
|
||||
printf("%s %s (Y/N)\n", PlatformString(title).toPlatformString(),
|
||||
PlatformString(description).toPlatformString());
|
||||
fflush(stdout);
|
||||
|
||||
std::string input;
|
||||
std::cin >> input;
|
||||
|
||||
if (input == "Y") {
|
||||
result = mrOK;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Module PosixPlatform::LoadLibrary(TString FileName) {
|
||||
return dlopen(StringToFileSystemString(FileName), RTLD_LAZY);
|
||||
}
|
||||
|
||||
void PosixPlatform::FreeLibrary(Module AModule) {
|
||||
dlclose(AModule);
|
||||
}
|
||||
|
||||
Procedure PosixPlatform::GetProcAddress(Module AModule,
|
||||
std::string MethodName) {
|
||||
return dlsym(AModule, PlatformString(MethodName));
|
||||
}
|
||||
|
||||
Process* PosixPlatform::CreateProcess() {
|
||||
return new PosixProcess();
|
||||
}
|
||||
|
||||
void PosixPlatform::addPlatformDependencies(JavaLibrary *pJavaLibrary) {
|
||||
}
|
||||
|
||||
void Platform::CopyString(char *Destination,
|
||||
size_t NumberOfElements, const char *Source) {
|
||||
strncpy(Destination, Source, NumberOfElements);
|
||||
|
||||
if (NumberOfElements > 0) {
|
||||
Destination[NumberOfElements - 1] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
void Platform::CopyString(wchar_t *Destination,
|
||||
size_t NumberOfElements, const wchar_t *Source) {
|
||||
wcsncpy(Destination, Source, NumberOfElements);
|
||||
|
||||
if (NumberOfElements > 0) {
|
||||
Destination[NumberOfElements - 1] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
// Owner must free the return value.
|
||||
|
||||
MultibyteString Platform::WideStringToMultibyteString(
|
||||
const wchar_t* value) {
|
||||
MultibyteString result;
|
||||
size_t count = 0;
|
||||
|
||||
if (value == NULL) {
|
||||
return result;
|
||||
}
|
||||
|
||||
count = wcstombs(NULL, value, 0);
|
||||
if (count > 0) {
|
||||
result.data = new char[count + 1];
|
||||
result.data[count] = '\0';
|
||||
result.length = count;
|
||||
wcstombs(result.data, value, count);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Owner must free the return value.
|
||||
|
||||
WideString Platform::MultibyteStringToWideString(const char* value) {
|
||||
WideString result;
|
||||
size_t count = 0;
|
||||
|
||||
if (value == NULL) {
|
||||
return result;
|
||||
}
|
||||
|
||||
count = mbstowcs(NULL, value, 0);
|
||||
if (count > 0) {
|
||||
result.data = new wchar_t[count + 1];
|
||||
result.data[count] = '\0';
|
||||
result.length = count;
|
||||
mbstowcs(result.data, value, count);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void PosixPlatform::InitStreamLocale(wios *stream) {
|
||||
// Nothing to do for POSIX platforms.
|
||||
}
|
||||
|
||||
PosixProcess::PosixProcess() : Process() {
|
||||
FChildPID = 0;
|
||||
FRunning = false;
|
||||
FOutputHandle = 0;
|
||||
FInputHandle = 0;
|
||||
}
|
||||
|
||||
PosixProcess::~PosixProcess() {
|
||||
Terminate();
|
||||
}
|
||||
|
||||
bool PosixProcess::ReadOutput() {
|
||||
bool result = false;
|
||||
|
||||
if (FOutputHandle != 0 && IsRunning() == true) {
|
||||
char buffer[4096] = {0};
|
||||
|
||||
ssize_t count = read(FOutputHandle, buffer, sizeof (buffer));
|
||||
|
||||
if (count == -1) {
|
||||
if (errno == EINTR) {
|
||||
// continue;
|
||||
} else {
|
||||
perror("read");
|
||||
exit(1);
|
||||
}
|
||||
} else if (count == 0) {
|
||||
// break;
|
||||
} else {
|
||||
std::list<TString> output = Helpers::StringToArray(buffer);
|
||||
FOutput.splice(FOutput.end(), output, output.begin(), output.end());
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PosixProcess::IsRunning() {
|
||||
bool result = false;
|
||||
|
||||
if (kill(FChildPID, 0) == 0) {
|
||||
result = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool PosixProcess::Terminate() {
|
||||
bool result = false;
|
||||
|
||||
if (IsRunning() == true && FRunning == true) {
|
||||
FRunning = false;
|
||||
Cleanup();
|
||||
int status = kill(FChildPID, SIGTERM);
|
||||
|
||||
if (status == 0) {
|
||||
result = true;
|
||||
} else {
|
||||
#ifdef DEBUG
|
||||
if (errno == EINVAL) {
|
||||
printf("Kill error: The value of the sig argument is an invalid or unsupported signal number.");
|
||||
} else if (errno == EPERM) {
|
||||
printf("Kill error: The process does not have permission to send the signal to any receiving process.");
|
||||
} else if (errno == ESRCH) {
|
||||
printf("Kill error: No process or process group can be found corresponding to that specified by pid.");
|
||||
}
|
||||
#endif // DEBUG
|
||||
if (IsRunning() == true) {
|
||||
status = kill(FChildPID, SIGKILL);
|
||||
|
||||
if (status == 0) {
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool PosixProcess::Wait() {
|
||||
bool result = false;
|
||||
|
||||
int status = 0;
|
||||
pid_t wpid = 0;
|
||||
|
||||
wpid = wait(&status);
|
||||
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
|
||||
if (errno != EINTR) {
|
||||
status = -1;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
if (WIFEXITED(status)) {
|
||||
printf("child exited, status=%d\n", WEXITSTATUS(status));
|
||||
} else if (WIFSIGNALED(status)) {
|
||||
printf("child killed (signal %d)\n", WTERMSIG(status));
|
||||
} else if (WIFSTOPPED(status)) {
|
||||
printf("child stopped (signal %d)\n", WSTOPSIG(status));
|
||||
#ifdef WIFCONTINUED // Not all implementations support this
|
||||
} else if (WIFCONTINUED(status)) {
|
||||
printf("child continued\n");
|
||||
#endif // WIFCONTINUED
|
||||
} else { // Non-standard case -- may never happen
|
||||
printf("Unexpected status (0x%x)\n", status);
|
||||
}
|
||||
#endif // DEBUG
|
||||
|
||||
if (wpid != -1) {
|
||||
result = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
TProcessID PosixProcess::GetProcessID() {
|
||||
return FChildPID;
|
||||
}
|
||||
|
||||
void PosixProcess::SetInput(TString Value) {
|
||||
if (FInputHandle != 0) {
|
||||
if (write(FInputHandle, Value.data(), Value.size()) < 0) {
|
||||
throw Exception(_T("Internal Error - write failed"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::list<TString> PosixProcess::GetOutput() {
|
||||
ReadOutput();
|
||||
return Process::GetOutput();
|
||||
}
|
@ -1,83 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2019, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#ifndef POSIXPLATFORM_H
|
||||
#define POSIXPLATFORM_H
|
||||
|
||||
#include "Platform.h"
|
||||
#include <signal.h>
|
||||
|
||||
class PosixPlatform : virtual public Platform {
|
||||
protected:
|
||||
|
||||
TString fixName(const TString& name);
|
||||
|
||||
virtual TString getTmpDirString() = 0;
|
||||
|
||||
public:
|
||||
PosixPlatform(void);
|
||||
virtual ~PosixPlatform(void);
|
||||
|
||||
public:
|
||||
virtual MessageResponse ShowResponseMessage(TString title,
|
||||
TString description);
|
||||
|
||||
virtual Module LoadLibrary(TString FileName);
|
||||
virtual void FreeLibrary(Module AModule);
|
||||
virtual Procedure GetProcAddress(Module AModule, std::string MethodName);
|
||||
|
||||
virtual Process* CreateProcess();
|
||||
virtual TString GetTempDirectory();
|
||||
void InitStreamLocale(wios *stream);
|
||||
void addPlatformDependencies(JavaLibrary *pJavaLibrary);
|
||||
};
|
||||
|
||||
class PosixProcess : public Process {
|
||||
private:
|
||||
pid_t FChildPID;
|
||||
sigset_t saveblock;
|
||||
int FOutputHandle;
|
||||
int FInputHandle;
|
||||
struct sigaction savintr, savequit;
|
||||
bool FRunning;
|
||||
|
||||
void Cleanup();
|
||||
bool ReadOutput();
|
||||
|
||||
public:
|
||||
PosixProcess();
|
||||
virtual ~PosixProcess();
|
||||
|
||||
virtual bool IsRunning();
|
||||
virtual bool Terminate();
|
||||
virtual bool Execute(const TString Application,
|
||||
const std::vector<TString> Arguments, bool AWait = false);
|
||||
virtual bool Wait();
|
||||
virtual TProcessID GetProcessID();
|
||||
virtual void SetInput(TString Value);
|
||||
virtual std::list<TString> GetOutput();
|
||||
};
|
||||
|
||||
#endif // POSIXPLATFORM_H
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 2020, 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
|
||||
@ -64,8 +64,6 @@ public class WindowsAppImageBuilder extends AbstractAppImageBuilder {
|
||||
"jdk.incubator.jpackage.internal.resources.WinResources");
|
||||
|
||||
private final static String LIBRARY_NAME = "applauncher.dll";
|
||||
private final static String REDIST_MSVCR = "vcruntimeVS_VER.dll";
|
||||
private final static String REDIST_MSVCP = "msvcpVS_VER.dll";
|
||||
|
||||
private final static String TEMPLATE_APP_ICON ="java48.ico";
|
||||
|
||||
@ -189,13 +187,6 @@ public class WindowsAppImageBuilder extends AbstractAppImageBuilder {
|
||||
// copy the jars
|
||||
copyApplication(params);
|
||||
|
||||
// copy in the needed libraries
|
||||
try (InputStream is_lib = getResourceAsStream(LIBRARY_NAME)) {
|
||||
Files.copy(is_lib, binDir.resolve(LIBRARY_NAME));
|
||||
}
|
||||
|
||||
copyMSVCDLLs();
|
||||
|
||||
// create the additional launcher(s), if any
|
||||
List<Map<String, ? super Object>> entryPoints =
|
||||
StandardBundlerParam.ADD_LAUNCHERS.fetchFrom(params);
|
||||
@ -209,27 +200,6 @@ public class WindowsAppImageBuilder extends AbstractAppImageBuilder {
|
||||
public void prepareJreFiles(Map<String, ? super Object> params)
|
||||
throws IOException {}
|
||||
|
||||
private void copyMSVCDLLs() throws IOException {
|
||||
AtomicReference<IOException> ioe = new AtomicReference<>();
|
||||
try (Stream<Path> files = Files.list(runtimeDir.resolve("bin"))) {
|
||||
files.filter(p -> Pattern.matches(
|
||||
"^(vcruntime|msvcp|msvcr|ucrtbase|api-ms-win-).*\\.dll$",
|
||||
p.toFile().getName().toLowerCase()))
|
||||
.forEach(p -> {
|
||||
try {
|
||||
Files.copy(p, binDir.resolve((p.toFile().getName())));
|
||||
} catch (IOException e) {
|
||||
ioe.set(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
IOException e = ioe.get();
|
||||
if (e != null) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
private void validateValueAndPut(
|
||||
Map<String, String> data, String key,
|
||||
BundlerParamInfo<String> param,
|
||||
|
@ -0,0 +1,175 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#include <io.h>
|
||||
#include <fcntl.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include "AppLauncher.h"
|
||||
#include "Log.h"
|
||||
#include "FileUtils.h"
|
||||
#include "UniqueHandle.h"
|
||||
#include "ErrorHandling.h"
|
||||
#include "WinErrorHandling.h"
|
||||
|
||||
|
||||
// AllowSetForegroundWindow
|
||||
#pragma comment(lib, "user32")
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
void launchApp() {
|
||||
// [RT-31061] otherwise UI can be left in back of other windows.
|
||||
::AllowSetForegroundWindow(ASFW_ANY);
|
||||
|
||||
const tstring launcherPath = SysInfo::getProcessModulePath();
|
||||
const tstring appImageRoot = FileUtils::dirname(launcherPath);
|
||||
|
||||
AppLauncher()
|
||||
.setImageRoot(appImageRoot)
|
||||
.addJvmLibName(_T("bin\\jli.dll"))
|
||||
.setAppDir(FileUtils::mkpath() << appImageRoot << _T("app"))
|
||||
.setDefaultRuntimePath(FileUtils::mkpath() << appImageRoot
|
||||
<< _T("runtime"))
|
||||
.launch();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
#ifndef JP_LAUNCHERW
|
||||
|
||||
int APIENTRY wmain() {
|
||||
return AppLauncher::launch(std::nothrow, launchApp);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
namespace {
|
||||
|
||||
class LastErrorGuiLogAppender : public LogAppender {
|
||||
public:
|
||||
virtual void append(const LogEvent& v) {
|
||||
JP_TRY;
|
||||
|
||||
const std::wstring msg = (tstrings::any()
|
||||
<< AppLauncher::lastErrorMsg()).wstr();
|
||||
MessageBox(0, msg.c_str(),
|
||||
FileUtils::basename(SysInfo::getProcessModulePath()).c_str(),
|
||||
MB_ICONERROR | MB_OK);
|
||||
|
||||
JP_CATCH_ALL;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class Console {
|
||||
public:
|
||||
Console() {
|
||||
if (!AttachConsole(ATTACH_PARENT_PROCESS)) {
|
||||
// Failed to connect to parent's console. Create our own.
|
||||
if (!AllocConsole()) {
|
||||
// We already have a console, no need to redirect std I/O.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
stdoutChannel = std::unique_ptr<Channel>(new Channel(stdout));
|
||||
stderrChannel = std::unique_ptr<Channel>(new Channel(stderr));
|
||||
}
|
||||
|
||||
struct FileCloser {
|
||||
typedef FILE* pointer;
|
||||
|
||||
void operator()(pointer h) {
|
||||
::fclose(h);
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::unique_ptr<
|
||||
FileCloser::pointer,
|
||||
FileCloser
|
||||
> UniqueFILEHandle;
|
||||
|
||||
private:
|
||||
class Channel {
|
||||
public:
|
||||
Channel(FILE* stdFILEHandle): stdFILEHandle(stdFILEHandle) {
|
||||
const char* stdFileName = "CONOUT$";
|
||||
const char* openMode = "w";
|
||||
if (stdFILEHandle == stdin) {
|
||||
stdFileName = "CONIN$";
|
||||
openMode = "r";
|
||||
}
|
||||
|
||||
FILE* fp = 0;
|
||||
freopen_s(&fp, stdFileName, openMode, stdFILEHandle);
|
||||
|
||||
fileHandle = UniqueFILEHandle(fp);
|
||||
|
||||
std::ios_base::sync_with_stdio();
|
||||
}
|
||||
|
||||
virtual ~Channel() {
|
||||
JP_TRY;
|
||||
|
||||
FILE* fp = 0;
|
||||
fileHandle = UniqueFILEHandle(fp);
|
||||
std::ios_base::sync_with_stdio();
|
||||
|
||||
JP_CATCH_ALL;
|
||||
}
|
||||
|
||||
private:
|
||||
UniqueFILEHandle fileHandle;
|
||||
FILE *stdFILEHandle;
|
||||
};
|
||||
|
||||
std::unique_ptr<Channel> stdoutChannel;
|
||||
std::unique_ptr<Channel> stderrChannel;
|
||||
};
|
||||
|
||||
|
||||
void launchAppW() {
|
||||
std::unique_ptr<Console> console;
|
||||
if (AppLauncher::isWithLogging()) {
|
||||
console = std::unique_ptr<Console>(new Console());
|
||||
}
|
||||
|
||||
launchApp();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
int APIENTRY wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int) {
|
||||
LastErrorGuiLogAppender lastErrorLogAppender;
|
||||
TeeLogAppender logAppender(&AppLauncher::defaultLastErrorLogAppender(),
|
||||
&lastErrorLogAppender);
|
||||
return AppLauncher::launch(std::nothrow, launchAppW, &logAppender);
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#include <cstring>
|
||||
#include "PlatformLogEvent.h"
|
||||
#include "FileUtils.h"
|
||||
#include "Log.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
tstring retrieveModuleName() {
|
||||
try {
|
||||
return FileUtils::basename(SysInfo::getCurrentModulePath());
|
||||
}
|
||||
catch (const std::runtime_error&) {
|
||||
return _T("Unknown");
|
||||
}
|
||||
}
|
||||
|
||||
TCHAR moduleName[MAX_PATH] = { 'U', 'n', 'k', 'n', 'o', 'w', 'n', TCHAR(0) };
|
||||
|
||||
const LPCTSTR formatStr = _T("%04u/%02u/%02u %02u:%02u:%02u.%03u, %s (PID: %u, TID: %u), ");
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
PlatformLogEvent::PlatformLogEvent() {
|
||||
std::memset(static_cast<void*>(this), 0, sizeof(*this));
|
||||
}
|
||||
|
||||
|
||||
void LogEvent::init(PlatformLogEvent& logEvent) {
|
||||
GetLocalTime(&logEvent.ts);
|
||||
logEvent.pid = GetCurrentProcessId();
|
||||
logEvent.tid = GetCurrentThreadId();
|
||||
logEvent.moduleName = ::moduleName;
|
||||
}
|
||||
|
||||
|
||||
void LogEvent::appendFormatted(const PlatformLogEvent& logEvent,
|
||||
tstring& buffer) {
|
||||
const tstring str = tstrings::unsafe_format(formatStr,
|
||||
unsigned(logEvent.ts.wYear),
|
||||
unsigned(logEvent.ts.wMonth),
|
||||
unsigned(logEvent.ts.wDay),
|
||||
unsigned(logEvent.ts.wHour),
|
||||
unsigned(logEvent.ts.wMinute),
|
||||
unsigned(logEvent.ts.wSecond),
|
||||
unsigned(logEvent.ts.wMilliseconds),
|
||||
logEvent.moduleName,
|
||||
logEvent.pid,
|
||||
logEvent.tid);
|
||||
buffer.append(str);
|
||||
}
|
||||
|
||||
|
||||
void Logger::initializingLogging() {
|
||||
moduleName[0] = TCHAR(0);
|
||||
}
|
||||
|
||||
|
||||
void Logger::initializeLogging() {
|
||||
tstring mname = retrieveModuleName();
|
||||
mname.resize(_countof(moduleName) - 1);
|
||||
std::memcpy(moduleName, mname.c_str(), mname.size());
|
||||
moduleName[mname.size()] = TCHAR(0);
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user