jruby-launcher 1.1.1-java → 1.1.2-java

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,40 +1,40 @@
1
- include inc/Makefile-conf.mk
2
-
3
- # Build Targets
4
- .build-conf: ${BUILD_SUBPROJECTS}
5
- ${MAKE} -f inc/Makefile-rules.mk $(PROGRAM)
6
-
7
- jruby.dll: ${OBJECTFILES}
8
- ${LINK.cc} -shared -s -o $@ $^ $(LDLIBSOPTIONS)
9
-
10
- jruby: $(OBJECTDIR)/jruby-launcher
11
- cp $^ $@
12
-
13
- $(OBJECTDIR)/jruby-launcher: ${OBJECTFILES}
14
- ${LINK.cc} -o $@ $^ $(LDLIBSOPTIONS)
15
-
16
- $(OBJECTDIR)/%.o: %.cpp inc/Makefile-rules.mk inc/Makefile-conf.mk
17
- ${MKDIR} -p ${OBJECTDIR}
18
- ${RM} $@.d
19
- $(COMPILE.cc) $< -MMD -MP -MF $@.d -o $@
20
-
21
- $(OBJECTDIR)/%.o: %.c inc/Makefile-rules.mk inc/Makefile-conf.mk
22
- ${MKDIR} -p ${OBJECTDIR}
23
- ${RM} $@.d
24
- $(COMPILE.c) $< -MMD -MP -MF $@.d -o $@
25
-
26
- # Subprojects
27
- .build-subprojects:
28
-
29
- # Clean Targets
30
- .clean-conf: ${CLEAN_SUBPROJECTS}
31
- ${RM} -r build/$(CONF)
32
- ${RM} -f $(PROGRAM)
33
-
34
- # Subprojects
35
- .clean-subprojects:
36
-
37
- # Enable dependency checking
38
- .dep.inc: .depcheck-impl
39
-
40
- include .dep.inc
1
+ include inc/Makefile-conf.mk
2
+
3
+ # Build Targets
4
+ .build-conf: ${BUILD_SUBPROJECTS}
5
+ ${MAKE} -f inc/Makefile-rules.mk $(PROGRAM)
6
+
7
+ jruby.dll: ${OBJECTFILES}
8
+ ${LINK.cc} -shared -s -o $@ $^ $(LDLIBSOPTIONS)
9
+
10
+ jruby: $(OBJECTDIR)/jruby-launcher
11
+ cp $^ $@
12
+
13
+ $(OBJECTDIR)/jruby-launcher: ${OBJECTFILES}
14
+ ${LINK.cc} -o $@ $^ $(LDLIBSOPTIONS)
15
+
16
+ $(OBJECTDIR)/%.o: %.cpp inc/Makefile-rules.mk inc/Makefile-conf.mk
17
+ ${MKDIR} -p ${OBJECTDIR}
18
+ ${RM} $@.d
19
+ $(COMPILE.cc) $< -MMD -MP -MF $@.d -o $@
20
+
21
+ $(OBJECTDIR)/%.o: %.c inc/Makefile-rules.mk inc/Makefile-conf.mk
22
+ ${MKDIR} -p ${OBJECTDIR}
23
+ ${RM} $@.d
24
+ $(COMPILE.c) $< -MMD -MP -MF $@.d -o $@
25
+
26
+ # Subprojects
27
+ .build-subprojects:
28
+
29
+ # Clean Targets
30
+ .clean-conf: ${CLEAN_SUBPROJECTS}
31
+ ${RM} -r build/$(CONF)
32
+ ${RM} -f $(PROGRAM)
33
+
34
+ # Subprojects
35
+ .clean-subprojects:
36
+
37
+ # Enable dependency checking
38
+ .dep.inc: .depcheck-impl
39
+
40
+ include .dep.inc
data/jruby.cpp CHANGED
@@ -1,77 +1,77 @@
1
- /*
2
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
- *
4
- * Copyright 1997-2008 Sun Microsystems, Inc. All rights reserved.
5
- *
6
- * The contents of this file are subject to the terms of either the GNU
7
- * General Public License Version 2 only ("GPL") or the Common
8
- * Development and Distribution License("CDDL") (collectively, the
9
- * "License"). You may not use this file except in compliance with the
10
- * License. You can obtain a copy of the License at
11
- * http://www.netbeans.org/cddl-gplv2.html
12
- * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
13
- * specific language governing permissions and limitations under the
14
- * License. When distributing the software, include this License Header
15
- * Notice in each file and include the License file at
16
- * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
17
- * particular file as subject to the "Classpath" exception as provided
18
- * by Sun in the GPL Version 2 section of the License file that
19
- * accompanied this code. If applicable, add the following below the
20
- * License Header, with the fields enclosed by brackets [] replaced by
21
- * your own identifying information:
22
- * "Portions Copyrighted [year] [name of copyright owner]"
23
- *
24
- * Contributor(s):
25
- *
26
- * The Original Software is NetBeans. The Initial Developer of the Original
27
- * Software is Sun Microsystems, Inc. Portions Copyright 1997-2008 Sun
28
- * Microsystems, Inc. All Rights Reserved.
29
- *
30
- * If you wish your version of this file to be governed by only the CDDL
31
- * or only the GPL Version 2, indicate your decision by adding
32
- * "[Contributor] elects to include this software in this distribution
33
- * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
- * single choice of license, a recipient has the option to distribute
35
- * your version of this file under either the CDDL, the GPL Version 2 or
36
- * to extend the choice of license to its licensees as provided above.
37
- * However, if you add GPL Version 2 code and therefore, elected the GPL
38
- * Version 2 license, then the option applies only if the new code is
39
- * made subject to such option by the copyright holder.
40
- *
41
- * Author: Tomas Holy
42
- */
43
-
44
- #include "platformlauncher.h"
45
- #include "utilsfuncs.h"
46
-
47
- PlatformLauncher launcher;
48
-
49
- extern "C" BOOL APIENTRY DllMain(HANDLE hModule,
50
- DWORD ul_reason_for_call,
51
- LPVOID lpReserved
52
- ) {
53
- switch (ul_reason_for_call) {
54
- case DLL_PROCESS_ATTACH:
55
- break;
56
- case DLL_THREAD_ATTACH:
57
- break;
58
- case DLL_THREAD_DETACH:
59
- break;
60
- case DLL_PROCESS_DETACH:
61
- launcher.onExit();
62
- break;
63
- }
64
- return TRUE;
65
- }
66
-
67
- #define NBEXEC_EXPORT extern "C" __declspec(dllexport)
68
-
69
- NBEXEC_EXPORT int startPlatform(int argc, char *argv[], const char *helpMsg, const char *name) {
70
- DWORD retCode = 0;
71
- launcher.appendToHelp(helpMsg);
72
- launcher.setSuppressConsole(!isConsoleAttached());
73
- if (!launcher.start(argv, argc, &retCode, name)) {
74
- return -1;
75
- }
76
- return retCode;
77
- }
1
+ /*
2
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
+ *
4
+ * Copyright 1997-2008 Sun Microsystems, Inc. All rights reserved.
5
+ *
6
+ * The contents of this file are subject to the terms of either the GNU
7
+ * General Public License Version 2 only ("GPL") or the Common
8
+ * Development and Distribution License("CDDL") (collectively, the
9
+ * "License"). You may not use this file except in compliance with the
10
+ * License. You can obtain a copy of the License at
11
+ * http://www.netbeans.org/cddl-gplv2.html
12
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
13
+ * specific language governing permissions and limitations under the
14
+ * License. When distributing the software, include this License Header
15
+ * Notice in each file and include the License file at
16
+ * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
17
+ * particular file as subject to the "Classpath" exception as provided
18
+ * by Sun in the GPL Version 2 section of the License file that
19
+ * accompanied this code. If applicable, add the following below the
20
+ * License Header, with the fields enclosed by brackets [] replaced by
21
+ * your own identifying information:
22
+ * "Portions Copyrighted [year] [name of copyright owner]"
23
+ *
24
+ * Contributor(s):
25
+ *
26
+ * The Original Software is NetBeans. The Initial Developer of the Original
27
+ * Software is Sun Microsystems, Inc. Portions Copyright 1997-2008 Sun
28
+ * Microsystems, Inc. All Rights Reserved.
29
+ *
30
+ * If you wish your version of this file to be governed by only the CDDL
31
+ * or only the GPL Version 2, indicate your decision by adding
32
+ * "[Contributor] elects to include this software in this distribution
33
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
+ * single choice of license, a recipient has the option to distribute
35
+ * your version of this file under either the CDDL, the GPL Version 2 or
36
+ * to extend the choice of license to its licensees as provided above.
37
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
38
+ * Version 2 license, then the option applies only if the new code is
39
+ * made subject to such option by the copyright holder.
40
+ *
41
+ * Author: Tomas Holy
42
+ */
43
+
44
+ #include "platformlauncher.h"
45
+ #include "utilsfuncs.h"
46
+
47
+ PlatformLauncher launcher;
48
+
49
+ extern "C" BOOL APIENTRY DllMain(HANDLE hModule,
50
+ DWORD ul_reason_for_call,
51
+ LPVOID lpReserved
52
+ ) {
53
+ switch (ul_reason_for_call) {
54
+ case DLL_PROCESS_ATTACH:
55
+ break;
56
+ case DLL_THREAD_ATTACH:
57
+ break;
58
+ case DLL_THREAD_DETACH:
59
+ break;
60
+ case DLL_PROCESS_DETACH:
61
+ launcher.onExit();
62
+ break;
63
+ }
64
+ return TRUE;
65
+ }
66
+
67
+ #define NBEXEC_EXPORT extern "C" __declspec(dllexport)
68
+
69
+ NBEXEC_EXPORT int startPlatform(int argc, char *argv[], const char *helpMsg, const char *name) {
70
+ DWORD retCode = 0;
71
+ launcher.appendToHelp(helpMsg);
72
+ launcher.setSuppressConsole(!isConsoleAttached());
73
+ if (!launcher.start(argv, argc, &retCode, name)) {
74
+ return -1;
75
+ }
76
+ return retCode;
77
+ }
@@ -1,84 +1,84 @@
1
- /*
2
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
- *
4
- * Copyright 1997-2008, 2010 Sun Microsystems, Inc. All rights reserved.
5
- *
6
- * The contents of this file are subject to the terms of either the GNU
7
- * General Public License Version 2 only ("GPL") or the Common
8
- * Development and Distribution License("CDDL") (collectively, the
9
- * "License"). You may not use this file except in compliance with the
10
- * License. You can obtain a copy of the License at
11
- * http://www.netbeans.org/cddl-gplv2.html
12
- * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
13
- * specific language governing permissions and limitations under the
14
- * License. When distributing the software, include this License Header
15
- * Notice in each file and include the License file at
16
- * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
17
- * particular file as subject to the "Classpath" exception as provided
18
- * by Sun in the GPL Version 2 section of the License file that
19
- * accompanied this code. If applicable, add the following below the
20
- * License Header, with the fields enclosed by brackets [] replaced by
21
- * your own identifying information:
22
- * "Portions Copyrighted [year] [name of copyright owner]"
23
- *
24
- * Contributor(s):
25
- *
26
- * The Original Software is NetBeans. The Initial Developer of the Original
27
- * Software is Sun Microsystems, Inc. Portions Copyright 1997-2008 Sun
28
- * Microsystems, Inc. All Rights Reserved.
29
- *
30
- * If you wish your version of this file to be governed by only the CDDL
31
- * or only the GPL Version 2, indicate your decision by adding
32
- * "[Contributor] elects to include this software in this distribution
33
- * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
- * single choice of license, a recipient has the option to distribute
35
- * your version of this file under either the CDDL, the GPL Version 2 or
36
- * to extend the choice of license to its licensees as provided above.
37
- * However, if you add GPL Version 2 code and therefore, elected the GPL
38
- * Version 2 license, then the option applies only if the new code is
39
- * made subject to such option by the copyright holder.
40
- *
41
- * Author: Tomas Holy
42
- */
43
-
44
- #ifdef WIN32
45
- #include <windows.h>
46
- #include "nbexecloader.h"
47
-
48
- #ifdef JRUBYW
49
- const char *CON_ATTACH_MSG =
50
- "*WARNING*: The non-console JRubyW launcher is forced to attach to console.\n"
51
- "This may cause unexpected behavior of CMD console. Use:\n"
52
- " start /wait jrubyw.exe -Xconsole attach [args]\n";
53
- #endif // JRUBYW
54
- #else
55
- #include "unixlauncher.h"
56
- #endif // WIN32
57
-
58
- #include "utilsfuncs.h"
59
-
60
-
61
- int main(int argc, char *argv[], char* envp[]) {
62
- checkLoggingArg(argc, argv, true);
63
-
64
- #ifdef WIN32
65
- #ifdef JRUBYW
66
- if (!isConsoleAttached()) {
67
- logMsg("Console is not attached, assume WINDOW mode");
68
- DWORD parentProcID = 0;
69
- if (!setupProcess(argc, argv, parentProcID, CON_ATTACH_MSG)) {
70
- return -1;
71
- }
72
- } else {
73
- logMsg("Console is not attached, assume CONSOLE mode");
74
- }
75
- #endif // JRUBYW
76
-
77
- NBExecLoader loader;
78
- return loader.start("jruby.dll", argc - 1, argv + 1, argv[0]);
79
-
80
- #else // !WIN32
81
- UnixLauncher launcher;
82
- return launcher.run(argc, argv, envp);
83
- #endif // WIN32
84
- }
1
+ /*
2
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
+ *
4
+ * Copyright 1997-2008, 2010 Sun Microsystems, Inc. All rights reserved.
5
+ *
6
+ * The contents of this file are subject to the terms of either the GNU
7
+ * General Public License Version 2 only ("GPL") or the Common
8
+ * Development and Distribution License("CDDL") (collectively, the
9
+ * "License"). You may not use this file except in compliance with the
10
+ * License. You can obtain a copy of the License at
11
+ * http://www.netbeans.org/cddl-gplv2.html
12
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
13
+ * specific language governing permissions and limitations under the
14
+ * License. When distributing the software, include this License Header
15
+ * Notice in each file and include the License file at
16
+ * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
17
+ * particular file as subject to the "Classpath" exception as provided
18
+ * by Sun in the GPL Version 2 section of the License file that
19
+ * accompanied this code. If applicable, add the following below the
20
+ * License Header, with the fields enclosed by brackets [] replaced by
21
+ * your own identifying information:
22
+ * "Portions Copyrighted [year] [name of copyright owner]"
23
+ *
24
+ * Contributor(s):
25
+ *
26
+ * The Original Software is NetBeans. The Initial Developer of the Original
27
+ * Software is Sun Microsystems, Inc. Portions Copyright 1997-2008 Sun
28
+ * Microsystems, Inc. All Rights Reserved.
29
+ *
30
+ * If you wish your version of this file to be governed by only the CDDL
31
+ * or only the GPL Version 2, indicate your decision by adding
32
+ * "[Contributor] elects to include this software in this distribution
33
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
+ * single choice of license, a recipient has the option to distribute
35
+ * your version of this file under either the CDDL, the GPL Version 2 or
36
+ * to extend the choice of license to its licensees as provided above.
37
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
38
+ * Version 2 license, then the option applies only if the new code is
39
+ * made subject to such option by the copyright holder.
40
+ *
41
+ * Author: Tomas Holy
42
+ */
43
+
44
+ #ifdef WIN32
45
+ #include <windows.h>
46
+ #include "nbexecloader.h"
47
+
48
+ #ifdef JRUBYW
49
+ const char *CON_ATTACH_MSG =
50
+ "*WARNING*: The non-console JRubyW launcher is forced to attach to console.\n"
51
+ "This may cause unexpected behavior of CMD console. Use:\n"
52
+ " start /wait jrubyw.exe -Xconsole attach [args]\n";
53
+ #endif // JRUBYW
54
+ #else
55
+ #include "unixlauncher.h"
56
+ #endif // WIN32
57
+
58
+ #include "utilsfuncs.h"
59
+
60
+
61
+ int main(int argc, char *argv[], char* envp[]) {
62
+ checkLoggingArg(argc, argv, true);
63
+
64
+ #ifdef WIN32
65
+ #ifdef JRUBYW
66
+ if (!isConsoleAttached()) {
67
+ logMsg("Console is not attached, assume WINDOW mode");
68
+ DWORD parentProcID = 0;
69
+ if (!setupProcess(argc, argv, parentProcID, CON_ATTACH_MSG)) {
70
+ return -1;
71
+ }
72
+ } else {
73
+ logMsg("Console is not attached, assume CONSOLE mode");
74
+ }
75
+ #endif // JRUBYW
76
+
77
+ NBExecLoader loader;
78
+ return loader.start("jruby.dll", argc - 1, argv + 1, argv[0]);
79
+
80
+ #else // !WIN32
81
+ UnixLauncher launcher;
82
+ return launcher.run(argc, argv, envp);
83
+ #endif // WIN32
84
+ }
@@ -1,454 +1,459 @@
1
- /*
2
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
- *
4
- * Copyright 2009-2012 JRuby Team (www.jruby.org).
5
- * Copyright 1997-2008 Sun Microsystems, Inc. All rights reserved.
6
- *
7
- * The contents of this file are subject to the terms of either the GNU
8
- * General Public License Version 2 only ("GPL") or the Common
9
- * Development and Distribution License("CDDL") (collectively, the
10
- * "License"). You may not use this file except in compliance with the
11
- * License. You can obtain a copy of the License at
12
- * http://www.netbeans.org/cddl-gplv2.html
13
- * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
14
- * specific language governing permissions and limitations under the
15
- * License. When distributing the software, include this License Header
16
- * Notice in each file and include the License file at
17
- * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
18
- * particular file as subject to the "Classpath" exception as provided
19
- * by Sun in the GPL Version 2 section of the License file that
20
- * accompanied this code. If applicable, add the following below the
21
- * License Header, with the fields enclosed by brackets [] replaced by
22
- * your own identifying information:
23
- * "Portions Copyrighted [year] [name of copyright owner]"
24
- *
25
- * Contributor(s):
26
- *
27
- * The Original Software is NetBeans. The Initial Developer of the Original
28
- * Software is Sun Microsystems, Inc. Portions Copyright 1997-2008 Sun
29
- * Microsystems, Inc. All Rights Reserved.
30
- *
31
- * If you wish your version of this file to be governed by only the CDDL
32
- * or only the GPL Version 2, indicate your decision by adding
33
- * "[Contributor] elects to include this software in this distribution
34
- * under the [CDDL or GPL Version 2] license." If you do not indicate a
35
- * single choice of license, a recipient has the option to distribute
36
- * your version of this file under either the CDDL, the GPL Version 2 or
37
- * to extend the choice of license to its licensees as provided above.
38
- * However, if you add GPL Version 2 code and therefore, elected the GPL
39
- * Version 2 license, then the option applies only if the new code is
40
- * made subject to such option by the copyright holder.
41
- *
42
- * Author: Tomas Holy
43
- */
44
-
45
- #include "jvmlauncher.h"
46
- #include <cassert>
47
-
48
- using namespace std;
49
-
50
- const char *JvmLauncher::JDK_KEY = "Software\\JavaSoft\\Java Development Kit";
51
- const char *JvmLauncher::JRE_KEY = "Software\\JavaSoft\\Java Runtime Environment";
52
- const char *JvmLauncher::CUR_VERSION_NAME = "CurrentVersion";
53
- const char *JvmLauncher::JAVA_HOME_NAME = "JavaHome";
54
- const char *JvmLauncher::JAVA_BIN_DIR = "\\bin";
55
- const char *JvmLauncher::JAVA_EXE_FILE = "\\bin\\java.exe";
56
- const char *JvmLauncher::JAVAW_EXE_FILE = "\\bin\\javaw.exe";
57
- const char *JvmLauncher::JAVA_CLIENT_DLL_FILE = "\\bin\\client\\jvm.dll";
58
- const char *JvmLauncher::JAVA_SERVER_DLL_FILE = "\\bin\\server\\jvm.dll";
59
- const char *JvmLauncher::JAVA_JRE_PREFIX = "\\jre";
60
- const char *JvmLauncher::JNI_CREATEVM_FUNC = "JNI_CreateJavaVM";
61
-
62
-
63
- JvmLauncher::JvmLauncher()
64
- : suppressConsole(false) {
65
- }
66
-
67
- JvmLauncher::JvmLauncher(const JvmLauncher& orig) {
68
- }
69
-
70
- JvmLauncher::~JvmLauncher() {
71
- }
72
-
73
- void JvmLauncher::setJavaCmd(const string cmdPath) {
74
- javaExePath = cmdPath;
75
- javaPath = "";
76
- javawExePath = javaPath;
77
- javaClientDllPath = javaPath;
78
- javaServerDllPath = javaPath;
79
- }
80
-
81
- bool JvmLauncher::checkJava(std::string &path, const char *prefix) {
82
- assert(prefix);
83
- logMsg("checkJava('%s', '%s')", path.c_str(), prefix);
84
-
85
- if (*path.rbegin() == '\\') {
86
- path.erase(path.length() - 1, 1);
87
- }
88
- javaExePath = path + prefix + JAVA_EXE_FILE;
89
- javawExePath = path + prefix + JAVAW_EXE_FILE;
90
- javaClientDllPath = path + prefix + JAVA_CLIENT_DLL_FILE;
91
- javaServerDllPath = path + prefix + JAVA_SERVER_DLL_FILE;
92
- if (!fileExists(javaClientDllPath.c_str())) {
93
- javaClientDllPath = "";
94
- }
95
- if (!fileExists(javaServerDllPath.c_str())) {
96
- javaServerDllPath = "";
97
- }
98
- javaBinPath = path + prefix + JAVA_BIN_DIR;
99
- if (fileExists(javaExePath.c_str()) || !javaClientDllPath.empty() || !javaServerDllPath.empty()) {
100
- if (!fileExists(javawExePath.c_str())) {
101
- logMsg("javaw.exe not exists, forcing java.exe");
102
- javawExePath = javaExePath;
103
- }
104
- javaPath = path;
105
- return true;
106
- }
107
-
108
- javaBinPath.clear();
109
- javaExePath.clear();
110
- javawExePath.clear();
111
- javaClientDllPath.clear();
112
- javaServerDllPath.clear();
113
- return false;
114
- }
115
-
116
- bool JvmLauncher::initialize(const char *javaPathOrMinVersion) {
117
- logMsg("JvmLauncher::initialize()\n\tjavaPathOrMinVersion: %s", javaPathOrMinVersion);
118
- assert(javaPathOrMinVersion);
119
-
120
- std::string pathOrVersion(javaPathOrMinVersion);
121
-
122
- if (isVersionString(javaPathOrMinVersion)) {
123
- return findJava(javaPathOrMinVersion);
124
- } else {
125
- return (checkJava(pathOrVersion, JAVA_JRE_PREFIX) || checkJava(pathOrVersion, ""));
126
- }
127
- }
128
-
129
- bool JvmLauncher::getJavaPath(string &path) {
130
- logMsg("JvmLauncher::getJavaPath()");
131
- path = javaPath;
132
- return !javaPath.empty();
133
- }
134
-
135
- bool JvmLauncher::start(const char *mainClassName, list<string> args, list<string> options, bool &separateProcess, DWORD *retCode) {
136
- assert(mainClassName);
137
- logMsg("JvmLauncher::start()\n\tmainClassName: %s\n\tseparateProcess: %s",
138
- mainClassName, separateProcess ? "true" : "false");
139
- logMsg(" args:");
140
- for (list<string>::iterator it = args.begin(); it != args.end(); ++it) {
141
- logMsg("\t%s", it->c_str());
142
- }
143
- logMsg(" options:");
144
- for (list<string>::iterator it = options.begin(); it != options.end(); ++it) {
145
- logMsg("\t%s", it->c_str());
146
- }
147
-
148
- if (javaExePath.empty() && javaClientDllPath.empty() && javaServerDllPath.empty()) {
149
- // try to find out any java installed (check the registry)
150
- if (!initialize("")) {
151
- return false;
152
- }
153
- }
154
-
155
- if (!separateProcess) {
156
- // both client/server found, check option which should be used
157
- if (!javaClientDllPath.empty() && !javaServerDllPath.empty()) {
158
- // By default, load client VM. Load server VM only if explicitly asked.
159
- javaDllPath = findServerOption(options) ? javaServerDllPath: javaClientDllPath;
160
- } else {
161
- javaDllPath = javaClientDllPath.empty() ? javaServerDllPath : javaClientDllPath;
162
- }
163
-
164
- // it is necessary to absolutize dll path because current dir has to be
165
- // temporarily changed for dll loading
166
- char absoluteJavaDllPath[MAX_PATH] = "";
167
- strncpy(absoluteJavaDllPath, javaDllPath.c_str(), MAX_PATH);
168
- normalizePath(absoluteJavaDllPath, MAX_PATH);
169
- javaDllPath = absoluteJavaDllPath;
170
-
171
- logMsg("Java DLL path: %s", javaDllPath.c_str());
172
- if (!canLoadJavaDll()) {
173
- logMsg("Falling back to running Java in a separate process; DLL cannot be loaded (64-bit DLL?).");
174
- separateProcess = true;
175
- }
176
- }
177
-
178
- return separateProcess ? startOutProcJvm(mainClassName, args, options, retCode)
179
- : startInProcJvm(mainClassName, args, options);
180
- }
181
-
182
- bool JvmLauncher::findServerOption(list<string> &options) {
183
- for (list<string>::iterator it = options.begin(); it != options.end(); ++it) {
184
- if (*it == "-server") {
185
- return true;
186
- }
187
- }
188
- return false;
189
- }
190
-
191
- bool JvmLauncher::canLoadJavaDll() {
192
- // be prepared for stupid placement of msvcr71.dll in java installation
193
- // (in java 1.6/1.7 jvm.dll is dynamically linked to msvcr71.dll which si placed
194
- // in bin directory)
195
- PrepareDllPath prepare(javaBinPath.c_str());
196
- HMODULE hDll = LoadLibrary(javaDllPath.c_str());
197
- if (hDll) {
198
- FreeLibrary(hDll);
199
- return true;
200
- }
201
- logErr(true, false, "Cannot load %s.", javaDllPath.c_str());
202
- return false;
203
- }
204
-
205
- bool JvmLauncher::isVersionString(const char *str) {
206
- char *end = 0;
207
- strtod(str, &end);
208
- return *end == '\0';
209
- }
210
-
211
- bool JvmLauncher::startInProcJvm(const char *mainClassName, std::list<std::string> mbcs_args, std::list<std::string> mbcs_options) {
212
-
213
- std::list<std::string> args;
214
- for (std::list<std::string>::iterator it = mbcs_args.begin(); it != mbcs_args.end(); ++it) {
215
- wchar_t wstr[2048];
216
- UINT cp = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
217
- MultiByteToWideChar(cp, 0, it->c_str(), -1, wstr, sizeof(wstr) / sizeof(wchar_t));
218
- int mb_size = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL);
219
- char *mbstr = (char*)malloc(mb_size);
220
- WideCharToMultiByte(CP_UTF8, 0, wstr, -1, mbstr, mb_size, NULL, NULL);
221
- args.push_back(mbstr);
222
- }
223
-
224
- std::list<std::string> options;
225
- for (std::list<std::string>::iterator it = mbcs_options.begin(); it != mbcs_options.end(); ++it) {
226
- wchar_t wstr[2048];
227
- UINT cp = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
228
- MultiByteToWideChar(cp, 0, it->c_str(), -1, wstr, sizeof(wstr) / sizeof(wchar_t));
229
- int mb_size = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL);
230
- char *mbstr = (char*)malloc(mb_size);
231
- WideCharToMultiByte(CP_UTF8, 0, wstr, -1, mbstr, mb_size, NULL, NULL);
232
- options.push_back(mbstr);
233
- }
234
-
235
- class Jvm {
236
- public:
237
-
238
- Jvm(JvmLauncher *jvmLauncher)
239
- : hDll(0)
240
- , jvm(0)
241
- , env(0)
242
- , jvmOptions(0)
243
- , jvmLauncher(jvmLauncher)
244
- {
245
- }
246
-
247
- ~Jvm() {
248
- if (env && env->ExceptionOccurred()) {
249
- env->ExceptionDescribe();
250
- }
251
-
252
- if (jvm) {
253
- logMsg("Destroying JVM");
254
- jvm->DestroyJavaVM();
255
- }
256
-
257
- if (jvmOptions) {
258
- delete[] jvmOptions;
259
- }
260
-
261
- if (hDll) {
262
- FreeLibrary(hDll);
263
- }
264
- }
265
-
266
- bool init(list<string> options) {
267
- logMsg("JvmLauncher::Jvm::init()");
268
- logMsg("LoadLibrary(\"%s\")", jvmLauncher->javaDllPath.c_str());
269
- {
270
- PrepareDllPath prepare(jvmLauncher->javaBinPath.c_str());
271
- hDll = LoadLibrary(jvmLauncher->javaDllPath.c_str());
272
- if (!hDll) {
273
- logErr(true, true, "Cannot load %s.", jvmLauncher->javaDllPath.c_str());
274
- return false;
275
- }
276
- }
277
-
278
- CreateJavaVM createJavaVM = (CreateJavaVM) GetProcAddress(hDll, JNI_CREATEVM_FUNC);
279
- if (!createJavaVM) {
280
- logErr(true, true, "GetProcAddress for %s failed.", JNI_CREATEVM_FUNC);
281
- return false;
282
- }
283
-
284
- // Explicity remove -server and -client options, they are not
285
- // needed, since we invoke JVM in-process and already know
286
- // which DLL to use.
287
- options.remove("-server");
288
- options.remove("-client");
289
-
290
- logMsg("JVM options:");
291
- jvmOptions = new JavaVMOption[options.size()];
292
- int i = 0;
293
- for (list<string>::iterator it = options.begin(); it != options.end(); ++it, ++i) {
294
- string &option = *it;
295
- logMsg("\t%s", option.c_str());
296
- jvmOptions[i].optionString = (char *) option.c_str();
297
- jvmOptions[i].extraInfo = 0;
298
- }
299
-
300
- JavaVMInitArgs jvmArgs;
301
- jvmArgs.options = jvmOptions;
302
- jvmArgs.nOptions = options.size();
303
- jvmArgs.version = JNI_VERSION_1_4;
304
- jvmArgs.ignoreUnrecognized = JNI_FALSE;
305
-
306
- logMsg("Creating JVM...");
307
- if (createJavaVM(&jvm, &env, &jvmArgs) < 0) {
308
- logErr(false, true, "JVM creation failed");
309
- return false;
310
- }
311
- logMsg("JVM created.");
312
- return true;
313
- }
314
- typedef jint (CALLBACK *CreateJavaVM)(JavaVM **jvm, JNIEnv **env, void *args);
315
-
316
- HMODULE hDll;
317
- JavaVM *jvm;
318
- JNIEnv *env;
319
- JavaVMOption *jvmOptions;
320
- JvmLauncher *jvmLauncher;
321
- };
322
-
323
- Jvm jvm(this);
324
- if (!jvm.init(options)) {
325
- return false;
326
- }
327
-
328
- jclass mainClass = jvm.env->FindClass(mainClassName);
329
- if (!mainClass) {
330
- logErr(false, true, "Cannot find class %s.", mainClassName);
331
- return false;
332
- }
333
-
334
- jmethodID mainMethod = jvm.env->GetStaticMethodID(mainClass, "main", "([Ljava/lang/String;)V");
335
- if (!mainMethod) {
336
- logErr(false, true, "Cannot get main method.");
337
- return false;
338
- }
339
-
340
- jclass jclassString = jvm.env->FindClass("java/lang/String");
341
- if (!jclassString) {
342
- logErr(false, true, "Cannot find java/lang/String class");
343
- return false;
344
- }
345
-
346
- jstring jstringArg = jvm.env->NewStringUTF("");
347
- if (!jstringArg) {
348
- logErr(false, true, "NewStringUTF() failed");
349
- return false;
350
- }
351
-
352
- jobjectArray mainArgs = jvm.env->NewObjectArray(args.size(), jclassString, jstringArg);
353
- if (!mainArgs) {
354
- logErr(false, true, "NewObjectArray() failed");
355
- return false;
356
- }
357
- int i = 0;
358
- for (list<string>::iterator it = args.begin(); it != args.end(); ++it, ++i) {
359
- string &arg = *it;
360
- jstring jstringArg = jvm.env->NewStringUTF(arg.c_str());
361
- if (!jstringArg) {
362
- logErr(false, true, "NewStringUTF() failed");
363
- return false;
364
- }
365
- jvm.env->SetObjectArrayElement(mainArgs, i, jstringArg);
366
- }
367
-
368
- jvm.env->CallStaticVoidMethod(mainClass, mainMethod, mainArgs);
369
- return true;
370
- }
371
-
372
-
373
- bool JvmLauncher::startOutProcJvm(const char *mainClassName, std::list<std::string> args, std::list<std::string> options, DWORD *retCode) {
374
- string cmdLine = '\"' + (suppressConsole ? javawExePath : javaExePath) + '\"';
375
- cmdLine.reserve(32*1024);
376
- for (list<string>::iterator it = options.begin(); it != options.end(); ++it) {
377
- cmdLine += " \"";
378
- cmdLine += *it;
379
- cmdLine += "\"";
380
- }
381
-
382
- // mainClass and args
383
- cmdLine += ' ';
384
- cmdLine += mainClassName;
385
- for (list<string>::iterator it = args.begin(); it != args.end(); ++it) {
386
- if (javaClientDllPath.empty() && *it == "-client") {
387
- logMsg("Removing -client option, client java dll not found.");
388
- // remove client parameter, no client java found
389
- continue;
390
- }
391
- cmdLine += " \"";
392
- cmdLine += *it;
393
- cmdLine += "\"";
394
- }
395
-
396
- logMsg("Command line:\n%s", cmdLine.c_str());
397
- if (cmdLine.size() >= 32*1024) {
398
- logErr(false, true, "Command line is too long. Length: %u. Maximum length: %u.", cmdLine.c_str(), 32*1024);
399
- return false;
400
- }
401
-
402
- STARTUPINFO si = {0};
403
- si.cb = sizeof (STARTUPINFO);
404
- PROCESS_INFORMATION pi = {0};
405
-
406
- char cmdLineStr[32*1024] = "";
407
- strcpy(cmdLineStr, cmdLine.c_str());
408
- if (!CreateProcess(NULL, cmdLineStr, NULL, NULL, TRUE, CREATE_SUSPENDED, NULL, NULL, &si, &pi)) {
409
- logErr(true, true, "Failed to create process");
410
- return false;
411
- }
412
-
413
- disableFolderVirtualization(pi.hProcess);
414
- ResumeThread(pi.hThread);
415
- WaitForSingleObject(pi.hProcess, INFINITE);
416
- if (retCode) {
417
- GetExitCodeProcess(pi.hProcess, retCode);
418
- }
419
- CloseHandle(pi.hProcess);
420
- CloseHandle(pi.hThread);
421
- return true;
422
- }
423
-
424
- bool JvmLauncher::findJava(const char *minJavaVersion) {
425
- if (findJava(JDK_KEY, JAVA_JRE_PREFIX, minJavaVersion)) {
426
- return true;
427
- }
428
- if (findJava(JRE_KEY, "", minJavaVersion)) {
429
- return true;
430
- }
431
- javaPath = "";
432
- javaExePath = "";
433
- javaClientDllPath = "";
434
- javaServerDllPath = "";
435
- javaBinPath = "";
436
- return false;
437
- }
438
-
439
- bool JvmLauncher::findJava(const char *javaKey, const char *prefix, const char *minJavaVersion) {
440
- logMsg("JvmLauncher::findJava()\n\tjavaKey: %s\n\tprefix: %s\n\tminJavaVersion: %s", javaKey, prefix, minJavaVersion);
441
- string value;
442
- if (getStringFromRegistry(HKEY_LOCAL_MACHINE, javaKey, CUR_VERSION_NAME, value)) {
443
- if (value >= minJavaVersion) {
444
- string path;
445
- if (getStringFromRegistry(HKEY_LOCAL_MACHINE, (string(javaKey) + "\\" + value).c_str(), JAVA_HOME_NAME, path)) {
446
- if (*path.rbegin() == '\\') {
447
- path.erase(path.length() - 1, 1);
448
- }
449
- return checkJava(path, prefix);
450
- }
451
- }
452
- }
453
- return false;
454
- }
1
+ /*
2
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
+ *
4
+ * Copyright 2009-2012 JRuby Team (www.jruby.org).
5
+ * Copyright 1997-2008 Sun Microsystems, Inc. All rights reserved.
6
+ *
7
+ * The contents of this file are subject to the terms of either the GNU
8
+ * General Public License Version 2 only ("GPL") or the Common
9
+ * Development and Distribution License("CDDL") (collectively, the
10
+ * "License"). You may not use this file except in compliance with the
11
+ * License. You can obtain a copy of the License at
12
+ * http://www.netbeans.org/cddl-gplv2.html
13
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
14
+ * specific language governing permissions and limitations under the
15
+ * License. When distributing the software, include this License Header
16
+ * Notice in each file and include the License file at
17
+ * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
18
+ * particular file as subject to the "Classpath" exception as provided
19
+ * by Sun in the GPL Version 2 section of the License file that
20
+ * accompanied this code. If applicable, add the following below the
21
+ * License Header, with the fields enclosed by brackets [] replaced by
22
+ * your own identifying information:
23
+ * "Portions Copyrighted [year] [name of copyright owner]"
24
+ *
25
+ * Contributor(s):
26
+ *
27
+ * The Original Software is NetBeans. The Initial Developer of the Original
28
+ * Software is Sun Microsystems, Inc. Portions Copyright 1997-2008 Sun
29
+ * Microsystems, Inc. All Rights Reserved.
30
+ *
31
+ * If you wish your version of this file to be governed by only the CDDL
32
+ * or only the GPL Version 2, indicate your decision by adding
33
+ * "[Contributor] elects to include this software in this distribution
34
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
35
+ * single choice of license, a recipient has the option to distribute
36
+ * your version of this file under either the CDDL, the GPL Version 2 or
37
+ * to extend the choice of license to its licensees as provided above.
38
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
39
+ * Version 2 license, then the option applies only if the new code is
40
+ * made subject to such option by the copyright holder.
41
+ *
42
+ * Author: Tomas Holy
43
+ */
44
+
45
+ #include "jvmlauncher.h"
46
+ #include <cassert>
47
+
48
+ using namespace std;
49
+
50
+ const char *JvmLauncher::JDK_KEY = "Software\\JavaSoft\\Java Development Kit";
51
+ const char *JvmLauncher::JRE_KEY = "Software\\JavaSoft\\Java Runtime Environment";
52
+ const char *JvmLauncher::CUR_VERSION_NAME = "CurrentVersion";
53
+ const char *JvmLauncher::JAVA_HOME_NAME = "JavaHome";
54
+ const char *JvmLauncher::JAVA_BIN_DIR = "\\bin";
55
+ const char *JvmLauncher::JAVA_EXE_FILE = "\\bin\\java.exe";
56
+ const char *JvmLauncher::JAVAW_EXE_FILE = "\\bin\\javaw.exe";
57
+ const char *JvmLauncher::JAVA_CLIENT_DLL_FILE = "\\bin\\client\\jvm.dll";
58
+ const char *JvmLauncher::JAVA_SERVER_DLL_FILE = "\\bin\\server\\jvm.dll";
59
+ const char *JvmLauncher::JAVA_JRE_PREFIX = "\\jre";
60
+ const char *JvmLauncher::JNI_CREATEVM_FUNC = "JNI_CreateJavaVM";
61
+
62
+
63
+ JvmLauncher::JvmLauncher()
64
+ : suppressConsole(false) {
65
+ }
66
+
67
+ JvmLauncher::JvmLauncher(const JvmLauncher& orig) {
68
+ }
69
+
70
+ JvmLauncher::~JvmLauncher() {
71
+ }
72
+
73
+ void JvmLauncher::setJavaCmd(const string cmdPath) {
74
+ javaExePath = cmdPath;
75
+ javaPath = "";
76
+ javawExePath = javaPath;
77
+ javaClientDllPath = javaPath;
78
+ javaServerDllPath = javaPath;
79
+ }
80
+
81
+ bool JvmLauncher::checkJava(std::string &path, const char *prefix) {
82
+ assert(prefix);
83
+ logMsg("checkJava('%s', '%s')", path.c_str(), prefix);
84
+
85
+ if (*path.rbegin() == '\\') {
86
+ path.erase(path.length() - 1, 1);
87
+ }
88
+ javaExePath = path + prefix + JAVA_EXE_FILE;
89
+ javawExePath = path + prefix + JAVAW_EXE_FILE;
90
+ javaClientDllPath = path + prefix + JAVA_CLIENT_DLL_FILE;
91
+ javaServerDllPath = path + prefix + JAVA_SERVER_DLL_FILE;
92
+ if (!fileExists(javaClientDllPath.c_str())) {
93
+ javaClientDllPath = "";
94
+ }
95
+ if (!fileExists(javaServerDllPath.c_str())) {
96
+ javaServerDllPath = "";
97
+ }
98
+ javaBinPath = path + prefix + JAVA_BIN_DIR;
99
+ if (fileExists(javaExePath.c_str()) || !javaClientDllPath.empty() || !javaServerDllPath.empty()) {
100
+ if (!fileExists(javawExePath.c_str())) {
101
+ logMsg("javaw.exe not exists, forcing java.exe");
102
+ javawExePath = javaExePath;
103
+ }
104
+ javaPath = path;
105
+ return true;
106
+ }
107
+
108
+ javaBinPath.clear();
109
+ javaExePath.clear();
110
+ javawExePath.clear();
111
+ javaClientDllPath.clear();
112
+ javaServerDllPath.clear();
113
+ return false;
114
+ }
115
+
116
+ bool JvmLauncher::initialize(const char *javaPathOrMinVersion) {
117
+ logMsg("JvmLauncher::initialize()\n\tjavaPathOrMinVersion: %s", javaPathOrMinVersion);
118
+ assert(javaPathOrMinVersion);
119
+
120
+ std::string pathOrVersion(javaPathOrMinVersion);
121
+
122
+ if (isVersionString(javaPathOrMinVersion)) {
123
+ return findJava(javaPathOrMinVersion);
124
+ } else {
125
+ return (checkJava(pathOrVersion, JAVA_JRE_PREFIX) || checkJava(pathOrVersion, ""));
126
+ }
127
+ }
128
+
129
+ bool JvmLauncher::getJavaPath(string &path) {
130
+ logMsg("JvmLauncher::getJavaPath()");
131
+ path = javaPath;
132
+ return !javaPath.empty();
133
+ }
134
+
135
+ bool JvmLauncher::start(const char *mainClassName, list<string> args, list<string> options, bool &separateProcess, DWORD *retCode) {
136
+ assert(mainClassName);
137
+ logMsg("JvmLauncher::start()\n\tmainClassName: %s\n\tseparateProcess: %s",
138
+ mainClassName, separateProcess ? "true" : "false");
139
+ logMsg(" args:");
140
+ for (list<string>::iterator it = args.begin(); it != args.end(); ++it) {
141
+ logMsg("\t%s", it->c_str());
142
+ }
143
+ logMsg(" options:");
144
+ for (list<string>::iterator it = options.begin(); it != options.end(); ++it) {
145
+ logMsg("\t%s", it->c_str());
146
+ }
147
+
148
+ if (javaExePath.empty() && javaClientDllPath.empty() && javaServerDllPath.empty()) {
149
+ // try to find out any java installed (check the registry)
150
+ if (!initialize("")) {
151
+ return false;
152
+ }
153
+ }
154
+
155
+ if (!separateProcess) {
156
+ // both client/server found, check option which should be used
157
+ if (!javaClientDllPath.empty() && !javaServerDllPath.empty()) {
158
+ // By default, load client VM. Load server VM only if explicitly asked.
159
+ javaDllPath = findServerOption(options) ? javaServerDllPath: javaClientDllPath;
160
+ } else {
161
+ javaDllPath = javaClientDllPath.empty() ? javaServerDllPath : javaClientDllPath;
162
+ }
163
+
164
+ // it is necessary to absolutize dll path because current dir has to be
165
+ // temporarily changed for dll loading
166
+ char absoluteJavaDllPath[MAX_PATH] = "";
167
+ strncpy(absoluteJavaDllPath, javaDllPath.c_str(), MAX_PATH);
168
+ normalizePath(absoluteJavaDllPath, MAX_PATH);
169
+ javaDllPath = absoluteJavaDllPath;
170
+
171
+ logMsg("Java DLL path: %s", javaDllPath.c_str());
172
+ if (!canLoadJavaDll()) {
173
+ logMsg("Falling back to running Java in a separate process; DLL cannot be loaded (64-bit DLL?).");
174
+ separateProcess = true;
175
+ }
176
+ }
177
+
178
+ return separateProcess ? startOutProcJvm(mainClassName, args, options, retCode)
179
+ : startInProcJvm(mainClassName, args, options);
180
+ }
181
+
182
+ bool JvmLauncher::findServerOption(list<string> &options) {
183
+ for (list<string>::iterator it = options.begin(); it != options.end(); ++it) {
184
+ if (*it == "-server") {
185
+ return true;
186
+ }
187
+ }
188
+ return false;
189
+ }
190
+
191
+ bool JvmLauncher::canLoadJavaDll() {
192
+ // be prepared for stupid placement of msvcr71.dll in java installation
193
+ // (in java 1.6/1.7 jvm.dll is dynamically linked to msvcr71.dll which si placed
194
+ // in bin directory)
195
+ PrepareDllPath prepare(javaBinPath.c_str());
196
+ HMODULE hDll = LoadLibrary(javaDllPath.c_str());
197
+ if (hDll) {
198
+ FreeLibrary(hDll);
199
+ return true;
200
+ }
201
+ logErr(true, false, "Cannot load %s.", javaDllPath.c_str());
202
+ return false;
203
+ }
204
+
205
+ bool JvmLauncher::isVersionString(const char *str) {
206
+ char *end = 0;
207
+ strtod(str, &end);
208
+ return *end == '\0';
209
+ }
210
+
211
+ bool JvmLauncher::startInProcJvm(const char *mainClassName, std::list<std::string> mbcs_args, std::list<std::string> mbcs_options) {
212
+
213
+ std::list<std::string> args;
214
+ for (std::list<std::string>::iterator it = mbcs_args.begin(); it != mbcs_args.end(); ++it) {
215
+ wchar_t wstr[2048];
216
+ UINT cp = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
217
+ MultiByteToWideChar(cp, 0, it->c_str(), -1, wstr, sizeof(wstr) / sizeof(wchar_t));
218
+ int mb_size = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL);
219
+ char *mbstr = (char*)malloc(mb_size);
220
+ WideCharToMultiByte(CP_UTF8, 0, wstr, -1, mbstr, mb_size, NULL, NULL);
221
+ args.push_back(mbstr);
222
+ }
223
+
224
+ std::list<std::string> options;
225
+ for (std::list<std::string>::iterator it = mbcs_options.begin(); it != mbcs_options.end(); ++it) {
226
+ wchar_t wstr[2048];
227
+ UINT cp = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
228
+ MultiByteToWideChar(cp, 0, it->c_str(), -1, wstr, sizeof(wstr) / sizeof(wchar_t));
229
+ int mb_size = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL);
230
+ char *mbstr = (char*)malloc(mb_size);
231
+ WideCharToMultiByte(CP_UTF8, 0, wstr, -1, mbstr, mb_size, NULL, NULL);
232
+ options.push_back(mbstr);
233
+ }
234
+
235
+ class Jvm {
236
+ public:
237
+
238
+ Jvm(JvmLauncher *jvmLauncher)
239
+ : hDll(0)
240
+ , jvm(0)
241
+ , env(0)
242
+ , jvmOptions(0)
243
+ , jvmLauncher(jvmLauncher)
244
+ {
245
+ }
246
+
247
+ ~Jvm() {
248
+ if (env && env->ExceptionOccurred()) {
249
+ env->ExceptionDescribe();
250
+ }
251
+
252
+ if (jvm) {
253
+ logMsg("Destroying JVM");
254
+ jvm->DestroyJavaVM();
255
+ }
256
+
257
+ if (jvmOptions) {
258
+ delete[] jvmOptions;
259
+ }
260
+
261
+ if (hDll) {
262
+ FreeLibrary(hDll);
263
+ }
264
+ }
265
+
266
+ bool init(list<string> options) {
267
+ logMsg("JvmLauncher::Jvm::init()");
268
+ logMsg("LoadLibrary(\"%s\")", jvmLauncher->javaDllPath.c_str());
269
+ {
270
+ PrepareDllPath prepare(jvmLauncher->javaBinPath.c_str());
271
+ hDll = LoadLibrary(jvmLauncher->javaDllPath.c_str());
272
+ if (!hDll) {
273
+ logErr(true, true, "Cannot load %s.", jvmLauncher->javaDllPath.c_str());
274
+ return false;
275
+ }
276
+ }
277
+
278
+ CreateJavaVM createJavaVM = (CreateJavaVM) GetProcAddress(hDll, JNI_CREATEVM_FUNC);
279
+ if (!createJavaVM) {
280
+ logErr(true, true, "GetProcAddress for %s failed.", JNI_CREATEVM_FUNC);
281
+ return false;
282
+ }
283
+
284
+ // Explicity remove -server and -client options, they are not
285
+ // needed, since we invoke JVM in-process and already know
286
+ // which DLL to use.
287
+ options.remove("-server");
288
+ options.remove("-client");
289
+
290
+ logMsg("JVM options:");
291
+ jvmOptions = new JavaVMOption[options.size()];
292
+ int i = 0;
293
+ for (list<string>::iterator it = options.begin(); it != options.end(); ++it, ++i) {
294
+ string &option = *it;
295
+ logMsg("\t%s", option.c_str());
296
+ jvmOptions[i].optionString = (char *) option.c_str();
297
+ jvmOptions[i].extraInfo = 0;
298
+ }
299
+
300
+ JavaVMInitArgs jvmArgs;
301
+ jvmArgs.options = jvmOptions;
302
+ jvmArgs.nOptions = options.size();
303
+ jvmArgs.version = JNI_VERSION_1_4;
304
+ jvmArgs.ignoreUnrecognized = JNI_FALSE;
305
+
306
+ logMsg("Creating JVM...");
307
+ if (createJavaVM(&jvm, &env, &jvmArgs) < 0) {
308
+ logErr(false, true, "JVM creation failed");
309
+ return false;
310
+ }
311
+ logMsg("JVM created.");
312
+ return true;
313
+ }
314
+ typedef jint (CALLBACK *CreateJavaVM)(JavaVM **jvm, JNIEnv **env, void *args);
315
+
316
+ HMODULE hDll;
317
+ JavaVM *jvm;
318
+ JNIEnv *env;
319
+ JavaVMOption *jvmOptions;
320
+ JvmLauncher *jvmLauncher;
321
+ };
322
+
323
+ Jvm jvm(this);
324
+ if (!jvm.init(options)) {
325
+ return false;
326
+ }
327
+
328
+ jclass mainClass = jvm.env->FindClass(mainClassName);
329
+ if (!mainClass) {
330
+ logErr(false, true, "Cannot find class %s.", mainClassName);
331
+ return false;
332
+ }
333
+
334
+ jmethodID mainMethod = jvm.env->GetStaticMethodID(mainClass, "main", "([Ljava/lang/String;)V");
335
+ if (!mainMethod) {
336
+ logErr(false, true, "Cannot get main method.");
337
+ return false;
338
+ }
339
+
340
+ jclass jclassString = jvm.env->FindClass("java/lang/String");
341
+ if (!jclassString) {
342
+ logErr(false, true, "Cannot find java/lang/String class");
343
+ return false;
344
+ }
345
+
346
+ jstring jstringArg = jvm.env->NewStringUTF("");
347
+ if (!jstringArg) {
348
+ logErr(false, true, "NewStringUTF() failed");
349
+ return false;
350
+ }
351
+
352
+ jobjectArray mainArgs = jvm.env->NewObjectArray(args.size(), jclassString, jstringArg);
353
+ if (!mainArgs) {
354
+ logErr(false, true, "NewObjectArray() failed");
355
+ return false;
356
+ }
357
+ int i = 0;
358
+ for (list<string>::iterator it = args.begin(); it != args.end(); ++it, ++i) {
359
+ string &arg = *it;
360
+ jstring jstringArg = jvm.env->NewStringUTF(arg.c_str());
361
+ if (!jstringArg) {
362
+ logErr(false, true, "NewStringUTF() failed");
363
+ return false;
364
+ }
365
+ jvm.env->SetObjectArrayElement(mainArgs, i, jstringArg);
366
+ }
367
+
368
+ jvm.env->CallStaticVoidMethod(mainClass, mainMethod, mainArgs);
369
+ return true;
370
+ }
371
+
372
+
373
+ bool JvmLauncher::startOutProcJvm(const char *mainClassName, std::list<std::string> args, std::list<std::string> options, DWORD *retCode) {
374
+ string cmdLine = '\"' + (suppressConsole ? javawExePath : javaExePath) + '\"';
375
+ cmdLine.reserve(32*1024);
376
+ for (list<string>::iterator it = options.begin(); it != options.end(); ++it) {
377
+ cmdLine += " \"";
378
+ cmdLine += *it;
379
+ cmdLine += "\"";
380
+ }
381
+
382
+ // mainClass and args
383
+ cmdLine += ' ';
384
+ cmdLine += mainClassName;
385
+ for (list<string>::iterator it = args.begin(); it != args.end(); ++it) {
386
+ if (javaClientDllPath.empty() && *it == "-client") {
387
+ logMsg("Removing -client option, client java dll not found.");
388
+ // remove client parameter, no client java found
389
+ continue;
390
+ }
391
+ cmdLine += " \"";
392
+ cmdLine += *it;
393
+ cmdLine += "\"";
394
+ }
395
+
396
+ logMsg("Command line:\n%s", cmdLine.c_str());
397
+ if (cmdLine.size() >= 32*1024) {
398
+ logErr(false, true, "Command line is too long. Length: %u. Maximum length: %u.", cmdLine.c_str(), 32*1024);
399
+ return false;
400
+ }
401
+
402
+ STARTUPINFO si = {0};
403
+ si.cb = sizeof (STARTUPINFO);
404
+ PROCESS_INFORMATION pi = {0};
405
+
406
+ char cmdLineStr[32*1024] = "";
407
+ strcpy(cmdLineStr, cmdLine.c_str());
408
+ if (!CreateProcess(NULL, cmdLineStr, NULL, NULL, TRUE, CREATE_SUSPENDED, NULL, NULL, &si, &pi)) {
409
+ logErr(true, true, "Failed to create process");
410
+ return false;
411
+ }
412
+
413
+ // disable Ctrl-C handling in the parent process
414
+ if (!SetConsoleCtrlHandler(NULL, TRUE)) {
415
+ logErr(true, true, "Failed to disable Ctrl-C handling; Ctrl-C may behave oddly: %d", GetLastError());
416
+ }
417
+
418
+ disableFolderVirtualization(pi.hProcess);
419
+ ResumeThread(pi.hThread);
420
+ WaitForSingleObject(pi.hProcess, INFINITE);
421
+ if (retCode) {
422
+ GetExitCodeProcess(pi.hProcess, retCode);
423
+ }
424
+ CloseHandle(pi.hProcess);
425
+ CloseHandle(pi.hThread);
426
+ return true;
427
+ }
428
+
429
+ bool JvmLauncher::findJava(const char *minJavaVersion) {
430
+ if (findJava(JDK_KEY, JAVA_JRE_PREFIX, minJavaVersion)) {
431
+ return true;
432
+ }
433
+ if (findJava(JRE_KEY, "", minJavaVersion)) {
434
+ return true;
435
+ }
436
+ javaPath = "";
437
+ javaExePath = "";
438
+ javaClientDllPath = "";
439
+ javaServerDllPath = "";
440
+ javaBinPath = "";
441
+ return false;
442
+ }
443
+
444
+ bool JvmLauncher::findJava(const char *javaKey, const char *prefix, const char *minJavaVersion) {
445
+ logMsg("JvmLauncher::findJava()\n\tjavaKey: %s\n\tprefix: %s\n\tminJavaVersion: %s", javaKey, prefix, minJavaVersion);
446
+ string value;
447
+ if (getStringFromRegistry(HKEY_LOCAL_MACHINE, javaKey, CUR_VERSION_NAME, value)) {
448
+ if (value >= minJavaVersion) {
449
+ string path;
450
+ if (getStringFromRegistry(HKEY_LOCAL_MACHINE, (string(javaKey) + "\\" + value).c_str(), JAVA_HOME_NAME, path)) {
451
+ if (*path.rbegin() == '\\') {
452
+ path.erase(path.length() - 1, 1);
453
+ }
454
+ return checkJava(path, prefix);
455
+ }
456
+ }
457
+ }
458
+ return false;
459
+ }