The Holy Java

Building the right thing, building it right, fast

Posts Tagged ‘error’

Note To Self: What to Do When a Vagrant Machine Stops Working (Destroy or Up Failing)

Posted by Jakub Holý on March 24, 2012

Sometimes “vagrant destroy” fails with an exception from the depths of the virtualbox Ruby gem or vagrant up freezes for a long time only to fail with SSH connection failure message. Here are some tips how to solve such problems.

See also my Vagrant Notes.

Read the rest of this entry »

Posted in Tools | Tagged: , , , | Comments Off

Eclipse Profile configuration: The launch requires at least one data collector

Posted by Jakub Holý on May 13, 2010

I just installed TPTP into my Eclipse 3.5 under Ubuntu 9.04 and tried to profile a class. The Profile Configuration opened with a red warning reading “the launch requires at least one data collector to be selected“. Clicking the configuration’s Monitor tab reveals a more detailed error (and nothing to select):

IWATO435E An error occured when connecting to the host.

A quick check of the error log (Window – Show View – Other… – General – Error Log) reveals the cause:

RAServer generated the following output:  [Error Stream]:ACServer: error while loading shared libraries: /home/jholy/development/tools/eclipse-ide/pulse2-2.4.2/Common/plugins/org.eclipse.tptp.platform.ac.linux_ia32_4.4.202.v201002100300/agent_controller/bin/../lib/libtptpUtils.so.4: file too short

Checking the content of the lib/ folder revealed an interesting thing:

-rw-r–r– 1 jholy jholy   17 2010-02-16 23:16 libtptpUtils.so
-rw-r–r– 1 jholy jholy   21 2010-02-16 23:16 libtptpUtils.so.4
-rwxr-xr-x 1 jholy jholy 100K 2010-02-16 23:16 libtptpUtils.so.4.5.0

As also the content of the two small files suggests (they contain a name of the corresponding file with a longer name), the *.so and *.so.4 files should have been links but the installer failed to create them.

Solution

List all files in the lib/ folder, you will see that there are many real files like libtptpUtils.so.4.5.0 and libxerces-c.so.26.0 and many should-be-links files. The solution is, of course, to replace all those files that shoud be links with actual links.

For me the solution was:

$ cd .../plugins/org.eclipse.tptp.platform.ac.linux_ia32_4.4.202.v201002100300/agent_controller/lib
# Move out the files that are OK
lib$ mkdir tmp
lib$ mv libswt-* libcbe.so tmp/
# Fix the links
lib$ for FILE in `ls *.so`; do ln -sf "${FILE}.4.5.0" $FILE; ln -sf "${FILE}.4.5.0" "${FILE}.4"; done
# Move the correct files back
lib$ mv tmp/* .
lib$ rmdir tmp
# Fix links for files with *.26 instead of *.4.5.0
lib$ ln -sf libxerces-c.so.26.0 libxerces-c.so.26
lib$ ln -sf libxerces-c.so.26.0 libxerces-c.so
lib$ ln -sf libxerces-depdom.so.26.0 libxerces-depdom.so.26
lib$ ln -sf libxerces-depdom.so.26.0 libxerces-depdom.so
lib$ rm libxerces-depdom.so.4 libxerces-c.so.4
# Done!

Try to open the profile configuration now, the IWATO435E should have disappeared and you should be able to select a data collector.

If not, restart Eclipse, try again, check the error log.

My environment

  • Ubuntu 9.04
  • Eclipse 3.5
  • TPTP – see above

Related

There is a similar post of the same problem but with different cause: Get Eclipse TPTP to run on Ubuntu Karmic Koala – the cause was: “the Agent Controller was built against old C++ libraries which were no longer available on my system (Ubuntu 9.10 Karmic Koala, amd64)”.

Posted in eclipse | Tagged: , , , , | Comments Off

A logging wrapper around PreparedStatement to provide detailed info upon error

Posted by Jakub Holý on May 23, 2009

In my java web application I use JDBC to store data in batches into a database. When there is a problem the whole batch insert fails and it’s difficult to find out what data caused it to fail. Therefore I’ve created a wrapper around PreparedStatement that remembers values passed into the various set* methods and can provide a comma-separated listing of all rows in the batch upon failure.

This is my LoggingStatementDecorator that stores values for later logging; based on java.lang.reflect.Proxy:

package eu.ibacz.example;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.PreparedStatement;
import java.util.LinkedList;
import java.util.List;

/**
 * Remember values passed into a sql statement via setString etc. for later logging. 
 */
class LoggingStatementDecorator implements InvocationHandler {
    
    /** File's Subversion info (version etc.). */
    public static final String SVN_ID = "$id$";
    
    private List<List<Object>> batch = new LinkedList<List<Object>>();
    private List<Object> currentRow = new LinkedList<Object>();
    private PreparedStatement target;
    private boolean failed = false;
    
    public LoggingStatementDecorator(PreparedStatement target) {
        if (target == null) throw new IllegalArgumentException("'target' can't be null.");
        this.target = target;
    }


     // @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[]) */
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        
        final Object result; 
        
        try {
            result = method.invoke(target, args);
            failed = false;
        } catch (InvocationTargetException e) {
            failed = true;
            throw e.getTargetException();
        } catch (Exception e) {
            failed = true;
            throw e;
        }
        
        if ( method.getName().startsWith("setNull") 
                && (args.length >=1 && Integer.TYPE == method.getParameterTypes()[0] ) ) {
            handleSetSomething((Integer) args[0], null);
        } else if ( method.getName().startsWith("set") 
                && (args.length >=2 && Integer.TYPE == method.getParameterTypes()[0] ) ) {
            handleSetSomething((Integer) args[0], args[1]);
        } else if ("addBatch".equals(method.getName())) {
            handleAddBatch();
        }
        
        return result;
    }
    
    private void handleSetSomething(int index, Object value) {
        currentRow.add(value);
    }
    
    private void handleAddBatch() {
        batch.add(currentRow);
        currentRow = new LinkedList<Object>();
    }
    
    public List<List<Object>> getValues() {
        return batch;
    }
    
    public PreparedStatement getTarget() { return target; }
    
    /** Has the last method called on the Statement caused an exception? */
    public boolean isFailed() { return failed; }
    
    public String toString() { return "LoggingHandler[failed="+failed+"]"; }
    
    /** Values as comma-separated values. */
    public String getValuesAsCsv() {
        StringBuilder csv = new StringBuilder();
        for (List<Object> row : getValues()) {
            for (Object field : row) {
                // Escape Strings
                if (field instanceof String) {
                    field = "'" + ((String) field).replaceAll("'", "''") + "'";
                }
                csv.append(field).append(",");
            }
            csv.append("\n");
        }
        return csv.toString();
    } /* getValuesAsCsv */
    
    public PreparedStatement createProxy() {
        return (PreparedStatement) Proxy.newProxyInstance(
                PreparedStatement.class.getClassLoader(),
                new Class[] { PreparedStatement.class },
                this);
    };
    
}

And this is how you use it:

        // ...
        PreparedStatement stmt = null;
        try {
            LoggingStatementDecorator stmtHandler = new LoggingStatementDecorator( connection.prepareStatement("insert into mytable values(?,?)") );
            stmt =  stmtHandler.createProxy();
            
            // add data to the batch
            for(int i=0; i<10; ++i) {
                stmt.setInt(1, i);
                stmt.setString(2, "Row number " + i);
                stmt.addBatch();
            }
            
            stmt.executeBatch();
            
        } catch (SQLException e) {
            // ... some rollback etc.
            
            LoggingStatementDecorator stmtHandler = (LoggingStatementDecorator)
                    ((stmt instanceof Proxy)? Proxy.getInvocationHandler(stmt) : null);
                // TODO include the insert sql in the log!!!
                StringBuilder log = new StringBuilder();
                log = buildFailureInfo("mytable", stmtHandler, log);
                LOG.error("Failure while processing data:" + log, e);
            }
        }
            

    private StringBuilder buildFailureInfo(String table, LoggingStatementDecorator stmtHandler, StringBuilder details) {
        
        if (stmtHandler != null && stmtHandler.isFailed()) {
            // Already insertion of records failed
            details.append("\nInsert of records failed. Table=").append(table)
                .append("), values=[\n").append(stmtHandler.getValuesAsCsv()).append("]");
            
        }
        
        return details;
    } /* buildFailureInfo */

When an excepion occures, you get nice log that shall tell you all you need to detect the problem or reproduce it.

Fotnote: Of course I could have perhaps used the open-source P6Spy but I’m afraid it would log more than I need (I believe it to be bound to a data source, not a particular webapp’s PreparedStatement).

Posted in Languages | Tagged: , , , , | Comments Off