BSAF stalls opening a DB connection

165 Views Asked by At

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

There are 1 best solutions below

5
On

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.