13. April 2012 · 1 comment · Categories: java, tomcat

After a recent upgrade from Tomcat 6.0.24 to 6.0.35 the tif imaging reader was no longer found by my web application:

JAI tif error

One solution I came across was to disable the JreMemoryLeakPreventionListener in the conf/server.xml file:

Tomcat server.xml

but after reading this informative wiki post (http://wiki.apache.org/tomcat/MemoryLeakProtection) I really didn’t want to do this as memory leaks suck and and commenting out something called Memory Leak Prevention seemed like a bad idea. ¬†One other possible solution i stumbled upon that I did not try was setting the appContextProtection attribute to false rather than completely disabling the listener.

After quite a long time of researching aka googling and experimentation I was able to add a static initializer in my code that forced the container to rescan the classpath and find the readers.

static {
    ImageIO.scanForPlugins();
}

woohoo!

JTable with multiple JComboboxes

I recently was asked to add a column to an existing JTable to display a list of data using a JComboBox. Each row has its own set of data to display. All examples of JComboBox usage within a JTable I could find was for a set of data to be displayed for every row.

In order to see the combobox when both clicking it (editing) and viewing I had to create both a TableCellEditor and a TableCellRenderer.

public class ComboEditor
    extends AbstractCellEditor
    implements TableCellEditor {
    private JComboBox cb = new JComboBox();

    public Component getTableCellEditorComponent(JTable table,
            Object value,
            boolean isSelected,
            int row,
            int column) {
        if (value instanceof String[]) {
            DefaultComboBoxModel m = new DefaultComboBoxModel((String[]) value);
            cb.setModel(m);
            return cb;
        } else {
            return null;
        }
    }

    public Object getCellEditorValue() {
        return cb.getSelectedItem();
    }
}
public class ComboCellRenderer extends DefaultTableCellRenderer {

    /** Creates a new instance of MusicCellRenderer */
    public ComboCellRenderer() {
        setOpaque(false);
        setHorizontalAlignment(SwingConstants.LEFT);
    }

    @Override
    public Component getTableCellRendererComponent(
            JTable table,
            Object value,
            boolean isSelected,
            boolean hasFocus,
            int row,
            int column) {

        if (value instanceof String[]) {
            //don't actually create a new one every time if you don't need to
            final JComboBox cb = new JComboBox(((String[]) value));
            cb.setEditable(false);
            cb.addActionListener(new ActionListener() {

                public void actionPerformed(ActionEvent e) {
                    cb.setSelectedIndex(0);
                }
            });
            setColors(cb, row, isSelected);
            cb.setOpaque(true);
            cb.setFont(table.getFont());
            return cb;
        } else {
            try {
                setText(value.toString());
            } catch (Exception e) {
                setText(null);
            }
        }
        setFont(table.getFont());
        setOpaque(true);
        setColors(this, row, isSelected);
        return this;
    }

I was able to see the comboboxes in the table couldn’t interact with them to get them to drop down. In order to do this I needed to make that column editable by overriding the isCellEditable method.

@Override
public boolean isCellEditable(int row, int col) {
    if (col == COLUMN_COMBO) {
         return true;
    }
    return false;
}

I hate posts that do not include runnable source so here you go.

Source

I am certainly going to tweak this code before I'm done for both memory usage and performance.

After failing to get Giganews Accelerator to run under wine I decided to proceed in getting Pan to run ssl using stunnel.

Here’s how I did it.

First off get stunnel installed:

sudo apt-get install stunnel

Second edit the stunnel.conf

sudo gedit /etc/stunnel/stunnel.conf

Here is mine, replace the news server with yours:

; Sample stunnel configuration file by Michal Trojnara 2002-2006
; Some options used here may not be adequate for your particular configuration
; Please make sure you understand them (especially the effect of chroot jail)

; Certificate/key is needed in server mode and optional in client mode
; cert = /etc/stunnel/mail.pem
;key = /etc/stunnel/mail.pem

; Protocol version (all, SSLv2, SSLv3, TLSv1)
sslVersion = SSLv3

; Some security enhancements for UNIX systems - comment them out on Win32
chroot = /var/lib/stunnel4/
setuid = stunnel4
setgid = stunnel4
; PID is created inside chroot jail
pid = /stunnel4.pid

; Some performance tunings
socket = l:TCP_NODELAY=1
socket = r:TCP_NODELAY=1
;compression = rle

; Workaround for Eudora bug
;options = DONT_INSERT_EMPTY_FRAGMENTS

; Authentication stuff
;verify = 2
; Don't forget to c_rehash CApath
; CApath is located inside chroot jail
;CApath = /certs
; It's often easier to use CAfile
;CAfile = /etc/stunnel/certs.pem
; Don't forget to c_rehash CRLpath
; CRLpath is located inside chroot jail
;CRLpath = /crls
; Alternatively you can use CRLfile
;CRLfile = /etc/stunnel/crls.pem

; Some debugging stuff useful for troubleshooting
debug = 7
output = /var/log/stunnel4/stunnel.log

; Use it for client mode
client = yes

; Service-level configuration

[nntp]
accept = localhost:119
connect = YOUR.NEWSGROUP.HERE:PORT

; [pop3s]
; accept  = 995
; connect = 110

; [imaps]
; accept  = 993
; connect = 143

; [ssmtp]
; accept  = 465
; connect = 25

; [https]
; accept  = 443
; connect = 80
; TIMEOUTclose = 0

; vim:ft=dosini

Edit stunnel4:

sudo gedit /etc/default/stunnel4

Set Enabled=1

# /etc/default/stunnel
# Julien LEMOINE
# September 2003

# Change to one to enable stunnel
ENABLED=1
FILES="/etc/stunnel/*.conf"
OPTIONS=""

# Change to one to enable ppp restart scripts
PPP_RESTART=0

Start stunnel4:

/etc/init.d/stunnel4 start

Fire up Pan and set set your server to localhost on port 119