1

Running a Java application using Better Swing Application Framework (BSAF), if I ever try to open a connection with a database once the program has launched it gets stalled. If I happen to run the connection before the launch, it works properly. In my case there's no workaround possible as I require the user to actively open and close the connection.

The following code is a exmaple of what happens

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.EventObject;
import javax.swing.JButton;
import javax.swing.JPanel;
import org.jdesktop.application.Action;
import org.jdesktop.application.SingleFrameApplication;
import org.jdesktop.application.Task;

public class BsafConnection extends SingleFrameApplication {

    private static final String DB_URL = ""; // A proper URL
    private static final String DRIVER = ""; // A proper driver
    private static Connection CONNECTION;

    public BsafConnection() {
        super();

        addExitListener(new ExitListener() {
            @Override
            public boolean canExit(EventObject event) {
                return true;
            }
            @Override
            public void willExit(EventObject event) {
                if (CONNECTION != null) {
                    try {
                        CONNECTION.close();
                        System.out.println("Connection closed");
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                } else {
                    System.out.println("Connection was not open");
                }
            }});
    }

    @Override
    protected void startup() {
    }

    @Override
    public void ready() {
        JPanel panel = new JPanel();
        panel.add(new JButton(getContext().getActionMap().get("connect")));
        panel.add(new JButton("Press here to check that the EDT is not blocked"));
        show(panel);
    }

    @Action
    public Task<?, ?> connect() {
        return new Task<Object, Object> (this) {
            @Override
            protected Object doInBackground() throws Exception {
                javax.swing.Action action = getContext().getActionMap().get("connect");
                action.putValue(javax.swing.Action.NAME, "Connecting...");
                openConnection(); // Placing the connection here makes the application stall

                action.putValue(javax.swing.Action.NAME, "Connected!");
                return null;
            }};
    }

    public static void openConnection() {
        try {
            Class.forName(DRIVER);

            CONNECTION = DriverManager.getConnection(DB_URL); // This instruction stalls when called after launch()
            System.out.println("Connection open");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String... args) {
//        openConnection(); // Here, the connection would work but is not the desired place 
        launch(BsafConnection.class, args);
    }

}

I'm working on a Windows environment, if that might be some kind of issue. I'm afraid that might be related to the way BSAF runs the application using the EDT or about the ClassLoader. Just to clarify: blocking the EDT is not an issue, it's working properly, the thing is that the instruction DriverManager.getConnection(DB_URL); gets stuck and throws no exception.

EDIT: I just found out that if I happen to open a connection before the launch I can open them later properly.

EDIT 2: Added a more explanative example code.

EDIT 3: Clarified info about the possible reasons

1 Answers1

1

It looks like your connection is blocking the event dispatch thread. You should handle it in another thread like a SwingWorker.

Edit: I'm not sure why Task/SwingWorker isn't working, but you might look in the BASF forum on the topic.

Catalina Island
  • 7,027
  • 2
  • 23
  • 42
  • Tried already, it's not working: either using `SwingUtilities.invokeLater(...)` or using a `Task` of the framework, which is a `SwingWorker` internally. The example is simple, that's why it's blocking the EDT (in the real implementation is not getting blocked as it's handled inside a `Task`), but the real problem is not getting blocked, it's that the connection never happens. – Yago Méndez Vidal Oct 29 '13 at 12:24
  • Sorry, I don't understand how "the connection never happens." Do you mean `openConnection()` is never called or that it blocks the EDT? – Catalina Island Oct 30 '13 at 11:53
  • Neither: the problem is that the instruction `DriverManager.getConnection(DB_URL)` gets stalled always after the launch of the application. I'm going to rewrite the example for clarifying the problem. – Yago Méndez Vidal Oct 30 '13 at 13:10
  • I've added an example a bit more complex but that shows the problem a bit more clear. To clarify: The problem is that you can't open a DB connection after the launch(). – Yago Méndez Vidal Oct 31 '13 at 07:48
  • I've asked this in the forums as suggested, although those don't have much activity nowadays. After thinking and reading, maybe it's related to how BSAF manipulates the `ClassLoader` and how the Driver is registered, but still I'm completely lost. – Yago Méndez Vidal Oct 31 '13 at 11:19