[frs-248] FusionReactor Native Library Won’t Load: “No suitable image found”

Problem

On Mac OS X, after applying Apple updates to Java, you may see the following message output by FusionReactor, in your J2EE container's STDERR log (on ColdFusion, you may see this in the cfserver.log file):

java.lang.UnsatisfiedLinkError: /ServerApplications/ColdFusion9/runtime/bin/libFusionReactor-macos-x86_64.jnilib:  
Library not loaded: /System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Libraries/libclient.dylib   
Referenced from: /ServerApplications/ColdFusion9/runtime/bin/libFusionReactor-macos-x86_64.jnilib   Reason: no suitable image found.  Did find:  /System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Libraries/libclient.dylib: mach-o, 
but wrong architecture

Analysis

With the release of Java for Mac OS X 10.6 Update 3 and 10.5 Update 8, Apple prepared to stop producing and supporting their own version of Java by rearranging where the JVM was stored. Another change with this update seems to have been the reorganization of the 32- and 64-bit Java Virtual Machine dynamic libraries, known as dylibs.

FusionReactor's native library, which provides (amongst other things) CPU graphing, interfaces directly with the Java Virtual Machine using one of these dylibs.

The architecture of these libraries has changed slightly:

  • the libclient.dylib contains only the 32-bit Mac (Intel) architecture libraries
  • the libclient64.dylib contains both 32- and 64-bit Mac (Intel) architectures

This is demonstrated by the following output:

jhawksley@Myrtle% file libclient.dylib
  libclient.dylib: Mach-O dynamically linked shared library i386
jhawksley@Myrtle% file libclient64.dylib
  libclient64.dylib: Mach-O universal binary with 2 architectures
  libclient64.dylib (for architecture i386):	Mach-O dynamically linked shared library i386
  libclient64.dylib (for architecture x86_64):	Mach-O 64-bit dynamically linked shared library x86_64

The issue lies in the fact that Java and FusionReactor's own native library are 64-bit binaries, but are trying to load the libclient.dylib which, on Java 1.6, is a 32-bit library only.

Solution

Because of the wide range of Java available for Mac, and the fact that libraries are moving in Apple Java 1.6, it has not been feasible to produce a build of FusionReactor's native library which works in all cases.

We are therefore proposing the following workaround which is for users of Apple Java 1.6 only. The workaround entails copying (for safety) the old libclient.dylib, and linking the 64-bit dylib in its place. Since the 64-bit dylib contains both 32-bit (the i386 tag) and 64-bit (x86_64) architectures, this change should be transparent.

You may need to enter your password for the sudo commands.

  1. Open Terminal and navigate to the Java 6 library folder
    • cd /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Libraries
  2. Move the existing dylib out of the way
    • sudo mv libclient.dylib libclient32.dylib
  3. Link the 64-bit dylib into place
    • sudo ln -s libclient64.dylib libclient.dylib

You should then restart your J2EE container (e.g. ColdFusion) and observe the STDERR (e.g. cfserver.log) log to ensure the library has loaded. CPU graph data should then also be visible in FusionReactor.

If you need to back out the change, reverse the steps above.

  1. Remove the link
    • sudo rm libclient.dylib
  2. Move the backed-up 32-bit dylib back into place
    • sudo mv libclient32.dylib libclient.dylib

References

Issue Details

Type: Technote
Issue Number: FRS-248
Components: CPU + Memory
Environment:
Resolution: Fixed
Last Updated: 13/Apr/11 11:09 AM
Affects Version: 3.0, 4.0.0
Fixed Version: Pending
Server:
Platform: MacOS
Related Issues:

Comments are closed.