diff options
author | Bogdan Gheorghe | 2012-11-21 19:56:56 +0000 |
---|---|---|
committer | Bogdan Gheorghe | 2012-11-21 19:56:56 +0000 |
commit | bc208f9ff388083d4f2bb650e1efcceac5b9b10e (patch) | |
tree | 58a27eb1fd2d892117be84582703a207f782bdd7 | |
parent | 17a98f4def298e1a254c1c07c7f22ea088dbc08b (diff) | |
download | rt.equinox.framework-bc208f9ff388083d4f2bb650e1efcceac5b9b10e.tar.gz rt.equinox.framework-bc208f9ff388083d4f2bb650e1efcceac5b9b10e.tar.xz rt.equinox.framework-bc208f9ff388083d4f2bb650e1efcceac5b9b10e.zip |
Bug 302584 - A swing application started from the native launcher on MacOSX doesn't terminate properly + Java7 Support sha: a6568f5db9fc6011c02f6ee6a4b28bb359e3d9ea & 3011e6a9c0142036bd38851224e8e030936dc858
7 files changed, 209 insertions, 100 deletions
diff --git a/bundles/org.eclipse.equinox.executable/library/carbon/build.sh b/bundles/org.eclipse.equinox.executable/library/carbon/build.sh index 413176dd1..31ad71727 100644 --- a/bundles/org.eclipse.equinox.executable/library/carbon/build.sh +++ b/bundles/org.eclipse.equinox.executable/library/carbon/build.sh @@ -66,7 +66,7 @@ X86_64_OUTPUT_DIR="../../bin/$defaultWS/$defaultOS/x86_64/Eclipse.app/Contents/M if [ "$DEFAULT_WS" == "cocoa" ]; then makefile="make_cocoa.mak" - export MACOSX_DEPLOYMENT_TARGET=10.4 + export MACOSX_DEPLOYMENT_TARGET=10.5 else export MACOSX_DEPLOYMENT_TARGET=10.3 fi diff --git a/bundles/org.eclipse.equinox.executable/library/carbon/eclipseCarbon.c b/bundles/org.eclipse.equinox.executable/library/carbon/eclipseCarbon.c index 47739962b..149cb88c4 100644 --- a/bundles/org.eclipse.equinox.executable/library/carbon/eclipseCarbon.c +++ b/bundles/org.eclipse.equinox.executable/library/carbon/eclipseCarbon.c @@ -45,19 +45,24 @@ char *findCommand(char *command); /* Global Variables */ char* defaultVM = "java"; char* vmLibrary = "JavaVM"; -char* shippedVMDir = "jre/bin/"; +char* shippedVMDir = "../../../jre/Contents/Home/jre/bin/"; +int isSUN = 0; static void adjustLibraryPath(char * vmLibrary); static char * findLib(char * command); #ifdef i386 #define JAVA_ARCH "i386" +#define JAVA_HOME_ARCH "i386" #elif defined(__ppc__) || defined(__powerpc64__) #define JAVA_ARCH "ppc" +#define JAVA_HOME_ARCH "ppc" #elif defined(__amd64__) || defined(__x86_64__) #define JAVA_ARCH "amd64" +#define JAVA_HOME_ARCH "x86_64" #else #define JAVA_ARCH DEFAULT_OS_ARCH +#define JAVA_HOME_ARCH DEFAULT_OS_ARCH #endif #define LIB_PATH_VAR _T_ECLIPSE("LD_LIBRARY_PATH") @@ -73,15 +78,6 @@ static const char* jvmLibs[] = { "libjvm.dylib", "libjvm.jnilib", "libjvm.so", N /* Define the window system arguments for the various Java VMs. */ static char* argVM_JAVA[] = { "-XstartOnFirstThread", NULL }; -/* thread stuff */ -typedef struct { - _TCHAR * libPath; - _TCHAR ** vmArgs; - _TCHAR ** progArgs; - _TCHAR * jarFile; - JavaResults* result; -} StartVMArgs; - #ifdef COCOA static NSWindow* window = nil; @interface KeyWindow : NSWindow { } @@ -151,10 +147,6 @@ static NSWindow* window = nil; @end #endif -static CFRunLoopRef loopRef = NULL; -static void * startThread(void * init); -static void runEventLoop(CFRunLoopRef ref); -static void dummyCallback(void * info) {} #ifndef COCOA static CFMutableArrayRef files; static EventHandlerRef appHandler; @@ -465,10 +457,68 @@ char** getArgVM( char* vm ) return result; } +char * getJavaVersion(char* command) { + FILE *fp; + char buffer[4096]; + char *version = NULL, *firstChar; + int numChars = 0; + sprintf(buffer,"%s -version 2>&1", command); + fp = popen(buffer, "r"); + if (fp == NULL) { + return NULL; + } + while (fgets(buffer, sizeof(buffer)-1, fp) != NULL) { + if (!version) { + firstChar = (char *) (strchr(buffer, '"') + 1); + if (firstChar != NULL) + numChars = (int) (strrchr(buffer, '"') - firstChar); + + /* Allocate a buffer and copy the version string into it. */ + if (numChars > 0) + { + version = malloc( numChars + 1 ); + strncpy(version, firstChar, numChars); + version[numChars] = '\0'; + } + } + if (strstr(buffer, "Java HotSpot(TM)") || strstr(buffer, "OpenJDK")) { + isSUN = 1; + break; + } + if (strstr(buffer, "IBM") != NULL) { + isSUN = 0; + break; + } + } + pclose(fp); + return version; +} + +char * getJavaHome() { + FILE *fp; + char path[4096]; + char *result, *start; + sprintf(path, "/usr/libexec/java_home -a %s", JAVA_HOME_ARCH); + fp = popen(path, "r"); + if (fp == NULL) { + return NULL; + } + while (fgets(path, sizeof(path)-1, fp) != NULL) { + } + result = path; + start = strchr(result, '\n'); + if (start) { + start[0] = 0; + } + sprintf(path, "%s/bin/java", result); + pclose(fp); + return strdup(path); +} + char * findVMLibrary( char* command ) { char *start, *end; char *version; - int length; + int length, isJDK7; /*check first to see if command already points to the library */ if (strcmp(command, JAVA_FRAMEWORK) == 0) { @@ -493,7 +543,23 @@ char * findVMLibrary( char* command ) { free(version); } - } else if (strstr(command, "/JavaVM.framework/") == NULL) { + } + char *java_home = NULL, *cmd = command; + if (strstr(cmd, "/JavaVM.framework/") != NULL && (strstr(cmd, "/Current/") != NULL || strstr(cmd, "/A/") != NULL)) { + java_home = cmd = getJavaHome(); + } + version = getJavaVersion(cmd); + isJDK7 = version && versionCmp(version, "1.7.0") >= 0; + if (version) free(version); + if (isJDK7) { + start = strstr(cmd, "/Contents/"); + if (start != NULL){ + start[0] = 0; + return cmd; + } + } + if (java_home) free(java_home); + if (strstr(command, "/JavaVM.framework/") == NULL) { char * lib = findLib(command); if (lib != NULL) { adjustLibraryPath(lib); @@ -635,64 +701,9 @@ JavaResults* startJavaVM( _TCHAR* libPath, _TCHAR* vmArgs[], _TCHAR* progArgs[], char firstThreadEnvVariable[80]; sprintf(firstThreadEnvVariable, "JAVA_STARTED_ON_FIRST_THREAD_%d", getpid()); setenv(firstThreadEnvVariable, "1", 1); - return startJavaJNI(libPath, vmArgs, progArgs, jarFile); - } - - /* else, --launcher.secondThread was specified, create a new thread and run the - * vm on it. This main thread will run the CFRunLoop - */ - pthread_t thread; - struct rlimit limit = {0, 0}; - int stackSize = 0; - if (getrlimit(RLIMIT_STACK, &limit) == 0) { - if (limit.rlim_cur != 0) { - stackSize = limit.rlim_cur; - } } - - /* initialize thread attributes */ - pthread_attr_t attributes; - pthread_attr_init(&attributes); - pthread_attr_setscope(&attributes, PTHREAD_SCOPE_SYSTEM); - pthread_attr_setdetachstate(&attributes, PTHREAD_CREATE_DETACHED); - if (stackSize != 0) - pthread_attr_setstacksize(&attributes, stackSize); - - /* arguments to start the vm */ - StartVMArgs args; - args.libPath = libPath; - args.vmArgs = vmArgs; - args.progArgs = progArgs; - args.jarFile = jarFile; - args.result = 0; - - loopRef = CFRunLoopGetCurrent(); - - /* create the thread */ - pthread_create( &thread, &attributes, &startThread, &args); - pthread_attr_destroy(&attributes); - - runEventLoop(loopRef); - - return args.result; -} - -void * startThread(void * init) { - StartVMArgs *args = (StartVMArgs *) init; - args->result = startJavaJNI(args->libPath, args->vmArgs, args->progArgs, args->jarFile); - return NULL; -} - -void runEventLoop(CFRunLoopRef ref) { - CFRunLoopSourceContext sourceContext = { .version = 0, .info = NULL, .retain = NULL, .release = NULL, - .copyDescription = NULL, .equal = NULL, .hash = NULL, - .schedule = NULL, .cancel = NULL, .perform = &dummyCallback }; - - CFRunLoopSourceRef sourceRef = CFRunLoopSourceCreate(NULL, 0, &sourceContext); - CFRunLoopAddSource(ref, sourceRef, kCFRunLoopCommonModes); - - CFRunLoopRun(); - CFRelease(sourceRef); + JavaResults* results = startJavaJNI(libPath, vmArgs, progArgs, jarFile); + return results; } #ifndef COCOA @@ -811,6 +822,5 @@ void processVMArgs(char **vmargs[] ) } int isSunVM( _TCHAR * javaVM, _TCHAR * jniLib ) { - _TCHAR *vm = (jniLib != NULL) ? jniLib : javaVM; - return (strncmp(vm, JAVA_FRAMEWORK, strlen(JAVA_FRAMEWORK)) == 0); + return isSUN; } diff --git a/bundles/org.eclipse.equinox.executable/library/carbon/eclipseCarbonCommon.c b/bundles/org.eclipse.equinox.executable/library/carbon/eclipseCarbonCommon.c index 82e97194e..9ca48f16c 100644 --- a/bundles/org.eclipse.equinox.executable/library/carbon/eclipseCarbonCommon.c +++ b/bundles/org.eclipse.equinox.executable/library/carbon/eclipseCarbonCommon.c @@ -111,11 +111,20 @@ void displayMessage(char *title, char *message) CFRelease(inDescription); } +static int isLibrary( _TCHAR* vm ){ + _TCHAR *ch = NULL; + if (vm == NULL) return 0; + ch = _tcsrchr( vm, '.' ); + if(ch == NULL) + return 0; + return (_tcsicmp(ch, _T_ECLIPSE(".so")) == 0) || (_tcsicmp(ch, _T_ECLIPSE(".jnilib")) == 0) || (_tcsicmp(ch, _T_ECLIPSE(".dylib")) == 0); +} + /* Load the specified shared library */ void * loadLibrary( char * library ){ - if (strcmp(library, JAVA_FRAMEWORK) == 0) { - CFURLRef url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (const UInt8 *)JAVA_FRAMEWORK, strlen(JAVA_FRAMEWORK), true); + if (!isLibrary(library)) { + CFURLRef url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (const UInt8 *)library, strlen(library), true); javaVMBundle = CFBundleCreate(kCFAllocatorDefault, url); CFRelease(url); return (void*) &javaVMBundle; diff --git a/bundles/org.eclipse.equinox.executable/library/eclipseMain.c b/bundles/org.eclipse.equinox.executable/library/eclipseMain.c index fe5273072..11e6a7796 100644 --- a/bundles/org.eclipse.equinox.executable/library/eclipseMain.c +++ b/bundles/org.eclipse.equinox.executable/library/eclipseMain.c @@ -20,6 +20,15 @@ #include <ctype.h> #include <locale.h> #include <sys/stat.h> +#ifdef MACOSX +#include <CoreServices/CoreServices.h> +#ifdef COCOA +#include <Cocoa/Cocoa.h> +#else +#include <Carbon/Carbon.h> +#endif +#include <pthread.h> +#endif static _TCHAR* libraryMsg = _T_ECLIPSE("The %s executable launcher was unable to locate its \n\ @@ -34,17 +43,20 @@ finding the entry point."); /* New arguments have the form --launcher.<arg> to avoid collisions */ #define LIBRARY _T_ECLIPSE("--launcher.library") #define SUPRESSERRORS _T_ECLIPSE("--launcher.suppressErrors") +#define SECOND_THREAD _T_ECLIPSE("--launcher.secondThread") #define INI _T_ECLIPSE("--launcher.ini") /* this typedef must match the run method in eclipse.c */ typedef int (*RunMethod)(int argc, _TCHAR* argv[], _TCHAR* vmArgs[]); typedef void (*SetInitialArgs)(int argc, _TCHAR*argv[], _TCHAR* library); +static _TCHAR* program = NULL; /* program path */ static _TCHAR* name = NULL; /* program name */ static _TCHAR** userVMarg = NULL; /* user specific args for the Java VM */ static _TCHAR* programDir = NULL; /* directory where program resides */ static _TCHAR* officialName = NULL; static int suppressErrors = 0; /* supress error dialogs */ +static int secondThread = 0; /* True: start the VM on a second thread */ static int createUserArgs(int configArgc, _TCHAR **configArgv, int *argc, _TCHAR ***argv); static void parseArgs( int* argc, _TCHAR* argv[] ); @@ -90,18 +102,54 @@ int main(int argc, char* argv[]) { #define main mainW #endif /* UNICODE */ +static int callRunMethod(int argc, _TCHAR* argv[], void* handle, _TCHAR** userVMarg) { + RunMethod runMethod = (RunMethod)findSymbol(handle, RUN_METHOD); + int exitCd = 0; + if(runMethod != NULL) + exitCd = runMethod(argc, argv, userVMarg); + else { + if(!suppressErrors) + displayMessage(officialName, entryMsg); + else + _ftprintf(stderr, _T_ECLIPSE("%s:\n%s\n"), officialName, entryMsg); + exit(1); + } + unloadLibrary(handle); + free( eclipseLibrary ); + free( programDir ); + free( program ); + free( officialName ); + return exitCd; +} + +#ifdef MACOSX +typedef struct { + int argc; + _TCHAR** argv; + _TCHAR** userVMarg; + void* handle; +} ThreadArgs; + +static void * startThread(void * init) { + ThreadArgs * args = (ThreadArgs *) init; + int exitCode = callRunMethod (args->argc, args->argv, args->handle, args->userVMarg); + exit(exitCode); + return NULL; +} + +static void dummyCallback(void * info) {} +#endif + int main( int argc, _TCHAR* argv[] ) { _TCHAR* errorMsg; - _TCHAR* program; _TCHAR* iniFile; _TCHAR* ch; _TCHAR** configArgv = NULL; int configArgc = 0; int exitCode = 0; int ret = 0; - void * handle = 0; - RunMethod runMethod; + void* handle = NULL; SetInitialArgs setArgs; setlocale(LC_ALL, ""); @@ -181,22 +229,62 @@ int main( int argc, _TCHAR* argv[] ) exit(1); } - runMethod = (RunMethod)findSymbol(handle, RUN_METHOD); - if(runMethod != NULL) - exitCode = runMethod(argc, argv, userVMarg); - else { - if(!suppressErrors) - displayMessage(officialName, entryMsg); - else - _ftprintf(stderr, _T_ECLIPSE("%s:\n%s\n"), officialName, entryMsg); - exit(1); +#ifdef MACOSX + /* if --launcher.secondThread was specified, create a new thread and run the vm on it. + * This main thread will run the CFRunLoop + */ + if (secondThread != 0) { + /* Initialize the application */ + #ifdef COCOA + [NSApplication sharedApplication]; + #else + ClearMenuBar(); + #endif + + /* Create and run the sencond thread */ + struct rlimit limit = {0, 0}; + int stackSize = 0; + if (getrlimit(RLIMIT_STACK, &limit) == 0) { + if (limit.rlim_cur != 0) { + stackSize = limit.rlim_cur; + } + } + void *status; + pthread_t thread; + pthread_attr_t attributes; + pthread_attr_init(&attributes); + pthread_attr_setscope(&attributes, PTHREAD_SCOPE_SYSTEM); + pthread_attr_setdetachstate(&attributes, PTHREAD_CREATE_DETACHED); + if (stackSize != 0) + pthread_attr_setstacksize(&attributes, stackSize); + + CFRunLoopSourceContext sourceContext = { + .version = 0, .info = NULL, .retain = NULL, .release = NULL, + .copyDescription = NULL, .equal = NULL, .hash = NULL, + .schedule = NULL, .cancel = NULL, .perform = &dummyCallback + }; + + CFRunLoopSourceRef sourceRef = CFRunLoopSourceCreate(NULL, 0, &sourceContext); + CFRunLoopAddSource(CFRunLoopGetCurrent(), sourceRef, kCFRunLoopCommonModes); + + ThreadArgs threadArgs; + threadArgs.argc = argc; + threadArgs.argv = argv; + threadArgs.userVMarg = userVMarg; + threadArgs.handle = handle; + pthread_create( &thread, &attributes, &startThread, &threadArgs); + pthread_attr_destroy(&attributes); + + CFRunLoopRun(); + CFRelease(sourceRef); + + pthread_join(thread, &status); + } else { + exitCode = callRunMethod(argc, argv, handle, userVMarg); } - unloadLibrary(handle); - - free( eclipseLibrary ); - free( programDir ); - free( program ); - free( officialName ); +#else + exitCode = callRunMethod(argc, argv, handle, userVMarg); +#endif return exitCode; } @@ -261,6 +349,8 @@ static void parseArgs( int* pArgc, _TCHAR* argv[] ) eclipseLibrary = argv[++index]; } else if(_tcsicmp(argv[index], SUPRESSERRORS) == 0) { suppressErrors = 1; + } else if(_tcsicmp(argv[index], SECOND_THREAD) == 0) { + secondThread = 1; } } } diff --git a/bundles/org.eclipse.equinox.executable/library/eclipseUtil.c b/bundles/org.eclipse.equinox.executable/library/eclipseUtil.c index 9ed7b68b2..987ed41e4 100644 --- a/bundles/org.eclipse.equinox.executable/library/eclipseUtil.c +++ b/bundles/org.eclipse.equinox.executable/library/eclipseUtil.c @@ -250,6 +250,7 @@ char* getVMVersion( char *vmPath ) return version; } +#endif /* AIX */ /* Compare JVM Versions of the form "x.x.x..." * @@ -287,4 +288,3 @@ int versionCmp(char *ver1, char *ver2) return versionCmp((char*)(dot1 + 1), (char*)(dot2 + 1) ); } -#endif /* AIX */ diff --git a/bundles/org.eclipse.equinox.executable/library/eclipseUtil.h b/bundles/org.eclipse.equinox.executable/library/eclipseUtil.h index 970aba374..1c33f4ba4 100644 --- a/bundles/org.eclipse.equinox.executable/library/eclipseUtil.h +++ b/bundles/org.eclipse.equinox.executable/library/eclipseUtil.h @@ -43,12 +43,12 @@ extern _TCHAR* concatPaths(_TCHAR** paths, _TCHAR pathSeparator); /* check that the buffer contains all the given paths */ extern int containsPaths(_TCHAR * str, _TCHAR** paths); -#ifdef AIX +#ifdef AIX /* Get the version of the VM */ extern char* getVMVersion( char* vm ); +#endif /* Compare JVM Versions */ extern int versionCmp( char* ver1, char* ver2 ); -#endif #endif /* ECLIPSE_UTIL_H */ diff --git a/bundles/org.eclipse.equinox.executable/library/make_version.mak b/bundles/org.eclipse.equinox.executable/library/make_version.mak index 05aaff259..292533ca2 100644 --- a/bundles/org.eclipse.equinox.executable/library/make_version.mak +++ b/bundles/org.eclipse.equinox.executable/library/make_version.mak @@ -10,5 +10,5 @@ #******************************************************************************* maj_ver=1 -min_ver=312 +min_ver=313 LIB_VERSION = $(maj_ver)$(min_ver) |