3

Right, so Ive got an interesting problem here concerning SWT and swing integration on mac running java 1.7. Im trying to embed an SWT Browser widget into my swing project as a panel which is pretty simple to do on java version 1.6. There has been a number of posts which explain how to do this with SWT_AWT bridge classes along with the following example:

import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import org.eclipse.swt.SWT;
import org.eclipse.swt.awt.SWT_AWT;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

public class MySWTBrowserTest implements ActionListener {

public JButton addCodeButton;
public JButton launchBrowserButton;
public JTextField inputCode;
public JFrame frame;
static Display display;
static boolean exit;

public MySWTBrowserTest() {
    frame = new JFrame("Main Window");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    JPanel mainPanel = new JPanel();
    mainPanel.setLayout(new FlowLayout());

    inputCode = new JTextField(15);
    inputCode.setText("999");
    addCodeButton = new JButton("Add Code");
    addCodeButton.addActionListener(this);
    addCodeButton.setActionCommand("addcode");

    launchBrowserButton = new JButton("Launch Browser");
    launchBrowserButton.addActionListener(this);
    launchBrowserButton.setActionCommand("launchbrowser");

    mainPanel.add(inputCode);
    mainPanel.add(addCodeButton);
    mainPanel.add(launchBrowserButton);

    frame.getContentPane().add(mainPanel, BorderLayout.CENTER);
    frame.pack();
    frame.setVisible(true);
}

@Override
public void actionPerformed(ActionEvent e) {
    if (e.getActionCommand().equals("addcode")) {
    } else if (e.getActionCommand().equals("launchbrowser")) {
        createAndShowBrowser();
    }

}

public void createAndShowBrowser() {
    JFrame f = new JFrame();
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    final Canvas canvas = new Canvas();
    f.setSize(850, 650);
    f.getContentPane().add(canvas);
    f.setVisible(true);
    display.asyncExec(new Runnable() {

        @Override
        public void run() {
            Shell shell = SWT_AWT.new_Shell(display, canvas);
            shell.setSize(800, 600);
            Browser browser = new Browser(shell, SWT.NONE);
            browser.setLayoutData(new GridData(GridData.FILL_BOTH));
            browser.setSize(800, 600);
            browser.setUrl("http://www.google.com");
            shell.open();
        }
    });
}

public static void main(String args[]) {
    //SWT_AWT.embeddedFrameClass = "sun.lwawt.macosx.CEmbeddedFrame";
    display = new Display();

    EventQueue.invokeLater(new Runnable() {

        @Override
        public void run() {
            MySWTBrowserTest mySWTBrowserTest = new MySWTBrowserTest();
        }
    });

    while (!exit) {
        if (!display.readAndDispatch()) {
            display.sleep();
        }
    }
    display.dispose();
}
}

Im using the swt-3.8M5-cocoa-macosx-x86_64 JAR files which obviously need to be included to run the above example. When using both the 32 bit and 64 bit versions of the 1.6 JDK, this runs perfectly fine, but when switching to the JDK 1.7 or 1.8 VM the reproducible error is thrown:

2012-05-14 15:11:30.534 java[1514:707] Cocoa AWT: Apple AWT Java VM was loaded on first thread -- can't start AWT. (
0   liblwawt.dylib                      0x00000008db728ad0 JNI_OnLoad + 468
1   libjava.dylib                       0x00000001015526f1 Java_java_lang_ClassLoader_00024NativeLibrary_load + 207
2   ???                                 0x00000001015a4f90 0x0 + 4317663120
)
_NSJVMLoadLibrary: NSAddLibrary failed for /libjawt.dylib
JavaVM FATAL: lookup of function JAWT_GetAWT failed. Exit
Java Result: 255

Ive inspected the java 1.7 vm and did find the libraries there, so Im struggling to see what could cause it to not load that library. Of course I make sure to use: -XstartOnFirstThread as one of the VM parameters, as is required for the SWING/AWT integration.

On a further note, I have tried the DJ Native Widgets framework, and it throws the exact same error as it also uses the underlying SWT framework.

To reproduce the effects i suggest installing JDK 1.7 (release not the developer preview) on mac, downloading the: http://www.eclipse.org/downloads/download.php?file=/eclipse/downloads/drops4/S-4.2M7-201205031800/swt-S-4.2M7-201205031800-cocoa-macosx-x86_64.zip to get the library and then running it with the -XstartOnFirstThread -d64 java 1.7 vm.

really hoping someone has been able to sort this out as Im sure Im not the only one trying to integrate SWT into swing on the 1.7 vm

I also spent 8 hours on google to see if this error has been reproduced anywhere else, and it has come up on a few Matlab mailing lists, but other than that I haven't been able to find something even close to a solution.

Thanks in advance.


>> UPDATE 1

Looks like we may have a winner: https://bugs.eclipse.org/bugs/show_bug.cgi?id=374199 Going to monitor this and see where it goes.

>> UPDATE 2

Here is a working example: https://stackoverflow.com/a/27754819/363573

Community
  • 1
  • 1
Dylan Vorster
  • 56
  • 1
  • 6
  • 2
    Good Question!! Having the same problem with OpenGL (JOGL) on Mac... Too bad there is absolutely nothing we can do!!! Changing back the Workspace default Compiler and JRE to 1.6... – Mostafa Zeinali Feb 26 '13 at 07:05
  • 1
    no, you cant be serious : ( , I've used JOGL many times before D: so this must be a new thing.. its been almost a year and this problem still has not been fixed #frustrating – Dylan Vorster Feb 26 '13 at 12:29
  • I use JOGL through it's SWT Canvas implementation and I think that's the problem... I prefer SWT cuz my whole UI is SWT and also I freaking HATE Swing and AWT!!! I could go with newt but I was too lazy to try!! – Mostafa Zeinali Feb 26 '13 at 13:04
  • We had to force Java 7 to use the Java 6 plugin to get this working again. Here are the steps to do that: Java for OS X 2013-002: How to re-enable the Apple-provided Java SE 6 web plug-in and Web Start functionality. http://support.apple.com/kb/HT5559?viewlocale=en_US&locale=en_US – Dermot Doherty May 02 '13 at 17:53
  • While those are the steps involved to switch back java 7 to java 6, this does not solve the new problem the above link creates of writing the source code in java 7 and then trying to run it in the 1.6 VM. Nearly a year has passed since I first asked this question, and its now a much bigger problem as lwjgl and JOGL all suffer from this unfixed problem. Bottom line is: The native calls to openGL and/or any OSX widget you need to use in swing with java 1.7, is not possible because the fundamental AWT bridge is broken, and has not been fixed. Stick to 1.6 if you need native widgets in swing. – Dylan Vorster May 02 '13 at 22:38
  • If you want to see an even bigger mess, run netbeans in the 1.7 vm and then in the 1.6 vm. Thats quite a shocker... – Dylan Vorster May 02 '13 at 22:39

1 Answers1

2

Unfortunately there's no good answer to this. In Java 7 the AWT has been completely rewritten to use CoreAnimation layers. The SWT assumes that an AWT Canvas will be backed by an NSView but that's no longer the case. Your only choice right now is to stick with Java 6.

The AWT team is aware of the problem but you may want to file another bug on bugs.sun.com.

Scott K.
  • 1,761
  • 15
  • 26