Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 276564

Summary: Eclipse won't launch using JDK 7 because SWT native libraries don't load
Product: [Eclipse Project] Platform Reporter: David Green <greensopinion>
Component: SWTAssignee: Silenio Quarti <Silenio_Quarti>
Status: RESOLVED FIXED QA Contact:
Severity: normal    
Priority: P3 CC: bhunt, caniszczyk, cocoakevin, codex69, eclipse.felipe, grant_gayed, KetanPadegaonkar, Mike_Wilson, mvfranz, psolanki, Silenio_Quarti, skovatch, sma, snorthov
Version: 3.5Flags: snorthov: review+
eclipse.felipe: review+
Target Milestone: 3.5 RC2   
Hardware: Macintosh   
OS: Mac OS X   
Whiteboard:
Attachments:
Description Flags
patch for loading with JDK7
none
mylyn/context/zip
none
Possible fix
none
patch
none
shell script to launch using JDK7 bsd port none

Description David Green CLA 2009-05-15 16:23:27 EDT
Eclipse fails to launch with the following exception when launching with JDK 7 (OpenJDK) from https://jdk7.dev.java.net):

java.lang.UnsatisfiedLinkError: no swt-pi-cocoa-3547 or swt-pi-cocoa in swt.library.path, java.library.path or the jar file
 at org.eclipse.swt.internal.Library.loadLibrary(Library.java:248)
 at org.eclipse.swt.internal.Library.loadLibrary(Library.java:159)

As documented "here":http://greensopinion.blogspot.com/2009/05/eclipse-35-galileo-on-jdk-7.html this problem can be circumvented by extracting the relevant jnilib files and putting them on the java.library.path

After stepping through the code it appears as if the problem is related to differences in the value returned from @System.mapLibraryName()@ on JDK7.  JDK7 returns libswt-cocoa-3548.dylib, whereas other Java VMs return libswt-cocoa-3548.jnilib.  Notice the difference in filename extension.  Technically though I believe that dylib is correct for Darwin, jnilib is returned by other VMs probably for historical reasons.

SWT is unable to load since libswt-cocoa-3548.dylib cannot be extracted onto the filesystem in @org.eclipse.swt.internal.Library.extract(String, String)@, since it does not exist in the SWT jar.

SWT should either detect this case and attempt to load with the jnilib suffix, _or_ SWT should provide both jnilib and dylib files in the SWT jar.

Solving this issue would make it possible for Mac users to use an alternative Java VM to the one provided by Apple, thus enabling the use of 32-bit SWT on the mac platform.
Comment 1 David Green CLA 2009-05-15 16:32:47 EDT
BTW, if SWT provides both jnilib and dylib files in the SWT jar it will fix the issue with no code changes and thus might be a good candidate fix for 3.5, even though we're in the endgame.
Comment 2 Steve Northover CLA 2009-05-15 17:43:32 EDT
We could know we are on the Mac, first try "jnilib" and then try "dylib".
Comment 3 David Green CLA 2009-05-15 18:01:15 EDT
Created attachment 136087 [details]
patch for loading with JDK7

a candidate fix attached
Comment 4 David Green CLA 2009-05-15 18:01:49 EDT
Created attachment 136088 [details]
mylyn/context/zip
Comment 5 David Green CLA 2009-05-15 18:05:38 EDT
Note that the code changes in the attached patch are only run if all other attempts to load SWT libraries fail.  At this point (without the patch) SWT is going to fail to load the libraries anyways.  This was intentional in order to reduce the risk of breaking something.  
Comment 6 Steve Northover CLA 2009-05-15 18:09:23 EDT
This (or another equivalent hack in Library.load()) will fix the problem for SWT but Eclipse loads other JNI libraries.
Comment 7 Scott Kovatch CLA 2009-05-15 18:13:30 EDT
I thought SoyLatte was supposed to change to allow 'jnilib' as a valid native library extension. Adding Pratik, who I believe was working with the SoyLatte folks on this.
Comment 8 David Green CLA 2009-05-15 18:20:15 EDT
(In reply to comment #7)
> I thought SoyLatte was supposed to change to allow 'jnilib' as a valid native
> library extension. Adding Pratik, who I believe was working with the SoyLatte
> folks on this.

This is not SoyLatte, it's OpenJDK: https://jdk7.dev.java.net
Comment 9 David Green CLA 2009-05-15 18:28:44 EDT
(In reply to comment #6)
> This (or another equivalent hack in Library.load()) will fix the problem for SWT
> but Eclipse loads other JNI libraries.

Agreed.  In particular changes would be needed to @org.eclipse.core.runtime.internal.adaptor.EclipseClassLoadingHook@
Eclipse can be run successfully without fixing EclipseClassLoadingHook provided that plug-ins in use (other than SWT) don't depend on native libraries.
Comment 10 Pratik Solanki CLA 2009-05-15 19:24:03 EDT
FWIW, on Mac we try .dylib extension if we don't find .jnilib. This change showed up in Mac OSX Leopard. If you're only worried about Leopard++ and 1.5++, then renaming your library from .jnilib to .dylib should work fine with both OpenJDK and MacOSX java.

But I would argue that if OpenJDK wants to be able to run apps on the Mac, then they should change their implementation to look for .jnilib on the Mac (along with dylib). Can someone file a bug against OpenJDK7 and get them to fix it?
Comment 11 Pratik Solanki CLA 2009-05-15 19:29:41 EDT
My previous comments applies to the behaviour of System.loadLibrary(). If you're using absolute paths and calling System.load(), then, well, you're on your own.
Comment 12 Stefan Muller Arisona CLA 2009-05-15 19:41:19 EDT
(In reply to comment #9)
> (In reply to comment #6)
> > This (or another equivalent hack in Library.load()) will fix the problem for SWT
> > but Eclipse loads other JNI libraries.
> 
> Agreed.  In particular changes would be needed to
> @org.eclipse.core.runtime.internal.adaptor.EclipseClassLoadingHook@
> Eclipse can be run successfully without fixing EclipseClassLoadingHook provided
> that plug-ins in use (other than SWT) don't depend on native libraries.
> 


Agree, Eclipse generally should support .dylib on OSX. Apple officially states that .dylib is supported on Leopard: http://developer.apple.com/documentation/Java/Conceptual/Java14Development/05-CoreJavaAPIs/CoreJavaAPIs.html (at least for HotSpot). The use of .dylib would resolve tricky dynamic linking issues that arise with dependent native libs & renaming them into .jnilib (tweaking @rpath, etc...)
Comment 13 Michael Franz CLA 2009-05-15 20:08:28 EDT
The BSD port (which OS X is part of) is not in the official OpenJDK repo.  It is in a port project.  The best way to get this fixed is for the JDK to support multiple library extensions.  Currently OS X is the only platform that does this (AFAIK).  Dalibor Topic pointed me to this thread http://markmail.org/message/nvmhqaimybukzg4l as to the history of why OS X supports two library extensions.

I started a thread about this back in September http://mail.openjdk.java.net/pipermail/bsd-port-dev/2008-September/000024.html .  This includes the startOnFirstThread and the dylib issue.  The startOnFirstThread has made it into the port.  The dylib never did.  I had started a discussion here http://mail.openjdk.java.net/pipermail/bsd-port-dev/2008-October/000064.html .  That I never followed up on.

I would like to see .jnilib be deprecated in favor of only supporting .dylib.
Comment 14 David Green CLA 2009-05-15 21:00:17 EDT
Most of these dylib versus jnilib naming issues are moot for SWT since SWT uses System.load() with a fully qualified path.  The problem arrises from the fact that the SWT jar contains jnilib, but uses  System.mapLibraryName() to determine the file to look for.  Since System.mapLibraryName() returns dylib file extensions SWT starts looking for the wrong files.  Shouldn't SWT know that it contains jnilib files and avoid using System.mapLibraryName() altogether?
Comment 15 David Green CLA 2009-05-18 19:25:57 EDT
related issue for those trying to use OpenJDK, bug 276763: [launcher] launcher fails to use OpenJDK-based VM when -vm is specified
Comment 16 Felipe Heidrich CLA 2009-05-19 11:27:42 EDT
If there is anything safe and simple we could do, I would like to do it.  However, it seems late in the 3.5 cycle to be making changes in this area.
Comment 17 David Green CLA 2009-05-19 12:34:22 EDT
(In reply to comment #16)
> If there is anything safe and simple we could do, I would like to do it.
> However, it seems late in the 3.5 cycle to be making changes in this area.

That's great to hear!  Does the attached patch qualify as safe and simple?  Please let me know -- I'm prepared to rework the patch based on your feedback.
Comment 18 Steve Northover CLA 2009-05-19 13:10:05 EDT
Here is what I think:  Everyone who runs on the Mac who calls mapLibraryName() will have this problem.  OpenJDK should be changed to use "jnilib" on the Mac.

We could "fix" this by hacking SWT to look to see whether mapLibraryName() returns ".dylib" and change it to ".jnilib" because we know that is the kind of library that SWT builds.  We would do this by implementing Library.mapLibraryName() and change all senders to go through this new method.

I'm not crazy about this because other people may still be broken.
Comment 19 Silenio Quarti CLA 2009-05-19 13:10:27 EDT
Created attachment 136339 [details]
Possible fix

Would this patch fix the problem? Note that I have not run the code at all...
Comment 20 David Green CLA 2009-05-20 18:17:14 EDT
(In reply to comment #19)
> Would this patch fix the problem? Note that I have not run the code at all...

The patch looks great to me.  I've confirmed that it resolves the issue: with this patch I can run Eclipse using JDK 7 without having to do anything special for SWT.
Comment 21 David Green CLA 2009-05-20 18:17:41 EDT
BTW, I've also confirmed that with the patch I can run using Apple VMs too.
Comment 22 Felipe Heidrich CLA 2009-05-21 12:30:50 EDT
Created attachment 136677 [details]
patch 

This is same patch just added the //$NON-NLS-1$ and changed to use the local var (ext) in the if.
Comment 23 Steve Northover CLA 2009-05-21 12:47:20 EDT
Felipe, I would also like to comment the code and say what we are doing and why.
Comment 24 Silenio Quarti CLA 2009-05-21 12:52:09 EDT
Fixed > 20090521
Comment 25 David Green CLA 2009-05-21 13:12:45 EDT
Thanks for putting this one through for 3.5.
Comment 26 David Green CLA 2009-05-26 12:41:20 EDT
Created attachment 137195 [details]
shell script to launch using JDK7 bsd port

Verified that the fix works in eclipse-SDK-I20090522-1710-macosx-cocoa
In case anyone is interested, I've attached the shell script that I'm using to launch Eclipse using JDK 7.  This is an interim measure until the launcher is fixed.