Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Niefer2006-11-14 17:17:25 -0500
committerAndrew Niefer2006-11-14 17:17:25 -0500
commit4cabfd14740017f033c3509f59f967bb6c0aa231 (patch)
tree8067250eabfcaf85883a3f984402b86d3fb5a1f4
parent9f5bcde1dc3cbdacb8e674b2612f5740855a6b14 (diff)
downloadrt.equinox.framework-4cabfd14740017f033c3509f59f967bb6c0aa231.tar.gz
rt.equinox.framework-4cabfd14740017f033c3509f59f967bb6c0aa231.tar.xz
rt.equinox.framework-4cabfd14740017f033c3509f59f967bb6c0aa231.zip
finding startup.jar, setting up vmArgs vs progArgs
-rw-r--r--bundles/org.eclipse.equinox.launcher/.cdtproject15
-rw-r--r--bundles/org.eclipse.equinox.launcher/library/eclipse.c270
-rw-r--r--bundles/org.eclipse.equinox.launcher/library/eclipseJNI.c39
-rw-r--r--bundles/org.eclipse.equinox.launcher/library/eclipseJNI.h12
-rw-r--r--bundles/org.eclipse.equinox.launcher/library/eclipseOS.h18
-rw-r--r--bundles/org.eclipse.equinox.launcher/library/win32/eclipseWin.c199
-rw-r--r--bundles/org.eclipse.equinox.launcher/library/win32/make_mingw.mak4
7 files changed, 324 insertions, 233 deletions
diff --git a/bundles/org.eclipse.equinox.launcher/.cdtproject b/bundles/org.eclipse.equinox.launcher/.cdtproject
index da9d75c21..1f808cd5f 100644
--- a/bundles/org.eclipse.equinox.launcher/.cdtproject
+++ b/bundles/org.eclipse.equinox.launcher/.cdtproject
@@ -58,20 +58,27 @@
</item>
<item id="org.eclipse.cdt.make.core.buildtargets">
<buildTargets>
-<target name="win32-mingw-all" path="library" targetID="org.eclipse.cdt.make.MakeTargetBuilder">
+<target name="all-win32" path="library/win32" targetID="org.eclipse.cdt.make.MakeTargetBuilder">
<buildCommand>make</buildCommand>
-<buildArguments>-C win32 -f make_mingw.mak</buildArguments>
+<buildArguments>-f make_mingw.mak</buildArguments>
<buildTarget>all</buildTarget>
<stopOnError>false</stopOnError>
<useDefaultCommand>false</useDefaultCommand>
</target>
-<target name="win32-clean" path="library" targetID="org.eclipse.cdt.make.MakeTargetBuilder">
+<target name="clean" path="library/win32" targetID="org.eclipse.cdt.make.MakeTargetBuilder">
<buildCommand>make</buildCommand>
-<buildArguments>-C win32 -fmake_mingw.mak</buildArguments>
+<buildArguments>-f make_mingw.mak</buildArguments>
<buildTarget>clean</buildTarget>
<stopOnError>false</stopOnError>
<useDefaultCommand>false</useDefaultCommand>
</target>
+<target name="all-linux" path="library/gtk" targetID="org.eclipse.cdt.make.MakeTargetBuilder">
+<buildCommand>make</buildCommand>
+<buildArguments>-f make_linux.mak</buildArguments>
+<buildTarget>all</buildTarget>
+<stopOnError>false</stopOnError>
+<useDefaultCommand>false</useDefaultCommand>
+</target>
</buildTargets>
</item>
</data>
diff --git a/bundles/org.eclipse.equinox.launcher/library/eclipse.c b/bundles/org.eclipse.equinox.launcher/library/eclipse.c
index 63df06b97..82d65364d 100644
--- a/bundles/org.eclipse.equinox.launcher/library/eclipse.c
+++ b/bundles/org.eclipse.equinox.launcher/library/eclipse.c
@@ -179,6 +179,7 @@
*/
#include "eclipseOS.h"
+#include "eclipseJNI.h"
#include "eclipseConfig.h"
#ifdef _WIN32
@@ -196,6 +197,7 @@
#include <sys/stat.h>
#include <errno.h>
#include <ctype.h>
+#include <dirent.h>
#define MAX_PATH_LENGTH 2000
#define MAX_SHARED_LENGTH (16 * 1024)
@@ -232,7 +234,10 @@ static _TCHAR* homeMsg =
_T_ECLIPSE("The %s executable launcher was unable to locate its \n\
companion startup.jar file (in the same directory as the executable).");
-#define DEFAULT_STARTUP _T_ECLIPSE("startup.jar")
+#define DEFAULT_EQUINOX_STARTUP _T_ECLIPSE("org.eclipse.equinox.startup")
+#define DEFAULT_STARTUP _T_ECLIPSE("startup.jar")
+#define CLASSPATH_PREFIX _T_ECLIPSE("-Djava.class.path=")
+
/* Define constants for the options recognized by the launcher. */
#define CONSOLE _T_ECLIPSE("-console")
@@ -256,7 +261,7 @@ static int noSplash = 0; /* True: do not show splash win */
static _TCHAR* osArg = _T_ECLIPSE(DEFAULT_OS);
static _TCHAR* osArchArg = _T_ECLIPSE(DEFAULT_OS_ARCH);
static _TCHAR* showSplashArg = NULL; /* showsplash data (main launcher window) */
-static _TCHAR * startupArg = DEFAULT_STARTUP; /* path of the startup.jar the user wants to run relative to the program path */
+static _TCHAR * startupArg = NULL; /* path of the startup.jar the user wants to run relative to the program path */
static _TCHAR* vmName = NULL; /* Java VM that the user wants to run */
static _TCHAR* wsArg = _T_ECLIPSE(DEFAULT_WS); /* the SWT supported GUI to be used */
static _TCHAR* name = NULL; /* program name */
@@ -289,20 +294,23 @@ static int configArgc = 0;
static _TCHAR** configArgv = NULL;
/* Define the required VM arguments (all platforms). */
-static _TCHAR* jar = _T_ECLIPSE("-jar");
-static _TCHAR** reqVMarg[] = { &jar, &jarFile, NULL };
+static _TCHAR* cp = NULL;
+static _TCHAR** reqVMarg[] = { &cp, NULL };
/* Local methods */
static int createUserArgs(int configArgc, _TCHAR **configArgv, int *argc, _TCHAR ***argv);
static void parseArgs( int* argc, _TCHAR* argv[] );
static _TCHAR** parseArgList( _TCHAR *data );
static void freeArgList( _TCHAR** data );
-static _TCHAR** getVMCommand( int argc, _TCHAR* argv[] );
+static void getVMCommand( int argc, _TCHAR* argv[], _TCHAR **vmArgv[], _TCHAR **progArgv[] );
_TCHAR* findCommand( _TCHAR* command );
static _TCHAR* formatVmCommandMsg( _TCHAR* args[] );
_TCHAR* getProgramDir();
static _TCHAR* getDefaultOfficialName();
+static _TCHAR* findStartupJar();
+static char* findFile(char* path, char* prefix);
+
#ifdef _WIN32
#ifdef UNICODE
extern int main(int, char**);
@@ -348,10 +356,10 @@ int main( int argc, _TCHAR* argv[] )
_TCHAR** vmCommand = NULL;
_TCHAR** vmCommandList = NULL;
_TCHAR** vmCommandArgs = NULL;
+ _TCHAR** progCommandArgs = NULL;
_TCHAR* vmCommandMsg = NULL;
_TCHAR* errorMsg;
int exitCode;
- struct _stat stats;
setlocale(LC_ALL, "");
@@ -454,6 +462,7 @@ int main( int argc, _TCHAR* argv[] )
/* Either verify the VM specified by the user or
attempt to find the VM in the user's PATH. */
javaVM = findCommand( vmName );
+ javaVM = findVMLibrary( javaVM );
/* If the VM was not found, display a message and exit. */
if (javaVM == NULL)
@@ -467,29 +476,21 @@ int main( int argc, _TCHAR* argv[] )
}
}
- /* Construct the absolute name of the startup jar */
- jarFile = malloc( (_tcslen( programDir ) + _tcslen( startupArg ) + 1) * sizeof( _TCHAR ) );
- jarFile = _tcscpy( jarFile, programDir );
- jarFile = _tcscat( jarFile, startupArg );
-
- /* If the file does not exist, treat the argument as an absolute path */
- if (_tstat( jarFile, &stats ) != 0)
- {
- free( jarFile );
- jarFile = malloc( (_tcslen( startupArg ) + 1) * sizeof( _TCHAR ) );
- jarFile = _tcscpy( jarFile, startupArg );
- }
-
+ jarFile = findStartupJar();
+ cp = malloc((_tcslen(CLASSPATH_PREFIX) + _tcslen(jarFile)) * sizeof(_TCHAR));
+ cp = _tcscpy(cp, CLASSPATH_PREFIX);
+ _tcscat(cp, jarFile);
+
/* Get the command to start the Java VM. */
- vmCommandArgs = getVMCommand( argc, argv );
-
+ getVMCommand( argc, argv, &vmCommandArgs, &progCommandArgs );
+
/* While the Java VM should be restarted */
vmCommand = vmCommandArgs;
while (vmCommand != NULL)
{
vmCommandMsg = formatVmCommandMsg( vmCommand );
if (debug) _tprintf( goVMMsg, vmCommandMsg );
- exitCode = startJavaVM( vmCommand );
+ exitCode = startJavaVM(javaVM, vmCommandArgs, progCommandArgs );
switch( exitCode ) {
case 0:
vmCommand = NULL;
@@ -557,6 +558,96 @@ int main( int argc, _TCHAR* argv[] )
return 0;
}
+static _TCHAR* findStartupJar(){
+ _TCHAR * file;
+ struct _stat stats;
+
+ if( startupArg != NULL ) {
+ /* startup jar was specified on the command line */
+
+ /* Construct the absolute name of the startup jar */
+ file = malloc( (_tcslen( programDir ) + _tcslen( startupArg ) + 1) * sizeof( _TCHAR ) );
+ file = _tcscpy( file, programDir );
+ file = _tcscat( file, startupArg );
+
+
+ /* If the file does not exist, treat the argument as an absolute path */
+ if (_tstat( file, &stats ) != 0)
+ {
+ free( file );
+ file = malloc( (_tcslen( startupArg ) + 1) * sizeof( _TCHAR ) );
+ file = _tcscpy( file, startupArg );
+ }
+ return file;
+ }
+
+ /* TODO Need to resolve _TCHAR vs char and programDir vs workingDir */
+ char * plugins = "plugins";
+ char * path = getcwd(NULL, 0);
+ int pathLength = strlen(path);
+ char * fullPath = malloc( (pathLength + 1 + strlen(plugins)) * sizeof(char));
+ strcpy(fullPath, path);
+ fullPath[pathLength] = dirSeparator;
+ fullPath[pathLength + 1] = 0;
+ strcat(fullPath, plugins);
+
+ /* equinox startup jar? */
+ file = findFile(fullPath, "org.eclipse.equinox.startup");
+ if(file != NULL)
+ return file;
+
+ file = malloc( (_tcslen( DEFAULT_STARTUP ) + 1) * sizeof( _TCHAR ) );
+ file = _tcscpy( file, DEFAULT_STARTUP );
+ return file;
+}
+
+/*
+ * Looks for files of the form /path/prefix_version.<extension> and returns the full path to
+ * the file with the largest version number
+ */
+static char* findFile( char* path, char* prefix) {
+ struct stat stats;
+ struct dirent *file;
+ DIR *dir;
+ int prefixLength;
+ char * candidate = NULL;
+
+ /* does path exist? */
+ if( stat(path, &stats) != 0 )
+ return NULL;
+
+ dir = opendir(path);
+ if(dir == NULL)
+ return NULL; /* can't open dir */
+
+ prefixLength = strlen(prefix);
+ while((file = readdir(dir)) != NULL) {
+ if(strncmp( file->d_name, prefix, prefixLength) == 0) {
+ if(candidate == NULL)
+ candidate = strdup(file->d_name);
+ else {
+ /* compare, take the highest version */
+ if( strcmp(candidate, file->d_name) < 0) {
+ free(candidate);
+ candidate = strdup(file->d_name);
+ }
+ }
+ }
+ }
+ closedir(dir);
+
+ if(candidate != NULL) {
+ int pathLength = strlen(path);
+ char * result = malloc((pathLength + 1 + strlen(candidate)) * sizeof(char));
+ strcpy(result, path);
+ result[pathLength] = dirSeparator;
+ result[pathLength + 1] = 0;
+ strcat(result, candidate);
+ free(candidate);
+ return result;
+ }
+ return NULL;
+}
/*
* Parse arguments of the command.
*/
@@ -826,113 +917,104 @@ _TCHAR* findCommand( _TCHAR* command )
* Some of the arguments returned by this function were
* passed directly from the main( argv ) array so they
* should not be deallocated.
+ *
+ * Arguments are split into 2: vm arguments and program arguments
*/
-static _TCHAR** getVMCommand( int argc, _TCHAR* argv[] )
+static void getVMCommand( int argc, _TCHAR* argv[], _TCHAR **vmArgv[], _TCHAR **progArgv[] )
{
- _TCHAR** defVMarg;
- int nDefVMarg = 0;
+ _TCHAR** vmArg;
int nReqVMarg = 0;
- int nUserVMarg = 0;
- int totalArgs;
- _TCHAR** execArg;
+ int nVMarg = 0;
+ int totalVMArgs;
+ int totalProgArgs;
int src;
int dst;
- /* Calculate the number of user VM arguments. */
- if (userVMarg != NULL)
- {
- while (userVMarg[ nUserVMarg ] != NULL)
- nUserVMarg++;
- }
-
- /* Calculate the number of default VM arguments. */
- defVMarg = getArgVM( javaVM );
- while (defVMarg[ nDefVMarg ] != NULL)
- nDefVMarg++;
+ /* If the user specified "-vmargs", add them instead of the default VM args. */
+ vmArg = (userVMarg != NULL) ? userVMarg : getArgVM( javaVM );
+
+ /* Calculate the number of VM arguments. */
+ while (vmArg[ nVMarg ] != NULL)
+ nVMarg++;
/* Calculate the number of required VM arguments. */
while (reqVMarg[ nReqVMarg ] != NULL)
nReqVMarg++;
- /* Allocate the arg list for the exec call.
- * (VM + userVMargs + defaultVMargs + requiredVMargs + OS <os> + WS <ws> + ARCH <arch> + LAUNCHER <launcher> + NAME <officialName> +
- * + SHOWSPLASH <cmd> + argv[] + VM + <vm> + VMARGS + userVMargs + defaultVMargs + requiredVMargs
- * + NULL)
- */
- totalArgs = 1 + nUserVMarg + nDefVMarg + nReqVMarg + 2 + 2 + 2 + 2 + 2 + 2 + argc + 2 + 1 + nUserVMarg + nDefVMarg + nReqVMarg + 1;
- execArg = malloc( totalArgs * sizeof( _TCHAR* ) );
- dst = 0;
- execArg[ dst++ ] = javaVM;
-
- /* If the user specified "-vmargs", add them instead of the default VM args. */
- if (userVMarg != NULL)
- {
- for (src = 0; src < nUserVMarg; src++)
- execArg[ dst++ ] = userVMarg[ src ];
- }
- else
- {
- for (src = 0; src < nDefVMarg; src++)
- execArg[ dst++ ] = defVMarg[ src ];
+ /* VM argument list */
+ totalVMArgs = nVMarg + nReqVMarg + 1;
+ *vmArgv = malloc( totalVMArgs * sizeof(_TCHAR*) );
+
+ dst = 0;
+ for (src = 0; src < nVMarg; src++){
+ /*if the user specified a classpath, skip it */
+ if(_tcscmp(vmArg[src], cp) == 0){
+ src++;
+ continue;
+ }
+ (*vmArgv)[ dst++ ] = vmArg[ src ];
}
-
- /* For each required VM arg */
+
+ /* For each required VM arg */
for (src = 0; src < nReqVMarg; src++)
- execArg[ dst++ ] = *(reqVMarg[ src ]);
-
- /* Append the required options. */
- execArg[ dst++ ] = OS;
- execArg[ dst++ ] = osArg;
- execArg[ dst++ ] = WS;
- execArg[ dst++ ] = wsArg;
+ (*vmArgv)[ dst++ ] = *(reqVMarg[ src ]);
+
+ (*vmArgv)[dst] = NULL;
+
+ /* Program arguments */
+ /* OS <os> + WS <ws> + ARCH <arch> + LAUNCHER <launcher> + NAME <officialName> +
+ * + SHOWSPLASH <cmd> + argv[] + VM + <vm> + VMARGS + vmArg + requiredVMargs
+ * + NULL)
+ */
+ totalProgArgs = 2 + 2 + 2 + 2 + 2 + 2 + argc + 2 + 1 + nVMarg + nReqVMarg + 1;
+ *progArgv = malloc( totalProgArgs * sizeof( _TCHAR* ) );
+ dst = 0;
+
+ /* Append the required options. */
+ (*progArgv)[ dst++ ] = OS;
+ (*progArgv)[ dst++ ] = osArg;
+ (*progArgv)[ dst++ ] = WS;
+ (*progArgv)[ dst++ ] = wsArg;
if (_tcslen(osArchArg) > 0) {
- execArg[ dst++ ] = OSARCH;
- execArg[ dst++ ] = osArchArg;
+ (*progArgv)[ dst++ ] = OSARCH;
+ (*progArgv)[ dst++ ] = osArchArg;
}
/* Append the launcher command */
- execArg[ dst++ ] = LAUNCHER;
- execArg[ dst++ ] = program;
+ (*progArgv)[ dst++ ] = LAUNCHER;
+ (*progArgv)[ dst++ ] = program;
/* Append the name command */
- execArg[ dst++ ] = NAME;
- execArg[ dst++ ] = officialName;
+ (*progArgv)[ dst++ ] = NAME;
+ (*progArgv)[ dst++ ] = officialName;
/* Append the show splash window command, if defined. */
if (!noSplash)
{
- execArg[ dst++ ] = SHOWSPLASH;
- execArg[ dst++ ] = splashTimeout;
+ (*progArgv)[ dst++ ] = SHOWSPLASH;
+ (*progArgv)[ dst++ ] = splashTimeout;
}
/* Append the remaining user defined arguments. */
for (src = 1; src < argc; src++)
{
- execArg[ dst++ ] = argv[ src ];
+ (*progArgv)[ dst++ ] = argv[ src ];
}
/* Append VM and VMARGS to be able to relaunch using exit data. */
- execArg[ dst++ ] = VM;
- execArg[ dst++ ] = javaVM;
- execArg[ dst++ ] = VMARGS;
- /* If the user specified "-vmargs", add them instead of the default VM args. */
- if (userVMarg != NULL)
- {
- for (src = 0; src < nUserVMarg; src++)
- execArg[ dst++ ] = userVMarg[ src ];
- }
- else
- {
- for (src = 0; src < nDefVMarg; src++)
- execArg[ dst++ ] = defVMarg[ src ];
- }
+ (*progArgv)[ dst++ ] = VM;
+ (*progArgv)[ dst++ ] = javaVM;
+ (*progArgv)[ dst++ ] = VMARGS;
+
+ for (src = 0; src < nVMarg; src++)
+ (*progArgv)[ dst++ ] = vmArg[ src ];
+
/* For each required VM arg */
for (src = 0; src < nReqVMarg; src++)
- execArg[ dst++ ] = *(reqVMarg[ src ]);
+ (*progArgv)[ dst++ ] = *(reqVMarg[ src ]);
- execArg[ dst++ ] = NULL;
+ (*progArgv)[ dst++ ] = NULL;
- return execArg;
}
/* Format the JVM start command for error messages
diff --git a/bundles/org.eclipse.equinox.launcher/library/eclipseJNI.c b/bundles/org.eclipse.equinox.launcher/library/eclipseJNI.c
index 342ef9a18..6fd0237af 100644
--- a/bundles/org.eclipse.equinox.launcher/library/eclipseJNI.c
+++ b/bundles/org.eclipse.equinox.launcher/library/eclipseJNI.c
@@ -13,6 +13,9 @@
#include "eclipseOS.h"
#include <stdlib.h>
+
+_TCHAR * exitData = NULL;
+
static JNINativeMethod natives[] = {{"_update_splash", "()V", &update_splash},
{"_get_splash_handle", "()I", &get_splash_handle},
{"_set_exit_data", "(Ljava/lang/String;)V", &set_exit_data}};
@@ -36,18 +39,23 @@ JNIEXPORT jint JNICALL get_splash_handle(JNIEnv * env, jobject obj){
#endif
void setExitData(JNIEnv *env, jstring s){
- _TCHAR * copy = malloc((*env)->GetStringLength(env, s) * sizeof(_TCHAR*));
+ int length = (*env)->GetStringLength(env, s);
+ _TCHAR * copy = malloc(length * sizeof(_TCHAR*));
const _TCHAR * data;
+
#ifdef UNICODE
+ /* TODO need to figure out how to get a unicode version called */
data = (*env)->GetStringChars(env, s, 0);
- _tcscpy( copy, data );
+ _tcsncpy( copy, data, length);
(*env)->ReleaseStringChars(env, s, data);
-#else
+#else
data = (*env)->GetStringUTFChars(env, s, 0);
_tcscpy( copy, data );
(*env)->ReleaseStringUTFChars(env, s, data);
#endif
+ exitData = copy;
}
+
static jstring newJavaString(JNIEnv *env, _TCHAR * str)
{
jstring newString = 0;
@@ -102,8 +110,10 @@ static char *toNarrow(_TCHAR* src)
#endif
}
-int launchJavaVM(_TCHAR *dllPath, _TCHAR* progArgs[], int vmArgc, _TCHAR* vmArgv[] ) {
+int startJavaVM( _TCHAR* libPath, _TCHAR* vmArgs[], _TCHAR* progArgs[] )
+{
int i;
+ int numVMArgs = -1;
int jvmExitCode = 0;
void * jniLibrary;
JNI_createJavaVM createJavaVM;
@@ -112,7 +122,7 @@ int launchJavaVM(_TCHAR *dllPath, _TCHAR* progArgs[], int vmArgc, _TCHAR* vmArgv
JavaVM * jvm;
JNIEnv *env;
- jniLibrary = loadLibrary(dllPath);
+ jniLibrary = loadLibrary(libPath);
if(jniLibrary == NULL) {
return -1; /*error*/
}
@@ -122,23 +132,26 @@ int launchJavaVM(_TCHAR *dllPath, _TCHAR* progArgs[], int vmArgc, _TCHAR* vmArgv
return -1; /*error*/
}
- options = malloc(vmArgc * sizeof(JavaVMOption));
- for(i = 0; i < vmArgc; i++){
- options[i].optionString = toNarrow(vmArgv[i]);
+ /* count the vm args */
+ while(vmArgs[++numVMArgs] != NULL) {}
+
+ options = malloc(numVMArgs * sizeof(JavaVMOption));
+ for(i = 0; i < numVMArgs; i++){
+ options[i].optionString = toNarrow(vmArgs[i]);
options[i].extraInfo = 0;
}
init_args.version = JNI_VERSION_1_2;
init_args.options = options;
- init_args.nOptions = vmArgc;
+ init_args.nOptions = numVMArgs;
init_args.ignoreUnrecognized = JNI_TRUE;
if( createJavaVM(&jvm, &env, &init_args) == 0 ) {
- jclass mainClass = (*env)->FindClass(env, "org/eclipse/core/launcher/Main");
-
+ jclass bridge = (*env)->FindClass(env, "org/eclipse/core/launcher/JNIBridge");
int numNatives = sizeof(natives) / sizeof(natives[0]);
- (*env)->RegisterNatives(env, mainClass, natives, numNatives);
+ (*env)->RegisterNatives(env, bridge, natives, numNatives);
+ jclass mainClass = (*env)->FindClass(env, "org/eclipse/core/launcher/Main");
jmethodID mainConstructor = (*env)->GetMethodID(env, mainClass, "<init>", "()V");
jobject mainObject = (*env)->NewObject(env, mainClass, mainConstructor);
jmethodID runMethod = (*env)->GetMethodID(env, mainClass, "run", "([Ljava/lang/String;)I");
@@ -152,7 +165,7 @@ int launchJavaVM(_TCHAR *dllPath, _TCHAR* progArgs[], int vmArgc, _TCHAR* vmArgv
free(progArgs);
/* toNarrow allocated new strings, free them */
- for(i = 0; i < vmArgc; i++){
+ for(i = 0; i < numVMArgs; i++){
free( options[i].optionString );
}
diff --git a/bundles/org.eclipse.equinox.launcher/library/eclipseJNI.h b/bundles/org.eclipse.equinox.launcher/library/eclipseJNI.h
index e5f1a2c57..b99d1aefe 100644
--- a/bundles/org.eclipse.equinox.launcher/library/eclipseJNI.h
+++ b/bundles/org.eclipse.equinox.launcher/library/eclipseJNI.h
@@ -20,8 +20,11 @@
#define getInvocationFunction getInvocationFunctionW
#define launchJavaVM launchJavaVMW
#define setExitData setExitDataW
+#define startJavaVM startJavaVMW
#endif
+extern _TCHAR * exitData;
+
typedef jint (JNICALL *JNI_createJavaVM)(JavaVM **pvm, JNIEnv **env, void *args);
void setExitData(JNIEnv *env, jstring s);
@@ -50,4 +53,13 @@ extern JNIEXPORT void JNICALL update_splash(JNIEnv *, jobject);
*/
extern JNIEXPORT jint JNICALL get_splash_handle(JNIEnv *, jobject);
+
+/* Start the Java VM and Wait For It to Terminate
+ *
+ * This method is responsible for starting the Java VM and for
+ * detecting its termination. The resulting JVM exit code should
+ * be returned to the main launcher, which will display a message if
+ * the termination was not normal.
+ */
+extern int startJavaVM( _TCHAR* libPath, _TCHAR* vmArgs[], _TCHAR* progArgs[] );
#endif
diff --git a/bundles/org.eclipse.equinox.launcher/library/eclipseOS.h b/bundles/org.eclipse.equinox.launcher/library/eclipseOS.h
index b65d9f0e2..6a5fb3c1d 100644
--- a/bundles/org.eclipse.equinox.launcher/library/eclipseOS.h
+++ b/bundles/org.eclipse.equinox.launcher/library/eclipseOS.h
@@ -25,14 +25,15 @@
#define initWindowSystem initWindowSystemW
#define showSplash showSplashW
#define getArgVM getArgVMW
-#define startJavaVM startJavaVMW
#define findCommand findCommandW
#define getProgramDir getProgramDirW
#define officialName officialNameW
#define exitData exitDataW
+#define vmLibrary vmLibraryW
#define loadLibrary loadLibraryW
#define unloadLibrary unloadLibraryW
#define findSymbol findSymbolW
+#define findVMLibrary findVMLibraryW
#endif
/* Operating System Dependent Information */
@@ -48,6 +49,7 @@ extern _TCHAR* defaultVM; /* name of VM to use normally */
extern _TCHAR* shippedVMDir; /* VM bin directory with separator */
extern _TCHAR* officialName; /* Program official name */
extern _TCHAR* exitData; /* exit data set from Java */
+extern _TCHAR* vmLibrary; /* name of the VM shared library */
/* OS Specific Functions */
@@ -102,17 +104,6 @@ extern int showSplash( _TCHAR* splashId, _TCHAR* featureImage );
*/
extern _TCHAR** getArgVM( _TCHAR *vm );
-
-/* Start the Java VM and Wait For It to Terminate
- *
- * This method is responsible for starting the Java VM and for
- * detecting its termination. The resulting JVM exit code should
- * be returned to the main launcher, which will display a message if
- * the termination was not normal.
- */
-extern int startJavaVM( _TCHAR* args[] );
-
-
/* Load the specified shared library
*/
extern void * loadLibrary( _TCHAR * library );
@@ -125,5 +116,8 @@ extern void unloadLibrary( void * handle );
*/
extern void * findSymbol( void * handle, char * symbol );
+/* Find the vm shared library associated with the given java executable */
+extern _TCHAR * findVMLibrary( _TCHAR * command );
+
#endif /* ECLIPSE_OS_H */
diff --git a/bundles/org.eclipse.equinox.launcher/library/win32/eclipseWin.c b/bundles/org.eclipse.equinox.launcher/library/win32/eclipseWin.c
index 217d43d22..05ced63d5 100644
--- a/bundles/org.eclipse.equinox.launcher/library/win32/eclipseWin.c
+++ b/bundles/org.eclipse.equinox.launcher/library/win32/eclipseWin.c
@@ -18,6 +18,7 @@
#include <stdio.h>
#include <string.h>
#include <errno.h>
+#include <sys/stat.h>
#ifdef __MINGW32__
#include <stdlib.h>
@@ -30,6 +31,7 @@ _TCHAR dirSeparator = _T('\\');
_TCHAR pathSeparator = _T(';');
_TCHAR* consoleVM = _T("java.exe");
_TCHAR* defaultVM = _T("javaw.exe");
+_TCHAR* vmLibrary = _T("jvm.dll");
_TCHAR* shippedVMDir = _T("jre\\bin\\");
/* Define the window system arguments for the Java VM. */
@@ -39,21 +41,23 @@ static _TCHAR* argVM[] = { NULL };
static HWND topWindow = 0;
static WNDPROC oldProc;
-/* Define local variables for running the JVM and detecting its exit. */
-static int jvmProcess = 0;
-static int jvmExitCode = 0;
-static int jvmExitTimeout = 100;
-static int jvmExitTimerId = 99;
+/* define default locations in which to find the jvm shared library
+ * these are paths relative to the java exe, the shared library is
+ * for example jvmLocations[0] + dirSeparator + vmLibrary */
+#define MAX_LOCATION_LENGTH 10 /* none of the jvmLocations strings should be longer than this */
+static const _TCHAR* jvmLocations [] = { _T("j9vm"),
+ _T("client"),
+ _T("server"),
+ _T("classic"),
+ NULL };
/* Define local variables for handling the splash window and its image. */
static int splashTimerId = 88;
/* Local functions */
-static void CALLBACK detectJvmExit( HWND hwnd, UINT uMsg, UINT id, DWORD dwTime );
static void CALLBACK splashTimeout( HWND hwnd, UINT uMsg, UINT id, DWORD dwTime );
static LRESULT WINAPI WndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
-
/* Display a Message */
void displayMessage( _TCHAR* title, _TCHAR* message )
{
@@ -158,109 +162,8 @@ _TCHAR** getArgVM( _TCHAR *vm )
return argVM;
}
-
-/* Start the Java VM
- *
- * This method is called to start the Java virtual machine and to wait until it
- * terminates. The function returns the exit code from the JVM.
- */
-int startJavaVM( _TCHAR* args[] )
-{
- MSG msg;
- int index, length;
- _TCHAR *commandLine, *ch, *space;
-
- /*
- * Build the command line. Any argument with spaces must be in
- * double quotes in the command line.
- */
- length = 0;
- for (index = 0; args[index] != NULL; index++)
- {
- /* String length plus space character */
- length += _tcslen( args[ index ] ) + 1;
- /* Quotes */
- if (_tcschr( args[ index ], _T(' ') ) != NULL) length += 2;
- }
- commandLine = ch = malloc ( (length + 1) * sizeof(_TCHAR) );
- for (index = 0; args[index] != NULL; index++)
- {
- space = _tcschr( args[ index ], _T(' '));
- if (space != NULL) *ch++ = _T('\"');
- _tcscpy( ch, args[index] );
- ch += _tcslen( args[index] );
- if (space != NULL) *ch++ = _T('\"');
- *ch++ = _T(' ');
- }
- *ch = _T('\0');
-
- /*
- * Start the Java virtual machine. Use CreateProcess() instead of spawnv()
- * otherwise the arguments cannot be freed since spawnv() segments fault.
- */
- {
- STARTUPINFO si;
- PROCESS_INFORMATION pi;
- GetStartupInfo(&si);
- if (CreateProcess(NULL, commandLine, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) {
- CloseHandle( pi.hThread );
- jvmProcess = (int)pi.hProcess;
- }
- }
-
- free( commandLine );
-
- /* If the child process (JVM) would not start */
- if (jvmProcess == -1)
- {
- /* Return the error number. */
- jvmExitCode = errno;
- jvmProcess = 0;
- }
-
- /* else */
- else
- {
- /* Set a timer to detect JVM process termination. */
- SetTimer( topWindow, jvmExitTimerId, jvmExitTimeout, detectJvmExit );
-
- /* Process messages until the JVM terminates.
- This launcher process must continue to process events until the JVM exits
- or else Windows 2K will hang if the desktop properties (e.g., background) are
- changed by the user. Windows does a SendMessage() to every top level window
- process, which blocks the caller until the process responds. */
- while (jvmProcess != 0)
- {
- GetMessage( &msg, NULL, 0, 0 );
- TranslateMessage( &msg );
- DispatchMessage( &msg );
- }
-
- /* Kill the timer. */
- KillTimer( topWindow, jvmExitTimerId );
- }
-
- /* Return the exit code from the JVM. */
- return jvmExitCode;
-}
-
/* Local functions */
-/* Detect JVM Process Termination */
-static void CALLBACK detectJvmExit( HWND hwnd, UINT uMsg, UINT id, DWORD dwTime )
-{
- DWORD exitCode;
-
- /* If the JVM process has terminated */
- if (!GetExitCodeProcess( (HANDLE)jvmProcess, &exitCode ) ||
- exitCode != STILL_ACTIVE)
- {
- /* Save the JVM exit code. This should cause the loop in startJavaVM() to exit. */
- jvmExitCode = exitCode;
- jvmProcess = 0;
- }
-}
-
/* Splash Timeout */
static void CALLBACK splashTimeout( HWND hwnd, UINT uMsg, UINT id, DWORD dwTime )
{
@@ -303,3 +206,83 @@ void unloadLibrary( void * handle ){
void * findSymbol( void * handle, char * symbol ){
return GetProcAddress(handle, symbol);
}
+
+/*
+ * Find the VM shared library starting from the java executable
+ */
+_TCHAR* findVMLibrary( _TCHAR* command ) {
+ int i;
+ int pathLength;
+ struct _stat stats;
+ _TCHAR * path; /* path to resulting jvm shared library */
+ _TCHAR * location; /* points to begining of jvmLocations section of path */
+
+ if (command != NULL) {
+ location = _tcsrchr( command, dirSeparator ) + 1;
+
+ /*check first to see if command already points to the library */
+ if (_tcscmp(location, vmLibrary) == 0) {
+ return command;
+ }
+
+ pathLength = location - command;
+ path = malloc((pathLength + MAX_LOCATION_LENGTH + 1 + _tcslen(vmLibrary)) * sizeof(_TCHAR *));
+ _tcsncpy(path, command, pathLength);
+ location = &path[pathLength];
+
+ /*
+ * We are trying base/jvmLocations[*]/vmLibrary
+ * where base is the directory containing the given java command, normally jre/bin
+ */
+ i = -1;
+ while(jvmLocations[++i] != NULL) {
+ int length = _tcslen(jvmLocations[i]);
+ _tcscpy(location, jvmLocations[i]);
+ location[length] = dirSeparator;
+ location[length + 1] = _T('\0');
+ _tcscat(location, vmLibrary);
+ if (_tstat( path, &stats ) == 0 && (stats.st_mode & S_IFREG) != 0)
+ { /* found it */
+ return path;
+ }
+ }
+ }
+
+ /* Not found yet, try the registry, we will use the first 1.4 or 1.5 vm we can find*/
+ HKEY keys[2] = { HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE };
+ _TCHAR * jreKeyName = _T("Software\\JavaSoft\\Java Runtime Environment");
+ for (i = 0; i < 2; i++) {
+ HKEY jreKey = NULL;
+ if (RegOpenKeyEx(keys[i], jreKeyName, 0, KEY_READ, &jreKey) == ERROR_SUCCESS) {
+ int j = 0;
+ _TCHAR keyName[MAX_PATH];
+ DWORD length = MAX_PATH;
+ while (RegEnumKeyEx(jreKey, j++, keyName, &length, 0, 0, 0, 0) == ERROR_SUCCESS) {
+ /*look for a 1.4 or 1.5 vm*/
+ if( _tcsncmp(_T("1.4"), keyName, 3) == 0 || _tcsncmp(_T("1.5"), keyName, 3) == 0) {
+ HKEY subKey = NULL;
+ if(RegOpenKeyEx(jreKey, keyName, 0, KEY_READ, &subKey) == ERROR_SUCCESS) {
+ length = MAX_PATH;
+ _TCHAR lib[MAX_PATH];
+ /*The RuntimeLib value should point to the library we want*/
+ if(RegQueryValueEx(subKey, _T("RuntimeLib"), NULL, NULL, (void*)&lib, &length) == ERROR_SUCCESS) {
+ if (_tstat( lib, &stats ) == 0 && (stats.st_mode & S_IFREG) != 0)
+ { /*library exists*/
+ path = malloc( length * sizeof(TCHAR*));
+ path[0] = _T('\0');
+ _tcscat(path, lib);
+
+ RegCloseKey(subKey);
+ RegCloseKey(jreKey);
+ return path;
+ }
+ }
+ RegCloseKey(subKey);
+ }
+ }
+ }
+ RegCloseKey(jreKey);
+ }
+ }
+ return NULL;
+}
diff --git a/bundles/org.eclipse.equinox.launcher/library/win32/make_mingw.mak b/bundles/org.eclipse.equinox.launcher/library/win32/make_mingw.mak
index ab9ebb525..1beca0d97 100644
--- a/bundles/org.eclipse.equinox.launcher/library/win32/make_mingw.mak
+++ b/bundles/org.eclipse.equinox.launcher/library/win32/make_mingw.mak
@@ -52,7 +52,7 @@ LDFLAGS = -mwindows -mno-cygwin
RES = eclipse.res
EXEC = $(PROGRAM_OUTPUT)
DEBUG = $(CDEBUG)
-CFLAGS = -O -s -Wall \
+CFLAGS = -g -s -Wall \
-I. -I$(JAVA_JNI) $(SYSINC) \
-D_WIN32 \
-DWIN32_LEAN_AND_MEAN \
@@ -65,7 +65,7 @@ WCFLAGS = -DUNICODE $(ACFLAGS)
all: $(EXEC)
-eclipse.o: ../eclipseOS.h ../eclipseUnicode.h ../eclipse.c
+eclipse.o: ../eclipseOS.h ../eclipseUnicode.h ../eclipseJNI.h ../eclipse.c
$(CC) $(DEBUG) $(WCFLAGS) -c -o $@ ../eclipse.c
eclipseUtil.o: ../eclipseUtil.h ../eclipseUnicode.h ../eclipseUtil.c

Back to the top