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
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.