8242302: Refactor jpackage native code
Reviewed-by: herrick, almatvee, erikj
This commit is contained in:
parent
90ada6a314
commit
0c56c3511a
@ -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), \
|
||||
))
|
||||
@ -124,17 +119,16 @@ 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, \
|
||||
OUTPUT_DIR := $(JPACKAGE_OUTPUT_DIR), \
|
||||
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, \
|
||||
))
|
||||
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)
|
||||
|
||||
|
@ -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);
|
||||
}
|
@ -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,32 +23,19 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#ifndef FILEATTRIBUTES_H
|
||||
#define FILEATTRIBUTES_H
|
||||
#ifndef PlatformLogEvent_h
|
||||
#define PlatformLogEvent_h
|
||||
|
||||
#include "Platform.h"
|
||||
#include "PlatformString.h"
|
||||
#include "FileAttribute.h"
|
||||
#include <windows.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
class FileAttributes {
|
||||
private:
|
||||
TString FFileName;
|
||||
bool FFollowLink;
|
||||
std::vector<FileAttribute> FAttributes;
|
||||
struct PlatformLogEvent {
|
||||
SYSTEMTIME ts;
|
||||
long tid;
|
||||
long pid;
|
||||
LPCTSTR moduleName;
|
||||
|
||||
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);
|
||||
PlatformLogEvent();
|
||||
};
|
||||
|
||||
#endif // FILEATTRIBUTES_H
|
||||
|
||||
#endif // PlatformLogEvent_h
|
80
src/jdk.incubator.jpackage/windows/native/common/WinDll.cpp
Normal file
80
src/jdk.incubator.jpackage/windows/native/common/WinDll.cpp
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* 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 "Dll.h"
|
||||
#include "SysInfo.h"
|
||||
#include "FileUtils.h"
|
||||
#include "WinSysInfo.h"
|
||||
#include "WinErrorHandling.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
Dll::Handle loadLibrary(const std::wstring& path) {
|
||||
HMODULE h = LoadLibraryW(path.c_str());
|
||||
if (!h) {
|
||||
JP_THROW(SysError(tstrings::any() << "LoadLibraryW(" <<
|
||||
path << ") failed", LoadLibraryW));
|
||||
}
|
||||
return Dll::Handle(h);
|
||||
}
|
||||
|
||||
} // namesace
|
||||
|
||||
Dll::Dll(const tstrings::any &libPath): thePath(libPath.tstr()),
|
||||
handle(loadLibrary(libPath.wstr())) {
|
||||
}
|
||||
|
||||
Dll::Dll(const tstrings::any &libName, const System &tag):
|
||||
thePath(FileUtils::combinePath(SysInfo::getSystem32Dir(),
|
||||
libName.tstr())),
|
||||
handle(loadLibrary(tstrings::any(thePath).wstr())) {
|
||||
}
|
||||
|
||||
Dll::Dll(const Dll& other): thePath(other.thePath) {
|
||||
HMODULE h = NULL;
|
||||
if (!GetModuleHandleExW(0, thePath.c_str(), &h)) {
|
||||
JP_THROW(SysError(tstrings::any() << "GetModuleHandleExW("
|
||||
<< thePath << ") failed", GetModuleHandleExW));
|
||||
}
|
||||
handle = Handle(h);
|
||||
}
|
||||
|
||||
void* Dll::getFunction(const std::string &name, bool throwIfNotFound) const {
|
||||
void *ptr = GetProcAddress(handle.get(), name.c_str());
|
||||
if (throwIfNotFound && ptr == NULL) {
|
||||
JP_THROW(SysError(tstrings::any() << "GetProcAddress(" << thePath
|
||||
<< ", " << name << ") failed", GetProcAddress));
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void Dll::freeLibrary(HMODULE h) {
|
||||
if (h) {
|
||||
FreeLibrary(h);
|
||||
}
|
||||
}
|
@ -105,8 +105,7 @@ std::wstring getSystemMessageDescription(DWORD messageId, HMODULE moduleHandle)
|
||||
|
||||
SysError::SysError(const tstrings::any& msg, const void* caller, DWORD ec,
|
||||
const char* label):
|
||||
|
||||
std::runtime_error(makeMessage(msg.str(), label, caller, ec)) {
|
||||
std::runtime_error(makeMessage(msg.str(), label, caller, ec)) {
|
||||
}
|
||||
|
||||
std::wstring SysError::getSysErrorMessage(DWORD errCode, HMODULE moduleHandle) {
|
@ -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
|
||||
@ -26,8 +26,11 @@
|
||||
#include <memory>
|
||||
#include <algorithm>
|
||||
#include <shlwapi.h>
|
||||
#include <stdlib.h>
|
||||
#include <direct.h>
|
||||
|
||||
#include "FileUtils.h"
|
||||
#include "WinFileUtils.h"
|
||||
#include "WinErrorHandling.h"
|
||||
#include "Log.h"
|
||||
|
||||
@ -40,7 +43,6 @@ namespace FileUtils {
|
||||
|
||||
namespace {
|
||||
|
||||
|
||||
tstring reservedFilenameChars() {
|
||||
tstring buf;
|
||||
for (char charCode = 0; charCode < 32; ++charCode) {
|
||||
@ -52,10 +54,6 @@ tstring reservedFilenameChars() {
|
||||
|
||||
} // namespace
|
||||
|
||||
bool isDirSeparator(const tstring::value_type c) {
|
||||
return (c == '/' || c == '\\');
|
||||
}
|
||||
|
||||
bool isFileExists(const tstring &filePath) {
|
||||
return GetFileAttributes(filePath.c_str()) != INVALID_FILE_ATTRIBUTES;
|
||||
}
|
||||
@ -78,73 +76,32 @@ bool isDirectoryNotEmpty(const tstring &dirPath) {
|
||||
return FALSE == PathIsDirectoryEmpty(dirPath.c_str());
|
||||
}
|
||||
|
||||
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('.');
|
||||
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] == '.'
|
||||
&& (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.front());
|
||||
tstring childWOSlash = childHasSlash ? child.substr(1) : child;
|
||||
|
||||
return parentWOSlash + _T("\\") + childWOSlash;
|
||||
}
|
||||
|
||||
tstring removeTrailingSlash(const tstring& path) {
|
||||
tstring toAbsolutePath(const tstring& path) {
|
||||
if (path.empty()) {
|
||||
return path;
|
||||
TCHAR* buf = _tgetcwd(0, 1);
|
||||
if (buf) {
|
||||
const tstring result(buf);
|
||||
free(buf);
|
||||
if (result.empty()) {
|
||||
JP_THROW(tstrings::any() << "_tgetcwd() returned empty string");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
tstring::const_reverse_iterator it = path.rbegin();
|
||||
tstring::const_reverse_iterator end = path.rend();
|
||||
|
||||
while (it != end && isDirSeparator(*it)) {
|
||||
++it;
|
||||
JP_THROW(tstrings::any() << "_tgetcwd() failed");
|
||||
}
|
||||
return path.substr(0, end - it);
|
||||
|
||||
TCHAR* buf = _tfullpath(0, path.c_str(), size_t(1));
|
||||
if (buf) {
|
||||
const tstring result(buf);
|
||||
free(buf);
|
||||
return result;
|
||||
}
|
||||
|
||||
JP_THROW(tstrings::any() << "_tfullpath(" << path << ") failed");
|
||||
}
|
||||
|
||||
tstring normalizePath(tstring v) {
|
||||
std::replace(v.begin(), v.end(), '/', '\\');
|
||||
return tstrings::toLower(v);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
@ -565,11 +522,6 @@ void iterateDirectory(const tstring &dirPath, DirectoryCallback& callback)
|
||||
}
|
||||
|
||||
|
||||
tstring replaceSuffix(const tstring& path, const tstring& newSuffix) {
|
||||
return (path.substr(0, path.size() - suffix(path).size()) + newSuffix);
|
||||
}
|
||||
|
||||
|
||||
DirectoryIterator& DirectoryIterator::findItems(tstring_array& v) {
|
||||
if (!isDirectory(root)) {
|
||||
return *this;
|
@ -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,8 +23,8 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#ifndef FILEUTILS_H
|
||||
#define FILEUTILS_H
|
||||
#ifndef WINFILEUTILS_H
|
||||
#define WINFILEUTILS_H
|
||||
|
||||
|
||||
#include <fstream>
|
||||
@ -33,48 +33,6 @@
|
||||
|
||||
namespace FileUtils {
|
||||
|
||||
// Returns 'true' if the given character is a path separator.
|
||||
bool isDirSeparator(const tstring::value_type c);
|
||||
|
||||
// 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);
|
||||
|
||||
// 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);
|
||||
|
||||
// Creates a file with unique name in the specified base directory,
|
||||
// throws an exception if operation fails
|
||||
// path is constructed as <prefix><random number><suffix>.
|
||||
@ -166,14 +124,6 @@ namespace FileUtils {
|
||||
// the given directory.
|
||||
void iterateDirectory(const tstring &dirPath, DirectoryCallback& callback);
|
||||
|
||||
/**
|
||||
* 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());
|
||||
|
||||
class DirectoryIterator: DirectoryCallback {
|
||||
public:
|
||||
DirectoryIterator(const tstring& root=tstring()): root(root) {
|
||||
@ -225,34 +175,6 @@ namespace FileUtils {
|
||||
return DirectoryIterator(basedir).findItems();
|
||||
}
|
||||
|
||||
// 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;
|
||||
};
|
||||
|
||||
struct Directory {
|
||||
Directory() {
|
||||
}
|
||||
@ -395,4 +317,4 @@ namespace FileUtils {
|
||||
};
|
||||
} // FileUtils
|
||||
|
||||
#endif // FILEUTILS_H
|
||||
#endif // WINFILEUTILS_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
|
||||
@ -97,7 +97,7 @@ tstring getModulePath(HMODULE h)
|
||||
} // namespace
|
||||
|
||||
tstring getProcessModulePath() {
|
||||
return getModulePath(NULL);
|
||||
return FileUtils::toAbsolutePath(getModulePath(NULL));
|
||||
}
|
||||
|
||||
HMODULE getCurrentModuleHandle()
|
@ -1,98 +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.
|
||||
*/
|
||||
|
||||
#include <Windows.h>
|
||||
#include <Shellapi.h>
|
||||
#include <locale.h>
|
||||
#include <tchar.h>
|
||||
#include <string>
|
||||
|
||||
#define JPACKAGE_LIBRARY TEXT("applauncher.dll")
|
||||
|
||||
typedef bool (*start_launcher)(int argc, TCHAR* argv[]);
|
||||
typedef void (*stop_launcher)();
|
||||
|
||||
std::wstring GetTitle() {
|
||||
std::wstring result;
|
||||
wchar_t buffer[MAX_PATH];
|
||||
GetModuleFileName(NULL, buffer, MAX_PATH - 1);
|
||||
buffer[MAX_PATH - 1] = '\0';
|
||||
result = buffer;
|
||||
size_t slash = result.find_last_of('\\');
|
||||
|
||||
if (slash != std::wstring::npos)
|
||||
result = result.substr(slash + 1, result.size() - slash - 1);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef LAUNCHERC
|
||||
int main(int argc0, char *argv0[]) {
|
||||
#else // LAUNCHERC
|
||||
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
||||
LPTSTR lpCmdLine, int nCmdShow) {
|
||||
#endif // LAUNCHERC
|
||||
int result = 1;
|
||||
TCHAR **argv;
|
||||
int argc;
|
||||
|
||||
// [RT-31061] otherwise UI can be left in back of other windows.
|
||||
::AllowSetForegroundWindow(ASFW_ANY);
|
||||
|
||||
::setlocale(LC_ALL, "en_US.utf8");
|
||||
argv = CommandLineToArgvW(GetCommandLine(), &argc);
|
||||
|
||||
HMODULE library = ::LoadLibrary(JPACKAGE_LIBRARY);
|
||||
|
||||
if (library == NULL) {
|
||||
std::wstring title = GetTitle();
|
||||
std::wstring description = std::wstring(JPACKAGE_LIBRARY)
|
||||
+ std::wstring(TEXT(" not found."));
|
||||
MessageBox(NULL, description.data(),
|
||||
title.data(), MB_ICONERROR | MB_OK);
|
||||
}
|
||||
else {
|
||||
start_launcher start =
|
||||
(start_launcher)GetProcAddress(library, "start_launcher");
|
||||
stop_launcher stop =
|
||||
(stop_launcher)GetProcAddress(library, "stop_launcher");
|
||||
|
||||
if (start != NULL && stop != NULL) {
|
||||
if (start(argc, argv) == true) {
|
||||
result = 0;
|
||||
stop();
|
||||
}
|
||||
}
|
||||
|
||||
::FreeLibrary(library);
|
||||
}
|
||||
|
||||
if (argv != NULL) {
|
||||
LocalFree(argv);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -1,48 +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 FILEATTRIBUTE_H
|
||||
#define FILEATTRIBUTE_H
|
||||
|
||||
enum FileAttribute {
|
||||
faArchive = FILE_ATTRIBUTE_ARCHIVE,
|
||||
faCompressed = FILE_ATTRIBUTE_COMPRESSED,
|
||||
faDevice = FILE_ATTRIBUTE_DEVICE,
|
||||
faDirectory = FILE_ATTRIBUTE_DIRECTORY,
|
||||
faEncrypted = FILE_ATTRIBUTE_ENCRYPTED,
|
||||
faHidden = FILE_ATTRIBUTE_HIDDEN,
|
||||
faNormal = FILE_ATTRIBUTE_NORMAL,
|
||||
faNotContentIndexed = FILE_ATTRIBUTE_NOT_CONTENT_INDEXED,
|
||||
faOffline = FILE_ATTRIBUTE_OFFLINE,
|
||||
faSystem = FILE_ATTRIBUTE_SYSTEM,
|
||||
faSymbolicLink = FILE_ATTRIBUTE_REPARSE_POINT,
|
||||
faSparceFile = FILE_ATTRIBUTE_SPARSE_FILE,
|
||||
faReadOnly = FILE_ATTRIBUTE_READONLY,
|
||||
faTemporary = FILE_ATTRIBUTE_TEMPORARY,
|
||||
faVirtual = FILE_ATTRIBUTE_VIRTUAL
|
||||
};
|
||||
|
||||
#endif // FILEATTRIBUTE_H
|
||||
|
@ -1,468 +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 "FilePath.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <list>
|
||||
#include <ShellAPI.h>
|
||||
|
||||
bool FilePath::FileExists(const TString FileName) {
|
||||
bool result = false;
|
||||
WIN32_FIND_DATA FindFileData;
|
||||
TString fileName = FixPathForPlatform(FileName);
|
||||
HANDLE handle = FindFirstFile(fileName.data(), &FindFileData);
|
||||
|
||||
if (handle != INVALID_HANDLE_VALUE) {
|
||||
if (FILE_ATTRIBUTE_DIRECTORY & FindFileData.dwFileAttributes) {
|
||||
result = true;
|
||||
}
|
||||
else {
|
||||
result = true;
|
||||
}
|
||||
|
||||
FindClose(handle);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool FilePath::DirectoryExists(const TString DirectoryName) {
|
||||
bool result = false;
|
||||
WIN32_FIND_DATA FindFileData;
|
||||
TString directoryName = FixPathForPlatform(DirectoryName);
|
||||
HANDLE handle = FindFirstFile(directoryName.data(), &FindFileData);
|
||||
|
||||
if (handle != INVALID_HANDLE_VALUE) {
|
||||
if (FILE_ATTRIBUTE_DIRECTORY & FindFileData.dwFileAttributes) {
|
||||
result = true;
|
||||
}
|
||||
|
||||
FindClose(handle);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string GetLastErrorAsString() {
|
||||
// Get the error message, if any.
|
||||
DWORD errorMessageID = ::GetLastError();
|
||||
|
||||
if (errorMessageID == 0) {
|
||||
return "No error message has been recorded";
|
||||
}
|
||||
|
||||
LPSTR messageBuffer = NULL;
|
||||
size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER
|
||||
| FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL,
|
||||
SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL);
|
||||
|
||||
std::string message(messageBuffer, size);
|
||||
|
||||
// Free the buffer.
|
||||
LocalFree(messageBuffer);
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
bool FilePath::DeleteFile(const TString FileName) {
|
||||
bool result = false;
|
||||
|
||||
if (FileExists(FileName) == true) {
|
||||
TString lFileName = FixPathForPlatform(FileName);
|
||||
FileAttributes attributes(lFileName);
|
||||
|
||||
if (attributes.Contains(faReadOnly) == true) {
|
||||
attributes.Remove(faReadOnly);
|
||||
}
|
||||
|
||||
result = ::DeleteFile(lFileName.data()) == TRUE;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool FilePath::DeleteDirectory(const TString DirectoryName) {
|
||||
bool result = false;
|
||||
|
||||
if (DirectoryExists(DirectoryName) == true) {
|
||||
SHFILEOPSTRUCTW fos = {0};
|
||||
TString directoryName = FixPathForPlatform(DirectoryName);
|
||||
DynamicBuffer<TCHAR> lDirectoryName(directoryName.size() + 2);
|
||||
if (lDirectoryName.GetData() == NULL) {
|
||||
return false;
|
||||
}
|
||||
memcpy(lDirectoryName.GetData(), directoryName.data(),
|
||||
(directoryName.size() + 2) * sizeof(TCHAR));
|
||||
lDirectoryName[directoryName.size() + 1] = NULL;
|
||||
// Double null terminate for SHFileOperation.
|
||||
|
||||
// Delete the folder and everything inside.
|
||||
fos.wFunc = FO_DELETE;
|
||||
fos.pFrom = lDirectoryName.GetData();
|
||||
fos.fFlags = FOF_NO_UI;
|
||||
result = SHFileOperation(&fos) == 0;
|
||||
}
|
||||
|
||||
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) {
|
||||
TString result;
|
||||
size_t slash = Path.find_last_of(TRAILING_PATHSEPARATOR);
|
||||
if (slash != TString::npos)
|
||||
result = Path.substr(0, slash);
|
||||
return result;
|
||||
}
|
||||
|
||||
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) {
|
||||
TString result;
|
||||
|
||||
size_t slash = Path.find_last_of(TRAILING_PATHSEPARATOR);
|
||||
if (slash != TString::npos)
|
||||
result = Path.substr(slash + 1, Path.size() - slash - 1);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
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);
|
||||
// The maximum path that does not require long path prefix. On Windows the
|
||||
// maximum path is 260 minus 1 (NUL) but for directories it is 260 minus
|
||||
// 12 minus 1 (to allow for the creation of a 8.3 file in the directory).
|
||||
const int maxPath = 247;
|
||||
if (result.length() > maxPath &&
|
||||
result.find(_T("\\\\?\\")) == TString::npos &&
|
||||
result.find(_T("\\\\?\\UNC")) == TString::npos) {
|
||||
const TString prefix(_T("\\\\"));
|
||||
if (!result.compare(0, prefix.size(), prefix)) {
|
||||
// UNC path, converting to UNC path in long notation
|
||||
result = _T("\\\\?\\UNC") + result.substr(1, result.length());
|
||||
} else {
|
||||
// converting to non-UNC path in long notation
|
||||
result = _T("\\\\?\\") + result;
|
||||
}
|
||||
}
|
||||
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;
|
||||
|
||||
if (_wmkdir(lpath.data()) == 0) {
|
||||
result = true;
|
||||
} else {
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void FilePath::ChangePermissions(TString FileName, bool ownerOnly) {
|
||||
}
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
FileAttributes::FileAttributes(const TString FileName, bool FollowLink) {
|
||||
FFileName = FileName;
|
||||
FFollowLink = FollowLink;
|
||||
ReadAttributes();
|
||||
}
|
||||
|
||||
bool FileAttributes::WriteAttributes() {
|
||||
bool result = false;
|
||||
|
||||
DWORD attributes = 0;
|
||||
|
||||
for (std::vector<FileAttribute>::const_iterator iterator =
|
||||
FAttributes.begin();
|
||||
iterator != FAttributes.end(); iterator++) {
|
||||
switch (*iterator) {
|
||||
case faArchive: {
|
||||
attributes = attributes & FILE_ATTRIBUTE_ARCHIVE;
|
||||
break;
|
||||
}
|
||||
case faCompressed: {
|
||||
attributes = attributes & FILE_ATTRIBUTE_COMPRESSED;
|
||||
break;
|
||||
}
|
||||
case faDevice: {
|
||||
attributes = attributes & FILE_ATTRIBUTE_DEVICE;
|
||||
break;
|
||||
}
|
||||
case faDirectory: {
|
||||
attributes = attributes & FILE_ATTRIBUTE_DIRECTORY;
|
||||
break;
|
||||
}
|
||||
case faEncrypted: {
|
||||
attributes = attributes & FILE_ATTRIBUTE_ENCRYPTED;
|
||||
break;
|
||||
}
|
||||
case faHidden: {
|
||||
attributes = attributes & FILE_ATTRIBUTE_HIDDEN;
|
||||
break;
|
||||
}
|
||||
case faNormal: {
|
||||
attributes = attributes & FILE_ATTRIBUTE_NORMAL;
|
||||
break;
|
||||
}
|
||||
case faNotContentIndexed: {
|
||||
attributes = attributes & FILE_ATTRIBUTE_NOT_CONTENT_INDEXED;
|
||||
break;
|
||||
}
|
||||
case faOffline: {
|
||||
attributes = attributes & FILE_ATTRIBUTE_OFFLINE;
|
||||
break;
|
||||
}
|
||||
case faSystem: {
|
||||
attributes = attributes & FILE_ATTRIBUTE_SYSTEM;
|
||||
break;
|
||||
}
|
||||
case faSymbolicLink: {
|
||||
attributes = attributes & FILE_ATTRIBUTE_REPARSE_POINT;
|
||||
break;
|
||||
}
|
||||
case faSparceFile: {
|
||||
attributes = attributes & FILE_ATTRIBUTE_SPARSE_FILE;
|
||||
break;
|
||||
}
|
||||
case faReadOnly: {
|
||||
attributes = attributes & FILE_ATTRIBUTE_READONLY;
|
||||
break;
|
||||
}
|
||||
case faTemporary: {
|
||||
attributes = attributes & FILE_ATTRIBUTE_TEMPORARY;
|
||||
break;
|
||||
}
|
||||
case faVirtual: {
|
||||
attributes = attributes & FILE_ATTRIBUTE_VIRTUAL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (::SetFileAttributes(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;
|
||||
|
||||
DWORD attributes = ::GetFileAttributes(FFileName.data());
|
||||
|
||||
if (attributes != INVALID_FILE_ATTRIBUTES) {
|
||||
result = true;
|
||||
|
||||
if (attributes | FILE_ATTRIBUTE_ARCHIVE) {
|
||||
FAttributes.push_back(faArchive);
|
||||
}
|
||||
if (attributes | FILE_ATTRIBUTE_COMPRESSED) {
|
||||
FAttributes.push_back(faCompressed);
|
||||
}
|
||||
if (attributes | FILE_ATTRIBUTE_DEVICE) {
|
||||
FAttributes.push_back(faDevice);
|
||||
}
|
||||
if (attributes | FILE_ATTRIBUTE_DIRECTORY) {
|
||||
FAttributes.push_back(faDirectory);
|
||||
}
|
||||
if (attributes | FILE_ATTRIBUTE_ENCRYPTED) {
|
||||
FAttributes.push_back(faEncrypted);
|
||||
}
|
||||
if (attributes | FILE_ATTRIBUTE_HIDDEN) {
|
||||
FAttributes.push_back(faHidden);
|
||||
}
|
||||
if (attributes | FILE_ATTRIBUTE_NORMAL) {
|
||||
FAttributes.push_back(faNormal);
|
||||
}
|
||||
if (attributes | FILE_ATTRIBUTE_NOT_CONTENT_INDEXED) {
|
||||
FAttributes.push_back(faNotContentIndexed);
|
||||
}
|
||||
if (attributes | FILE_ATTRIBUTE_SYSTEM) {
|
||||
FAttributes.push_back(faSystem);
|
||||
}
|
||||
if (attributes | FILE_ATTRIBUTE_OFFLINE) {
|
||||
FAttributes.push_back(faOffline);
|
||||
}
|
||||
if (attributes | FILE_ATTRIBUTE_REPARSE_POINT) {
|
||||
FAttributes.push_back(faSymbolicLink);
|
||||
}
|
||||
if (attributes | FILE_ATTRIBUTE_SPARSE_FILE) {
|
||||
FAttributes.push_back(faSparceFile);
|
||||
}
|
||||
if (attributes | FILE_ATTRIBUTE_READONLY ) {
|
||||
FAttributes.push_back(faReadOnly);
|
||||
}
|
||||
if (attributes | FILE_ATTRIBUTE_TEMPORARY) {
|
||||
FAttributes.push_back(faTemporary);
|
||||
}
|
||||
if (attributes | FILE_ATTRIBUTE_VIRTUAL) {
|
||||
FAttributes.push_back(faVirtual);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool FileAttributes::Valid(const FileAttribute Value) {
|
||||
bool result = false;
|
||||
|
||||
switch (Value) {
|
||||
case faHidden:
|
||||
case faReadOnly: {
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void FileAttributes::Append(FileAttribute Value) {
|
||||
if (Valid(Value) == true) {
|
||||
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) {
|
||||
std::vector<FileAttribute>::iterator iterator =
|
||||
std::find(FAttributes.begin(), FAttributes.end(), Value);
|
||||
|
||||
if (iterator != FAttributes.end()) {
|
||||
FAttributes.erase(iterator);
|
||||
WriteAttributes();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,765 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 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 "Platform.h"
|
||||
|
||||
#include "JavaVirtualMachine.h"
|
||||
#include "WindowsPlatform.h"
|
||||
#include "Package.h"
|
||||
#include "Helpers.h"
|
||||
#include "PlatformString.h"
|
||||
#include "Macros.h"
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <regex>
|
||||
#include <fstream>
|
||||
#include <locale>
|
||||
#include <codecvt>
|
||||
|
||||
using namespace std;
|
||||
|
||||
#define WINDOWS_JPACKAGE_TMP_DIR \
|
||||
L"\\AppData\\Local\\Java\\JPackage\\tmp"
|
||||
|
||||
class Registry {
|
||||
private:
|
||||
HKEY FKey;
|
||||
HKEY FOpenKey;
|
||||
bool FOpen;
|
||||
|
||||
public:
|
||||
|
||||
Registry(HKEY Key) {
|
||||
FOpen = false;
|
||||
FKey = Key;
|
||||
}
|
||||
|
||||
~Registry() {
|
||||
Close();
|
||||
}
|
||||
|
||||
void Close() {
|
||||
if (FOpen == true) {
|
||||
RegCloseKey(FOpenKey);
|
||||
}
|
||||
}
|
||||
|
||||
bool Open(TString SubKey) {
|
||||
bool result = false;
|
||||
Close();
|
||||
|
||||
if (RegOpenKeyEx(FKey, SubKey.data(), 0, KEY_READ, &FOpenKey) ==
|
||||
ERROR_SUCCESS) {
|
||||
result = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::list<TString> GetKeys() {
|
||||
std::list<TString> result;
|
||||
DWORD count;
|
||||
|
||||
if (RegQueryInfoKey(FOpenKey, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
&count, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) {
|
||||
|
||||
DWORD length = 255;
|
||||
DynamicBuffer<TCHAR> buffer(length);
|
||||
if (buffer.GetData() == NULL) {
|
||||
return result;
|
||||
}
|
||||
|
||||
for (unsigned int index = 0; index < count; index++) {
|
||||
buffer.Zero();
|
||||
DWORD status = RegEnumValue(FOpenKey, index, buffer.GetData(),
|
||||
&length, NULL, NULL, NULL, NULL);
|
||||
|
||||
while (status == ERROR_MORE_DATA) {
|
||||
length = length * 2;
|
||||
if (!buffer.Resize(length)) {
|
||||
return result;
|
||||
}
|
||||
status = RegEnumValue(FOpenKey, index, buffer.GetData(),
|
||||
&length, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
if (status == ERROR_SUCCESS) {
|
||||
TString value = buffer.GetData();
|
||||
result.push_back(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
TString ReadString(TString Name) {
|
||||
TString result;
|
||||
DWORD length;
|
||||
DWORD dwRet;
|
||||
DynamicBuffer<wchar_t> buffer(0);
|
||||
length = 0;
|
||||
|
||||
dwRet = RegQueryValueEx(FOpenKey, Name.data(), NULL, NULL, NULL,
|
||||
&length);
|
||||
if (dwRet == ERROR_MORE_DATA || dwRet == 0) {
|
||||
if (!buffer.Resize(length + 1)) {
|
||||
return result;
|
||||
}
|
||||
dwRet = RegQueryValueEx(FOpenKey, Name.data(), NULL, NULL,
|
||||
(LPBYTE) buffer.GetData(), &length);
|
||||
result = buffer.GetData();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
WindowsPlatform::WindowsPlatform(void) : Platform() {
|
||||
FMainThread = ::GetCurrentThreadId();
|
||||
}
|
||||
|
||||
WindowsPlatform::~WindowsPlatform(void) {
|
||||
}
|
||||
|
||||
TString WindowsPlatform::GetPackageAppDirectory() {
|
||||
return FilePath::IncludeTrailingSeparator(
|
||||
GetPackageRootDirectory()) + _T("app");
|
||||
}
|
||||
|
||||
TString WindowsPlatform::GetPackageLauncherDirectory() {
|
||||
return GetPackageRootDirectory();
|
||||
}
|
||||
|
||||
TString WindowsPlatform::GetPackageRuntimeBinDirectory() {
|
||||
return FilePath::IncludeTrailingSeparator(GetPackageRootDirectory()) + _T("runtime\\bin");
|
||||
}
|
||||
|
||||
TCHAR* WindowsPlatform::ConvertStringToFileSystemString(TCHAR* Source,
|
||||
bool &release) {
|
||||
// Not Implemented.
|
||||
return NULL;
|
||||
}
|
||||
|
||||
TCHAR* WindowsPlatform::ConvertFileSystemStringToString(TCHAR* Source,
|
||||
bool &release) {
|
||||
// Not Implemented.
|
||||
return NULL;
|
||||
}
|
||||
|
||||
TString WindowsPlatform::GetPackageRootDirectory() {
|
||||
TString result;
|
||||
TString filename = GetModuleFileName();
|
||||
return FilePath::ExtractFilePath(filename);
|
||||
}
|
||||
|
||||
TString WindowsPlatform::GetAppDataDirectory() {
|
||||
TString result;
|
||||
TCHAR path[MAX_PATH];
|
||||
|
||||
if (SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, path) == S_OK) {
|
||||
result = path;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
TString WindowsPlatform::GetAppName() {
|
||||
TString result = GetModuleFileName();
|
||||
result = FilePath::ExtractFileName(result);
|
||||
result = FilePath::ChangeFileExt(result, _T(""));
|
||||
return result;
|
||||
}
|
||||
|
||||
void WindowsPlatform::ShowMessage(TString title, TString description) {
|
||||
MessageBox(NULL, description.data(),
|
||||
!title.empty() ? title.data() : description.data(),
|
||||
MB_ICONERROR | MB_OK);
|
||||
}
|
||||
|
||||
void WindowsPlatform::ShowMessage(TString description) {
|
||||
TString appname = GetModuleFileName();
|
||||
appname = FilePath::ExtractFileName(appname);
|
||||
MessageBox(NULL, description.data(), appname.data(), MB_ICONERROR | MB_OK);
|
||||
}
|
||||
|
||||
MessageResponse WindowsPlatform::ShowResponseMessage(TString title,
|
||||
TString description) {
|
||||
MessageResponse result = mrCancel;
|
||||
|
||||
if (::MessageBox(NULL, description.data(), title.data(), MB_OKCANCEL) ==
|
||||
IDOK) {
|
||||
result = mrOK;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
TString WindowsPlatform::GetBundledJavaLibraryFileName(TString RuntimePath) {
|
||||
TString result = FilePath::IncludeTrailingSeparator(RuntimePath) +
|
||||
_T("jre\\bin\\jli.dll");
|
||||
|
||||
if (FilePath::FileExists(result) == false) {
|
||||
result = FilePath::IncludeTrailingSeparator(RuntimePath) +
|
||||
_T("bin\\jli.dll");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
ISectionalPropertyContainer* WindowsPlatform::GetConfigFile(TString FileName) {
|
||||
IniFile *result = new IniFile();
|
||||
if (result == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
result->LoadFromFile(FileName);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
TString WindowsPlatform::GetModuleFileName() {
|
||||
TString result;
|
||||
DynamicBuffer<wchar_t> buffer(MAX_PATH);
|
||||
if (buffer.GetData() == NULL) {
|
||||
return result;
|
||||
}
|
||||
|
||||
::GetModuleFileName(NULL, buffer.GetData(),
|
||||
static_cast<DWORD> (buffer.GetSize()));
|
||||
|
||||
while (ERROR_INSUFFICIENT_BUFFER == GetLastError()) {
|
||||
if (!buffer.Resize(buffer.GetSize() * 2)) {
|
||||
return result;
|
||||
}
|
||||
::GetModuleFileName(NULL, buffer.GetData(),
|
||||
static_cast<DWORD> (buffer.GetSize()));
|
||||
}
|
||||
|
||||
result = buffer.GetData();
|
||||
return result;
|
||||
}
|
||||
|
||||
Module WindowsPlatform::LoadLibrary(TString FileName) {
|
||||
return ::LoadLibrary(FileName.data());
|
||||
}
|
||||
|
||||
void WindowsPlatform::FreeLibrary(Module AModule) {
|
||||
::FreeLibrary((HMODULE) AModule);
|
||||
}
|
||||
|
||||
Procedure WindowsPlatform::GetProcAddress(Module AModule,
|
||||
std::string MethodName) {
|
||||
return ::GetProcAddress((HMODULE) AModule, MethodName.c_str());
|
||||
}
|
||||
|
||||
bool WindowsPlatform::IsMainThread() {
|
||||
bool result = (FMainThread == ::GetCurrentThreadId());
|
||||
return result;
|
||||
}
|
||||
|
||||
TString WindowsPlatform::GetTempDirectory() {
|
||||
TString result;
|
||||
PWSTR userDir = 0;
|
||||
|
||||
if (SUCCEEDED(SHGetKnownFolderPath(
|
||||
FOLDERID_Profile,
|
||||
0,
|
||||
NULL,
|
||||
&userDir))) {
|
||||
result = userDir;
|
||||
result += WINDOWS_JPACKAGE_TMP_DIR;
|
||||
CoTaskMemFree(userDir);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static BOOL CALLBACK enumWindows(HWND winHandle, LPARAM lParam) {
|
||||
DWORD pid = (DWORD) lParam, wPid = 0;
|
||||
GetWindowThreadProcessId(winHandle, &wPid);
|
||||
if (pid == wPid) {
|
||||
SetForegroundWindow(winHandle);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
TPlatformNumber WindowsPlatform::GetMemorySize() {
|
||||
SYSTEM_INFO si;
|
||||
GetSystemInfo(&si);
|
||||
size_t result = (size_t) si.lpMaximumApplicationAddress;
|
||||
result = result / 1048576; // Convert from bytes to megabytes.
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<TString> FilterList(std::vector<TString> &Items,
|
||||
std::wregex Pattern) {
|
||||
std::vector<TString> result;
|
||||
|
||||
for (std::vector<TString>::iterator it = Items.begin();
|
||||
it != Items.end(); ++it) {
|
||||
TString item = *it;
|
||||
std::wsmatch match;
|
||||
|
||||
if (std::regex_search(item, match, Pattern)) {
|
||||
result.push_back(item);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Process* WindowsPlatform::CreateProcess() {
|
||||
return new WindowsProcess();
|
||||
}
|
||||
|
||||
void WindowsPlatform::InitStreamLocale(wios *stream) {
|
||||
const std::locale empty_locale = std::locale::empty();
|
||||
const std::locale utf8_locale =
|
||||
std::locale(empty_locale, new std::codecvt_utf8<wchar_t>());
|
||||
stream->imbue(utf8_locale);
|
||||
}
|
||||
|
||||
void WindowsPlatform::addPlatformDependencies(JavaLibrary *pJavaLibrary) {
|
||||
if (pJavaLibrary == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (FilePath::FileExists(_T("msvcr100.dll")) == true) {
|
||||
pJavaLibrary->AddDependency(_T("msvcr100.dll"));
|
||||
}
|
||||
|
||||
TString runtimeBin = GetPackageRuntimeBinDirectory();
|
||||
SetDllDirectory(runtimeBin.c_str());
|
||||
}
|
||||
|
||||
void Platform::CopyString(char *Destination,
|
||||
size_t NumberOfElements, const char *Source) {
|
||||
strcpy_s(Destination, NumberOfElements, Source);
|
||||
|
||||
if (NumberOfElements > 0) {
|
||||
Destination[NumberOfElements - 1] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
void Platform::CopyString(wchar_t *Destination,
|
||||
size_t NumberOfElements, const wchar_t *Source) {
|
||||
wcscpy_s(Destination, NumberOfElements, Source);
|
||||
|
||||
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 = WideCharToMultiByte(CP_UTF8, 0, value, -1, NULL, 0, NULL, NULL);
|
||||
|
||||
if (count > 0) {
|
||||
result.data = new char[count + 1];
|
||||
result.length = WideCharToMultiByte(CP_UTF8, 0, value, -1,
|
||||
result.data, (int)count, NULL, NULL);
|
||||
}
|
||||
|
||||
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 = MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS,
|
||||
value, -1, NULL, 0);
|
||||
|
||||
if (count > 0) {
|
||||
result.data = new wchar_t[count];
|
||||
result.length = MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS,
|
||||
value, -1, result.data, (int)count);
|
||||
if (result.length == 0) {
|
||||
delete[] result.data;
|
||||
result.data = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
FileHandle::FileHandle(std::wstring FileName) {
|
||||
FHandle = ::CreateFile(FileName.data(), GENERIC_READ, FILE_SHARE_READ,
|
||||
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
|
||||
}
|
||||
|
||||
FileHandle::~FileHandle() {
|
||||
if (IsValid() == true) {
|
||||
::CloseHandle(FHandle);
|
||||
}
|
||||
}
|
||||
|
||||
bool FileHandle::IsValid() {
|
||||
return FHandle != INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
HANDLE FileHandle::GetHandle() {
|
||||
return FHandle;
|
||||
}
|
||||
|
||||
FileMappingHandle::FileMappingHandle(HANDLE FileHandle) {
|
||||
FHandle = ::CreateFileMapping(FileHandle, NULL, PAGE_READONLY, 0, 0, NULL);
|
||||
}
|
||||
|
||||
bool FileMappingHandle::IsValid() {
|
||||
return FHandle != NULL;
|
||||
}
|
||||
|
||||
FileMappingHandle::~FileMappingHandle() {
|
||||
if (IsValid() == true) {
|
||||
::CloseHandle(FHandle);
|
||||
}
|
||||
}
|
||||
|
||||
HANDLE FileMappingHandle::GetHandle() {
|
||||
return FHandle;
|
||||
}
|
||||
|
||||
FileData::FileData(HANDLE Handle) {
|
||||
FBaseAddress = ::MapViewOfFile(Handle, FILE_MAP_READ, 0, 0, 0);
|
||||
}
|
||||
|
||||
FileData::~FileData() {
|
||||
if (IsValid() == true) {
|
||||
::UnmapViewOfFile(FBaseAddress);
|
||||
}
|
||||
}
|
||||
|
||||
bool FileData::IsValid() {
|
||||
return FBaseAddress != NULL;
|
||||
}
|
||||
|
||||
LPVOID FileData::GetBaseAddress() {
|
||||
return FBaseAddress;
|
||||
}
|
||||
|
||||
WindowsLibrary::WindowsLibrary(std::wstring FileName) {
|
||||
FFileName = FileName;
|
||||
}
|
||||
|
||||
std::vector<TString> WindowsLibrary::GetImports() {
|
||||
std::vector<TString> result;
|
||||
FileHandle library(FFileName);
|
||||
|
||||
if (library.IsValid() == true) {
|
||||
FileMappingHandle mapping(library.GetHandle());
|
||||
|
||||
if (mapping.IsValid() == true) {
|
||||
FileData fileData(mapping.GetHandle());
|
||||
|
||||
if (fileData.IsValid() == true) {
|
||||
PIMAGE_DOS_HEADER dosHeader =
|
||||
(PIMAGE_DOS_HEADER) fileData.GetBaseAddress();
|
||||
PIMAGE_FILE_HEADER pImgFileHdr =
|
||||
(PIMAGE_FILE_HEADER) fileData.GetBaseAddress();
|
||||
if (dosHeader->e_magic == IMAGE_DOS_SIGNATURE) {
|
||||
result = DumpPEFile(dosHeader);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Given an RVA, look up the section header that encloses it and return a
|
||||
// pointer to its IMAGE_SECTION_HEADER
|
||||
|
||||
PIMAGE_SECTION_HEADER WindowsLibrary::GetEnclosingSectionHeader(DWORD rva,
|
||||
PIMAGE_NT_HEADERS pNTHeader) {
|
||||
PIMAGE_SECTION_HEADER result = 0;
|
||||
PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(pNTHeader);
|
||||
|
||||
for (unsigned index = 0; index < pNTHeader->FileHeader.NumberOfSections;
|
||||
index++, section++) {
|
||||
// Is the RVA is within this section?
|
||||
if ((rva >= section->VirtualAddress) &&
|
||||
(rva < (section->VirtualAddress + section->Misc.VirtualSize))) {
|
||||
result = section;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
LPVOID WindowsLibrary::GetPtrFromRVA(DWORD rva, PIMAGE_NT_HEADERS pNTHeader,
|
||||
DWORD imageBase) {
|
||||
LPVOID result = 0;
|
||||
PIMAGE_SECTION_HEADER pSectionHdr = GetEnclosingSectionHeader(rva,
|
||||
pNTHeader);
|
||||
|
||||
if (pSectionHdr != NULL) {
|
||||
INT delta = (INT) (
|
||||
pSectionHdr->VirtualAddress - pSectionHdr->PointerToRawData);
|
||||
DWORD_PTR dwp = (DWORD_PTR) (imageBase + rva - delta);
|
||||
result = reinterpret_cast<LPVOID> (dwp); // VS2017 - FIXME
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<TString> WindowsLibrary::GetImportsSection(DWORD base,
|
||||
PIMAGE_NT_HEADERS pNTHeader) {
|
||||
std::vector<TString> result;
|
||||
|
||||
// Look up where the imports section is located. Normally in
|
||||
// the .idata section,
|
||||
// but not necessarily so. Therefore, grab the RVA from the data dir.
|
||||
DWORD importsStartRVA = pNTHeader->OptionalHeader.DataDirectory[
|
||||
IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
|
||||
|
||||
if (importsStartRVA != NULL) {
|
||||
// Get the IMAGE_SECTION_HEADER that contains the imports. This is
|
||||
// usually the .idata section, but doesn't have to be.
|
||||
PIMAGE_SECTION_HEADER pSection =
|
||||
GetEnclosingSectionHeader(importsStartRVA, pNTHeader);
|
||||
|
||||
if (pSection != NULL) {
|
||||
PIMAGE_IMPORT_DESCRIPTOR importDesc =
|
||||
(PIMAGE_IMPORT_DESCRIPTOR) GetPtrFromRVA(
|
||||
importsStartRVA, pNTHeader, base);
|
||||
|
||||
if (importDesc != NULL) {
|
||||
while (true) {
|
||||
// See if we've reached an empty IMAGE_IMPORT_DESCRIPTOR
|
||||
if ((importDesc->TimeDateStamp == 0) &&
|
||||
(importDesc->Name == 0)) {
|
||||
break;
|
||||
}
|
||||
|
||||
std::string filename = (char*) GetPtrFromRVA(
|
||||
importDesc->Name, pNTHeader, base);
|
||||
result.push_back(PlatformString(filename));
|
||||
importDesc++; // advance to next IMAGE_IMPORT_DESCRIPTOR
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<TString> WindowsLibrary::DumpPEFile(PIMAGE_DOS_HEADER dosHeader) {
|
||||
std::vector<TString> result;
|
||||
// all of this is VS2017 - FIXME
|
||||
DWORD_PTR dwDosHeaders = reinterpret_cast<DWORD_PTR> (dosHeader);
|
||||
DWORD_PTR dwPIHeaders = dwDosHeaders + (DWORD) (dosHeader->e_lfanew);
|
||||
|
||||
PIMAGE_NT_HEADERS pNTHeader =
|
||||
reinterpret_cast<PIMAGE_NT_HEADERS> (dwPIHeaders);
|
||||
|
||||
// Verify that the e_lfanew field gave us a reasonable
|
||||
// pointer and the PE signature.
|
||||
// TODO: To really fix JDK-8131321 this condition needs to be changed.
|
||||
// There is a matching change
|
||||
// in JavaVirtualMachine.cpp that also needs to be changed.
|
||||
if (pNTHeader->Signature == IMAGE_NT_SIGNATURE) {
|
||||
DWORD base = (DWORD) (dwDosHeaders);
|
||||
result = GetImportsSection(base, pNTHeader);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#include <TlHelp32.h>
|
||||
|
||||
WindowsJob::WindowsJob() {
|
||||
FHandle = NULL;
|
||||
}
|
||||
|
||||
WindowsJob::~WindowsJob() {
|
||||
if (FHandle != NULL) {
|
||||
CloseHandle(FHandle);
|
||||
}
|
||||
}
|
||||
|
||||
HANDLE WindowsJob::GetHandle() {
|
||||
if (FHandle == NULL) {
|
||||
FHandle = CreateJobObject(NULL, NULL); // GLOBAL
|
||||
|
||||
if (FHandle == NULL) {
|
||||
::MessageBox(0, _T("Could not create job object"),
|
||||
_T("TEST"), MB_OK);
|
||||
} else {
|
||||
JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli = {0};
|
||||
|
||||
// Configure all child processes associated with
|
||||
// the job to terminate when the
|
||||
jeli.BasicLimitInformation.LimitFlags =
|
||||
JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
|
||||
if (0 == SetInformationJobObject(FHandle,
|
||||
JobObjectExtendedLimitInformation, &jeli, sizeof (jeli))) {
|
||||
::MessageBox(0, _T("Could not SetInformationJobObject"),
|
||||
_T("TEST"), MB_OK);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return FHandle;
|
||||
}
|
||||
|
||||
// Initialize static member of WindowsProcess
|
||||
WindowsJob WindowsProcess::FJob;
|
||||
|
||||
WindowsProcess::WindowsProcess() : Process() {
|
||||
FRunning = false;
|
||||
}
|
||||
|
||||
WindowsProcess::~WindowsProcess() {
|
||||
Terminate();
|
||||
}
|
||||
|
||||
void WindowsProcess::Cleanup() {
|
||||
CloseHandle(FProcessInfo.hProcess);
|
||||
CloseHandle(FProcessInfo.hThread);
|
||||
}
|
||||
|
||||
bool WindowsProcess::IsRunning() {
|
||||
bool result = false;
|
||||
|
||||
HANDLE handle = ::CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0);
|
||||
if (handle == INVALID_HANDLE_VALUE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
PROCESSENTRY32 process = {0};
|
||||
process.dwSize = sizeof (process);
|
||||
|
||||
if (::Process32First(handle, &process)) {
|
||||
do {
|
||||
if (process.th32ProcessID == FProcessInfo.dwProcessId) {
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
} while (::Process32Next(handle, &process));
|
||||
}
|
||||
|
||||
CloseHandle(handle);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool WindowsProcess::Terminate() {
|
||||
bool result = false;
|
||||
|
||||
if (IsRunning() == true && FRunning == true) {
|
||||
FRunning = false;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool WindowsProcess::Execute(const TString Application,
|
||||
const std::vector<TString> Arguments, bool AWait) {
|
||||
bool result = false;
|
||||
|
||||
if (FRunning == false) {
|
||||
FRunning = true;
|
||||
|
||||
STARTUPINFO startupInfo;
|
||||
ZeroMemory(&startupInfo, sizeof (startupInfo));
|
||||
startupInfo.cb = sizeof (startupInfo);
|
||||
ZeroMemory(&FProcessInfo, sizeof (FProcessInfo));
|
||||
|
||||
TString command = Application;
|
||||
|
||||
for (std::vector<TString>::const_iterator iterator = Arguments.begin();
|
||||
iterator != Arguments.end(); iterator++) {
|
||||
command += TString(_T(" ")) + *iterator;
|
||||
}
|
||||
|
||||
if (::CreateProcess(Application.data(), (wchar_t*)command.data(), NULL,
|
||||
NULL, FALSE, 0, NULL, NULL, &startupInfo, &FProcessInfo)
|
||||
== FALSE) {
|
||||
TString message = PlatformString::Format(
|
||||
_T("Error: Unable to create process %s"),
|
||||
Application.data());
|
||||
throw Exception(message);
|
||||
} else {
|
||||
if (FJob.GetHandle() != NULL) {
|
||||
if (::AssignProcessToJobObject(FJob.GetHandle(),
|
||||
FProcessInfo.hProcess) == 0) {
|
||||
// Failed to assign process to job. It doesn't prevent
|
||||
// anything from continuing so continue.
|
||||
}
|
||||
}
|
||||
|
||||
// Wait until child process exits.
|
||||
if (AWait == true) {
|
||||
Wait();
|
||||
// Close process and thread handles.
|
||||
Cleanup();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool WindowsProcess::Wait() {
|
||||
bool result = false;
|
||||
|
||||
WaitForSingleObject(FProcessInfo.hProcess, INFINITE);
|
||||
return result;
|
||||
}
|
||||
|
||||
TProcessID WindowsProcess::GetProcessID() {
|
||||
return FProcessInfo.dwProcessId;
|
||||
}
|
||||
|
||||
bool WindowsProcess::ReadOutput() {
|
||||
bool result = false;
|
||||
// TODO implement
|
||||
return result;
|
||||
}
|
||||
|
||||
void WindowsProcess::SetInput(TString Value) {
|
||||
// TODO implement
|
||||
}
|
||||
|
||||
std::list<TString> WindowsProcess::GetOutput() {
|
||||
ReadOutput();
|
||||
return Process::GetOutput();
|
||||
}
|
@ -1,171 +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 WINDOWSPLATFORM_H
|
||||
#define WINDOWSPLATFORM_H
|
||||
|
||||
#include <Windows.h>
|
||||
#include "Platform.h"
|
||||
|
||||
class WindowsPlatform : virtual public Platform {
|
||||
private:
|
||||
DWORD FMainThread;
|
||||
|
||||
public:
|
||||
WindowsPlatform(void);
|
||||
virtual ~WindowsPlatform(void);
|
||||
|
||||
virtual TCHAR* ConvertStringToFileSystemString(TCHAR* Source,
|
||||
bool &release);
|
||||
virtual TCHAR* ConvertFileSystemStringToString(TCHAR* Source,
|
||||
bool &release);
|
||||
|
||||
virtual void ShowMessage(TString title, TString description);
|
||||
virtual void ShowMessage(TString description);
|
||||
virtual MessageResponse ShowResponseMessage(TString title,
|
||||
TString description);
|
||||
|
||||
virtual TString GetPackageRootDirectory();
|
||||
virtual TString GetAppDataDirectory();
|
||||
virtual TString GetAppName();
|
||||
virtual TString GetBundledJavaLibraryFileName(TString RuntimePath);
|
||||
TString GetPackageAppDirectory();
|
||||
TString GetPackageLauncherDirectory();
|
||||
TString GetPackageRuntimeBinDirectory();
|
||||
|
||||
virtual ISectionalPropertyContainer* GetConfigFile(TString FileName);
|
||||
|
||||
virtual TString GetModuleFileName();
|
||||
virtual Module LoadLibrary(TString FileName);
|
||||
virtual void FreeLibrary(Module AModule);
|
||||
virtual Procedure GetProcAddress(Module AModule, std::string MethodName);
|
||||
|
||||
virtual Process* CreateProcess();
|
||||
|
||||
virtual bool IsMainThread();
|
||||
virtual TPlatformNumber GetMemorySize();
|
||||
|
||||
virtual TString GetTempDirectory();
|
||||
void InitStreamLocale(wios *stream);
|
||||
void addPlatformDependencies(JavaLibrary *pJavaLibrary);
|
||||
};
|
||||
|
||||
class FileHandle {
|
||||
private:
|
||||
HANDLE FHandle;
|
||||
|
||||
public:
|
||||
FileHandle(std::wstring FileName);
|
||||
~FileHandle();
|
||||
|
||||
bool IsValid();
|
||||
HANDLE GetHandle();
|
||||
};
|
||||
|
||||
|
||||
class FileMappingHandle {
|
||||
private:
|
||||
HANDLE FHandle;
|
||||
|
||||
public:
|
||||
FileMappingHandle(HANDLE FileHandle);
|
||||
~FileMappingHandle();
|
||||
|
||||
bool IsValid();
|
||||
HANDLE GetHandle();
|
||||
};
|
||||
|
||||
|
||||
class FileData {
|
||||
private:
|
||||
LPVOID FBaseAddress;
|
||||
|
||||
public:
|
||||
FileData(HANDLE Handle);
|
||||
~FileData();
|
||||
|
||||
bool IsValid();
|
||||
LPVOID GetBaseAddress();
|
||||
};
|
||||
|
||||
|
||||
class WindowsLibrary {
|
||||
private:
|
||||
TString FFileName;
|
||||
|
||||
// Given an RVA, look up the section header that encloses it and return a
|
||||
// pointer to its IMAGE_SECTION_HEADER
|
||||
static PIMAGE_SECTION_HEADER GetEnclosingSectionHeader(DWORD rva,
|
||||
PIMAGE_NT_HEADERS pNTHeader);
|
||||
static LPVOID GetPtrFromRVA(DWORD rva, PIMAGE_NT_HEADERS pNTHeader,
|
||||
DWORD imageBase);
|
||||
static std::vector<TString> GetImportsSection(DWORD base,
|
||||
PIMAGE_NT_HEADERS pNTHeader);
|
||||
static std::vector<TString> DumpPEFile(PIMAGE_DOS_HEADER dosHeader);
|
||||
|
||||
public:
|
||||
WindowsLibrary(const TString FileName);
|
||||
|
||||
std::vector<TString> GetImports();
|
||||
};
|
||||
|
||||
|
||||
class WindowsJob {
|
||||
private:
|
||||
HANDLE FHandle;
|
||||
|
||||
public:
|
||||
WindowsJob();
|
||||
~WindowsJob();
|
||||
|
||||
HANDLE GetHandle();
|
||||
};
|
||||
|
||||
|
||||
class WindowsProcess : public Process {
|
||||
private:
|
||||
bool FRunning;
|
||||
|
||||
PROCESS_INFORMATION FProcessInfo;
|
||||
static WindowsJob FJob;
|
||||
|
||||
void Cleanup();
|
||||
bool ReadOutput();
|
||||
|
||||
public:
|
||||
WindowsProcess();
|
||||
virtual ~WindowsProcess();
|
||||
|
||||
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 // WINDOWSPLATFORM_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
|
||||
@ -30,6 +30,8 @@
|
||||
|
||||
#include "Utils.h"
|
||||
|
||||
#pragma comment(lib, "advapi32")
|
||||
|
||||
// Max value name size per MSDN plus NULL
|
||||
#define VALUE_NAME_SIZE 16384
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2019, 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
|
||||
@ -105,11 +105,6 @@ extern "C" {
|
||||
return 1;
|
||||
}
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason,
|
||||
LPVOID lpvReserved) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -1,8 +1,34 @@
|
||||
/*
|
||||
* 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
|
||||
* 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 <windows.h>
|
||||
|
||||
#include "SysInfo.h"
|
||||
#include "FileUtils.h"
|
||||
#include "WinFileUtils.h"
|
||||
#include "Executor.h"
|
||||
#include "Resources.h"
|
||||
#include "WinErrorHandling.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
|
||||
@ -25,6 +25,7 @@
|
||||
|
||||
#include "Resources.h"
|
||||
#include "FileUtils.h"
|
||||
#include "WinFileUtils.h"
|
||||
#include "WinErrorHandling.h"
|
||||
|
||||
#include <fstream>
|
||||
|
@ -1,10 +1,12 @@
|
||||
/*
|
||||
* 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
* 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
|
||||
@ -20,6 +22,7 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package jdk.jpackage.test;
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
@ -733,10 +736,10 @@ public final class JPackageCommand extends CommandArguments<JPackageCommand> {
|
||||
|
||||
return args.stream().map(v -> {
|
||||
String str = v;
|
||||
// Escape quotes.
|
||||
str = str.replace("\"", "\\\"");
|
||||
// Escape backslashes.
|
||||
str = str.replace("\\", "\\\\");
|
||||
// Escape quotes.
|
||||
str = str.replace("\"", "\\\"");
|
||||
// If value contains whitespace characters, put the value in quotes
|
||||
if (whitespaceRegexp.matcher(str).find()) {
|
||||
str = "\"" + str + "\"";
|
||||
|
@ -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
|
||||
@ -82,7 +82,6 @@ public class ApplicationLayoutTest {
|
||||
assertTrue(Files.isDirectory(layout.appModsDirectory()));
|
||||
assertTrue(Files.isRegularFile(layout.launchersDirectory().resolve("Foo")));
|
||||
assertTrue(Files.isRegularFile(layout.destktopIntegrationDirectory().resolve("Foo.png")));
|
||||
assertTrue(Files.isRegularFile(layout.dllDirectory().resolve("libapplauncher.so")));
|
||||
assertTrue(Files.isRegularFile(layout.runtimeDirectory().resolve("bin/java")));
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package jdk.jpackage.tests;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import jdk.jpackage.test.Annotations.Test;
|
||||
import jdk.jpackage.test.Annotations.Parameter;
|
||||
import jdk.jpackage.test.HelloApp;
|
||||
import jdk.jpackage.test.JavaAppDesc;
|
||||
import jdk.jpackage.test.JPackageCommand;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @summary jpackage application packed in multiple jars
|
||||
* @library ../../../../helpers
|
||||
* @build jdk.jpackage.test.*
|
||||
* @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal
|
||||
* @compile MultipleJarAppTest.java
|
||||
* @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main
|
||||
* --jpt-run=jdk.jpackage.tests.MultipleJarAppTest
|
||||
*/
|
||||
|
||||
public final class MultipleJarAppTest {
|
||||
|
||||
@Test
|
||||
@Parameter("B")
|
||||
@Parameter("C")
|
||||
public void test(String mainClass) {
|
||||
JPackageCommand cmd = JPackageCommand.helloAppImage("a.jar:A");
|
||||
HelloApp.createBundle(JavaAppDesc.parse("b.jar:B"), cmd.inputDir());
|
||||
HelloApp.createBundle(JavaAppDesc.parse("c.jar:C"), cmd.inputDir());
|
||||
|
||||
cmd.setArgumentValue("--main-class", mainClass);
|
||||
cmd.executeAndAssertHelloAppImageCreated();
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user