Wednesday, July 25, 2012
MySQL jdbc driver hangs only with jnlp...
There is a strange bug with the MySQL jdbc driver that happens only when the application is launched through JavaWebStart. This issue caused me a lot of head scratching until the solution surfaced, somehow by luck. This post is just to share the information in case somebody has the same problem.
Normally, the following code connects to the server:
Class.forName("com.mysql.jdbc.Driver").newInstance();
Properties info = new Properties();
info.setProperty("user", username);
info.setProperty("password", password);
info.setProperty("timeout", "1");
connection = DriverManager.getConnection( "serverName", info );
This code works both when running directly in Eclipse and also when starting the application from a compiled jar.
If the network connection is ok, then it connects, and if not, then it will give either a timeout exception or an unknown host exception or something similar.
Weirdly, when the same compiled jar is launched using a jnlp file over JavaWebStart, then the application just hung. It would sit for hours and hours, not giving any timeout or exception or anything. Looking in the Java console gave no clues, but narrowed the problem down to the line:
connection = DriverManager.getConnection( "serverName", info );
The problem was diagnosed many many months later as a host resolution issue. When the "serverName" was replaced with "serverName.company.com" then the application connected properly.
So, just in case you have the same problem but only when using JavaWebStart, I would recommend adding the domain suffix to the server address and giving that a try.
Hope it helps!
Monday, July 16, 2012
SWT Table Simple Performance Improvement
If you have ever used the SWT Table widget for any serious amount of data, you may have noticed that the performance is, let's say not great. One way to improve the performance of the SWT Table is to use the SWT.VIRTUAL style and fill the data "on demand". While this does work, there is another very easy way to improve it noticeably.
The trick is using the redraw flag correctly. Normally, the redraw flag is set true by default, which means that the widget redraws with any change whatsoever. So, for example, adding a TableColumn or a TableItem (new row) means a redraw. Of course, if you are filling thousands of rows into a table, the performance is usually quite poor.
You can just set the redraw flag to false before filling the table and set it to true after filling it. As an example, take a look at an example, adapted from the snippet here.
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
public class TableShellExample {
Display display;
Shell shell;
TableShellExample() {
display = new Display();
shell = new Shell(display);
shell.setSize(300, 500);
shell.setText("A Table Shell Example");
shell.setLayout(new FillLayout());
Table table = new Table(shell, SWT.BORDER);
TableColumn tc1 = new TableColumn(table, SWT.CENTER);
TableColumn tc2 = new TableColumn(table, SWT.CENTER);
TableColumn tc3 = new TableColumn(table, SWT.CENTER);
tc1.setText("Column 1");
tc2.setText("Column 2");
tc3.setText("Column 3");
tc1.setWidth(80);
tc2.setWidth(80);
tc3.setWidth(80);
table.setHeaderVisible(true);
shell.open();
// turn redraw off before filling table
table.setRedraw(false);
long start = System.currentTimeMillis();
for (int i = 0; i < 5000; i++) {
TableItem item = new TableItem(table, SWT.NONE);
item.setText(0, "A "+i);
item.setText(1, "B "+i);
item.setText(2, "C "+i);
}
// turn redraw on again after filling table
table.setRedraw(true);
long end = System.currentTimeMillis();
System.out.println("Filling table took "+(end-start)+" milliseconds.");
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
public static void main(String[] args) {
new TableShellExample();
}
}
By turning off redraw before filling and turning it on after filling, this drops to 70 milliseconds on average.
So, just by setting a flag off and then on again, you can make the standard SWT Table more than 10 times faster.
The trick is using the redraw flag correctly. Normally, the redraw flag is set true by default, which means that the widget redraws with any change whatsoever. So, for example, adding a TableColumn or a TableItem (new row) means a redraw. Of course, if you are filling thousands of rows into a table, the performance is usually quite poor.
You can just set the redraw flag to false before filling the table and set it to true after filling it. As an example, take a look at an example, adapted from the snippet here.
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
public class TableShellExample {
Display display;
Shell shell;
TableShellExample() {
display = new Display();
shell = new Shell(display);
shell.setSize(300, 500);
shell.setText("A Table Shell Example");
shell.setLayout(new FillLayout());
Table table = new Table(shell, SWT.BORDER);
TableColumn tc1 = new TableColumn(table, SWT.CENTER);
TableColumn tc2 = new TableColumn(table, SWT.CENTER);
TableColumn tc3 = new TableColumn(table, SWT.CENTER);
tc1.setText("Column 1");
tc2.setText("Column 2");
tc3.setText("Column 3");
tc1.setWidth(80);
tc2.setWidth(80);
tc3.setWidth(80);
table.setHeaderVisible(true);
shell.open();
// turn redraw off before filling table
table.setRedraw(false);
long start = System.currentTimeMillis();
for (int i = 0; i < 5000; i++) {
TableItem item = new TableItem(table, SWT.NONE);
item.setText(0, "A "+i);
item.setText(1, "B "+i);
item.setText(2, "C "+i);
}
// turn redraw on again after filling table
table.setRedraw(true);
long end = System.currentTimeMillis();
System.out.println("Filling table took "+(end-start)+" milliseconds.");
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
public static void main(String[] args) {
new TableShellExample();
}
}
Performance?
Well, on my humble system, the code without switching the redraw off and on took, on average 797 milliseconds.By turning off redraw before filling and turning it on after filling, this drops to 70 milliseconds on average.
So, just by setting a flag off and then on again, you can make the standard SWT Table more than 10 times faster.
Subscribe to:
Posts (Atom)