Lubos Programming Weblog

Stopping or interrupting Java hanging thread

November 15, 2009 · Leave a Comment

As most of Java developers know and experienced, some Java frameworks including core Java libraries do have nasty habit to run for very, very loooong time or hang indefinitely. Classic example is Java regex library which can cause stack overflow, or it can hang indefinitely.

In order to prevent the whole application from hanging and to allow to stop or interrupt the offending hanging thread, I am using timeout thread that checks if the watched thread finished in allotted time, and if it did not the timeout thread interrupts the watched, hanging thread.

Abruptly stopping or interrupting a thread from different thread is not well supported in Java especially when Thread.stop() method was deprecated, see How to stop a thread article.

But the problem is that Java offers nothing better to forcefully interrupt the offending hanging thread. Following is an example code of the TimeoutThread:

package com.lingoport.scanner.util;

import java.util.Date;

/** Stop a thread after a given timeout has elapsed
* <P>
* A simple timeout class.  You give it a thread to watch and a timeout
* in milliseconds.  After the timeout has elapsed, the thread is killed
* with a Thread.stop().  If the thread finishes successfully before then,
* you can cancel the timeout with a done() call; you can also re-use the
* timeout on the same thread with the reset() call.
* <P>
*
*/

public class TimeoutThread implements Runnable {

private final Thread targetThread;
private long millis;
private final Thread watcherThread;
private boolean loop;
private boolean enabled;
private static final boolean TIMEOUT_DISABLED = System.getProperty("disable.timeout") != null;

/**
* Constructor. Give it a thread to watch, and a timeout in milliseconds.
* After the timeout has elapsed, the thread gets killed. If you want
* to cancel the kill, just call done().
*
* @param targetThread
* @param millis
*/
public TimeoutThread(Thread targetThread, long millis) {
this.targetThread = targetThread;
this.millis = millis;
if (TIMEOUT_DISABLED) {
watcherThread = null;
enabled = false;
} else {
watcherThread = new Thread(this);
enabled = true;
watcherThread.start();
// Hack - pause a bit to let the watcher thread get started.
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
}
}

/**
* Constructor, current thread.
*
* @param millis
*/
public TimeoutThread(long millis) {
this(Thread.currentThread(), millis);
}

/**
* Call this when the target thread has finished.
*/
public synchronized void done() {
loop = false;
enabled = false;
notify();
}

/**
* Call this to restart the wait from zero.
*/
public synchronized void reset() {
loop = true;
notify();
}

/**
* Call this to restart the wait from zero with a different timeout value.
*
* @param millis
*/
public synchronized void reset(long millis) {
this.millis = millis;
reset();
}

/*
* The watcher thread - from the Runnable interface.
* This has to be pretty anal to avoid monitor lockup, lost threads, etc.
*
*  (non-Javadoc)
* @see java.lang.Runnable#run()
*/
public synchronized void run() {
if (TIMEOUT_DISABLED) return;
Thread me = Thread.currentThread();
me.setPriority(Thread.MAX_PRIORITY);
if (enabled) {
do {
loop = false;
try {
wait(millis);
} catch (InterruptedException e) {
}
} while (enabled && loop);
}
// The call stop() is deprecated, but Java doesn't offer anything better
if (enabled && targetThread.isAlive()) {
targetThread.stop();
done();
}
}

// Test main
public static void main(String[] args) {
System.out.println((new Date()) + "  Setting ten-second timeout...");
TimeoutThread tk = new TimeoutThread(10000);
try {
double f = 1.;
System.out.println((new Date()) + "  Starting execution of long loop...");
for(double i = 0; i < 1.0E99; i++) f = f * i;
System.out.println((new Date()) + "  Another execution of long loop...");
for(double i = 0; i < 1.0E99; i++) f = f * i;
tk.done();
} catch (Exception e) {
System.out.println((new Date()) + "  Caught Exception");
} catch (ThreadDeath td) {
System.out.println((new Date()) + "  Caught ThreadDeath");
}
System.out.println((new Date()) + "  Finished!");

}

}

This solution seems to be working quite well, and the offending hanging thread (caused for example by Java regex) can catch ThreadDeath exception, recover appropriately and continue work.

The only problem I encountered so far is that it doesn’t play well with Eclipse debugging, that is why I disable the TimoutThread while debugging the application using disable.timeout system property.

I know, that this is not great solution, but it works, and I couldn’t find any better solution (BTW, Thread.interrupt() does not work in this case). Let me know if you have better solution.

 

→ Leave a CommentCategories: java

Why I am not Mac user

September 18, 2009 · Leave a Comment

I have small one man software development consulting company, High Country Computing. Sometimes I need to deliver product(s) that needs to be tested on Apple hardware.
I used to be Apple fan while starting with personal computing in 1988 or so with AppleII. But I switched to Windows and Linux based computers in early 1990ies and never looked back (who would pay $500-$1500 more for inferior hardware ;-) .

Because of need to test software applications on Apple and Mac OSX hardware, I finally caved in and decided to buy Mini Mac. Unfortunately, the experience was terrible and I will not buy any Apple made product any time soon.

I bought Mini Mac from reseller and the Mac didn’t even boot. The only solution I was offered by Apple customer support was to bring it to authorized repair shop, which is quite inconvenient considering I live high in the mountains and I would have to drive over 100 miles (Lenovo, Dell, HP let you ship the computer for repair in their expense). It was my first experience in 15 years with Apple, and I regret buying it, and I will not recommend to my friends or at work (I am part time system administrator for small healthcare provider) to even consider Apple. I contacted Apple customer support for help, but the customer support guy was very, very unhelpful, and he was quite rude. My impression was that Apple support is terrible compared to Lenovo, HP, Dell (have hands on experience with all of them). Fortunately the Mac reseller, where I purchased the Mini Mac, was much more customer friendly than Apple and took the broken Mac back.

See you Apple!

→ Leave a CommentCategories: java

Installing and Uninstalling Windows7

August 15, 2009 · Leave a Comment

I have tried to install Windows7 RC on my HP Pavillion zd7000 laptop (1.25Gb memory, 2×3.0GHz processor) with Windows XP SP3. The installation went OK, the only problem was running Windows7 compatibility check application which hanged and never finished.

The problems came after the install, and there was enough of them to force me to uninstall Windows7 and restore good old Windows XP.
Here is the list of problems:

  • Windows XP cannot be upgraded, it requires full OS install and the install partition has to have at least 6GB free
  • I had hard time to redirect video from laptop to external monitor
  • The Windows7 migration application failed to install, so I was forced to moved the Documents and Setting and Program Files from Windows.old manually (painful)
  • I couldn’t find NVIDIA driver, so the screen resolution was only 1024×768 (XP is 1600×1200)
  • Networking had problems connecting to printer (HP J6400), and to my NAS (WD MyWorldBook), sometimes it worked, sometimes not

Fortunately there is relatively easy way to uninstall Windows7 and restore Windows XP, see this article for details.

Honestly, I am not sure why all the “expert” reviews are so positive, I have Windows XP laptop, another laptop with Windows Vista, and also desktop with Windows Vista (64b). Base on my one day experience I do not see Windows7 being worth upgrading and they are definitely NOT dramatically better than Windows XP or Windows Vista.
I still like Windows XP (they just work), but for last year plus, I mainly use Vista and after disabling UAC, I became Vista fan. It seems to me that the improvements in Windows7 are mainly cosmetic and there are quite a few things (and remind you, it is RC, so maybe they will have time to fix some issues ;-) .

I am system administrator for small business (20+ desktops, 2 servers), and I will stay with Windows XP for as long as I can. No plan for me to upgrade to Windows7 any time soon! I was planning to spend $150 to get the Windows7 family pack for my home computers, but looks like I can now spend the money at Starbucks ;-) .

What is your experience with Windows7?

→ Leave a CommentCategories: java

Creating database schema using JDBC

July 28, 2009 · Leave a Comment

Unfortunately there is no database agnostic way to create database schema in Java using ORM tools like Hibernate, and even JDBC doesn’t offer database agnostic way to create new database schema.

Here is a JDBC code I use to create new database schema for MySql and PostgreSql:


Statement stmt = null;
 Connection con = null;
 try {
 String url = configuration.getProperty("hibernate.connection.url");
 con = getConnection(url,
 configuration.getProperty("hibernate.connection.username"),
 configuration.getProperty("hibernate.connection.password"));

 stmt = con.createStatement();
 if (!con.getMetaData().getTables(null,"mydb","mytable",null).next()){
 if (url.startsWith("jdbc:postgresql")) {
 int count = stmt.executeUpdate("CREATE DATABASE \"MyDb\"  WITH OWNER = " +
 configuration.getProperty("hibernate.connection.username"));
 } else if (url.startsWith("jdbc:mysql")) {
 int count = stmt.executeUpdate("CREATE SCHEMA mydb");
 } else {
 throw new SQLException("DB not supported");
 }
 }
 } catch (Exception e) {
 // log failure
 } finally {
 if (stmt != null) try {stmt.close();} catch (Exception ex) {}
 if (con != null) try {con.close();} catch (Exception ex) {}
 }

private static Connection getConnection(String url, String user, String password) throws SQLException {
 String urlPart = getUrlPart(url);
 return DriverManager.getConnection(urlPart, user, password);
 }

private static String getUrlPart(String url) {
 int idx = url.lastIndexOf('/');
 if (idx < 0) return url;
 String part = url.substring(0, idx);
 if (url.startsWith("jdbc:postgresql")) {
 return part + "/postgres";
 } else if (url.startsWith("jdbc:mysql")) {
 return part + "/mysql";
 }
 return url;
 }

Let me know if you find better way to create database schema in Java.

→ Leave a CommentCategories: java

Platform dependent line separator handling in Swing JTextArea

July 25, 2009 · Leave a Comment

If you wish to support platform dependent line separator handling in Swing JTextArea you have to use its read() and write() methods to load or persist the text in the JTextArea. Internally text area remembers the line separators and converts all of them to \n. When the text area is saved into file using write(), the line separators are converted to its original value.

Here is sample code to read the file into text area:

public class MyTextArea extends JTextArea {
...

try {
 FileInputStream fis = new FileInputStream(sourceFile);
 reader = new InputStreamReader(fis);
 read(reader, null);
} finally {
 if (reader != null) {
 try {
 reader.close();
 } catch (Exception ex) {
 // log exception
 }
 }
 }
}

Here is sample code to write text area into a file:

<pre>
<pre>public class MyTextArea extends JTextArea {
...</pre>
</pre>
try {
 writer = new OutputStreamWriter(new FileOutputStream(newFile));
 write(writer);
 } finally {
 if (writer != null) {
 try {
 writer.close();
 } catch (Exception ex) {
 // log exception
 }
 }
 }
}

Do not read the file content using Reader directly to get the content of the file and than call JTextArea.setText() it will not remember the line separator and it will keep the original line separator in the text area, so for example if the file uses Windows line separator \r\n, you will have to press Delete/Backspace key twice to delete line terminator. Pressing Enter key will insert \n and might cause inconsistent line separators (e.g. mixture of \r\n and \n) in the file when saved.

Do not write the file content using Writer directly to save the content of the text area in the file and after call JTextArea.getText(), it  would save the line separators as they are currently in the text area without converting them to the original state.

Check this thread for more info.

→ Leave a CommentCategories: swing
Tagged: ,

Excellent Groovy presentation

July 25, 2009 · Leave a Comment

Excellent presentation about Groovy patterns highlighting advantages of Groovy:
Seven Groovy usage patterns for Java developers | Software Development Videos

→ Leave a CommentCategories: java

(Re) installing Ruby on Ubuntu

March 26, 2008 · 1 Comment

I ran into trouble on Ubuntu 7.10 and had to reinstall Ruby, It wasn’t smooth sailing, so here is what I did to make ruby and gems work again:

  • sudo apt-get remove gem
  • sudo apt-get remove ruby
  • rm -rf /var/lib/gems
  • rm -rf /usr/lib/ruby
  • sudo apt-get install ruby
  • sudo apt-get install rubygems
  • sudo apt-get install irb
  • sudo apt-get install ri
  • sudo apt-get install rdoc
  • sudo apt-get install ruby1.8-dev
  • sudo apt-get install build-essential
  • sudo gem install rake
  • sudo apt-get install rake
  • sudo gem install ruby-debug-ide
  • sudo gem install hpricot -v 0.5
  • sudo gem install activesuport
  • sudo gem install builder
  • sudo gem install hoe
  • sudo gem install rspec
  • sudo gem install ruby-debug-base
  • sudo gem install ruby-debug-ide

Here is a slightly obsolete link http://wiki.rubyonrails.org/rails/pages/RailsOnUbuntu.

→ 1 CommentCategories: java

Monitor your Java applications using RSS ~ lorecraft

July 26, 2007 · Leave a Comment

→ Leave a CommentCategories: java

Java Scripting in JDK 6.0

February 1, 2007 · Leave a Comment

Java – Java Scripting in JDK 6.0

Java Scripting in JDK 6.0

powered by performancing firefox

→ Leave a CommentCategories: java · scripting

organgrinder: Clustering Lucene

November 6, 2006 · Leave a Comment

→ Leave a CommentCategories: java · search