<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-4396093936384561136</id><updated>2011-11-27T16:42:09.273-08:00</updated><category term='/'/><title type='text'>No milk in my coffee</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://morningcofee.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://morningcofee.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Frenchie</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>35</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-4396093936384561136.post-119533176294612796</id><published>2011-08-05T02:20:00.000-07:00</published><updated>2011-08-05T02:26:23.526-07:00</updated><title type='text'>How were we successful before OSGI?</title><content type='html'>According to some people discourse it would be a fair question, seems that modularity is impossible before OSGI. Wonder what we have been doing for the last 10 years...&lt;br /&gt;&lt;br /&gt;Mind you, it was impossible to be successful without EJBs. So after sorting our threading issues with a well thought stack, now we have experts sorting our class loader and so far they are doing the same great job...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4396093936384561136-119533176294612796?l=morningcofee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://morningcofee.blogspot.com/feeds/119533176294612796/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4396093936384561136&amp;postID=119533176294612796' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/119533176294612796'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/119533176294612796'/><link rel='alternate' type='text/html' href='http://morningcofee.blogspot.com/2011/08/how-were-we-successful-before-osgi.html' title='How were we successful before OSGI?'/><author><name>Frenchie</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4396093936384561136.post-1520058363003967330</id><published>2011-08-02T08:14:00.000-07:00</published><updated>2011-08-02T08:17:53.076-07:00</updated><title type='text'>Spring ws Saaj vs Axiom</title><content type='html'>Saaj create a lot of contention when manipulating the message - it seems to reload the an file from the class loader every time -, Axiom is much faster under stress.&lt;br /&gt;&lt;br /&gt;to change the message factory create a new one in the application context under the name messageFactory&lt;br /&gt;&lt;br /&gt;&lt;pre&gt; &lt;br /&gt;&lt;br /&gt;&amp;lt;bean name="messageFactory" class="org.springframework.ws.soap.axiom.AxiomSoapMessageFactory"&gt;&lt;br /&gt;&amp;lt;/bean&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4396093936384561136-1520058363003967330?l=morningcofee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://morningcofee.blogspot.com/feeds/1520058363003967330/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4396093936384561136&amp;postID=1520058363003967330' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/1520058363003967330'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/1520058363003967330'/><link rel='alternate' type='text/html' href='http://morningcofee.blogspot.com/2011/08/spring-ws-saaj-vs-axiom.html' title='Spring ws Saaj vs Axiom'/><author><name>Frenchie</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4396093936384561136.post-3982363275851358243</id><published>2009-02-26T04:37:00.001-08:00</published><updated>2009-02-26T04:40:05.854-08:00</updated><title type='text'>Introducing Unit Testing in Legacy code base</title><content type='html'>In big companies, developing a green field project is a rare privilege&lt;br /&gt;... most of the time you will have to develop on a existing code base of&lt;br /&gt;versatile quality - Not due to the skill of the developer more likely to&lt;br /&gt;the history of the project, lack of code review and poor quality focus,&lt;br /&gt;short term vs. long term risk -.&lt;br /&gt;&lt;br /&gt;Anyway if you are not lucky you are facing a big spaghetti monster&lt;br /&gt;calling other pasta entities in ways ranging from CORBA, RV, rmi, EJB,&lt;br /&gt;ftp messaging ... Chances is that the code can't even run on your dev&lt;br /&gt;machine, making development laborious and non productive.&lt;br /&gt;&lt;br /&gt;There are 2 ways to deal with this problem&lt;br /&gt;&lt;br /&gt; 1 Status quo, self explanatory&lt;br /&gt; 2 Introducing unit test, mocking the internal and external monsters&lt;br /&gt;&lt;br /&gt;1 : simple solution, not very rewarding but if the cost of solution 2&lt;br /&gt;overcome the benefit that's the way to go&lt;br /&gt;2 : long term benefit in development and quality. But costly&lt;br /&gt;&lt;br /&gt;Though with a bit of method there are way to make 2 less costly, all you&lt;br /&gt;will need is :&lt;br /&gt;&lt;br /&gt; - A good refactoring dev environment, eclipse or idea&lt;br /&gt; - Junit, XmlUnit&lt;br /&gt; - XStream an xml serializer/desiralizer&lt;br /&gt; - an UAT/Dev environment that runs.&lt;br /&gt;&lt;br /&gt;1 - identify the part the function you need to test&lt;br /&gt;&lt;br /&gt;you won't be able to test all the code, it is important to test a small&lt;br /&gt;chain of the code lest that the mocking will be too complex.&lt;br /&gt;&lt;br /&gt;It's likely that you can identify the function that is the entry and&lt;br /&gt;exit point&lt;br /&gt;&lt;br /&gt;  Object f1(Object... args)&lt;br /&gt;&lt;br /&gt;It is that function that we will try to unit test.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;2 - record samples&lt;br /&gt;&lt;br /&gt;your system is probably generating high complex object, based on high&lt;br /&gt;complex entry. Trying to reproduce the graph manually is laborious and&lt;br /&gt;sure to be incomplete. That's what we need to used XStream to record the&lt;br /&gt;args and the output of the function in a uat environment, getting that&lt;br /&gt;way real life object.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;br /&gt;// the new method that will delegate to the old&lt;br /&gt;// and dump in and out&lt;br /&gt;Object f1(Object... args)  {&lt;br /&gt;  dumpIn(args);&lt;br /&gt;&lt;br /&gt;  Object o  = _f1(args);&lt;br /&gt;&lt;br /&gt;  dumpOut(o);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// was the real&lt;br /&gt;Object _f1(Object args) {&lt;br /&gt;       ...&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;3 - integrate your sample in your unit test&lt;br /&gt;&lt;br /&gt;Now that you have sample with your input parameters and your expected&lt;br /&gt;result you can start writing your unit test.&lt;br /&gt;&lt;br /&gt;4 - mock the external call&lt;br /&gt;&lt;br /&gt;It is likely that once you integrate the sample in the unit test, the&lt;br /&gt;code will need to code external or internal component. you will need to&lt;br /&gt;refactor that code in specific method that you will overwrite for your&lt;br /&gt;test.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;br /&gt;class F {&lt;br /&gt;       Object _f1(Object... args) {&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;               // used to be inline&lt;br /&gt;               Object extInf = getExtInfo();&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;       Object getExtInfo() {&lt;br /&gt;        ....&lt;br /&gt;       }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class FTest extends F {&lt;br /&gt;&lt;br /&gt;       Object getExtInfo() {&lt;br /&gt;        return new MockObject();&lt;br /&gt;       }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;If the object is to complex to Mock you can use the XStream to dump a&lt;br /&gt;sample in uat environment.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;5 - run the test !&lt;br /&gt;&lt;br /&gt;6 - how to improve the solution&lt;br /&gt;&lt;br /&gt;It is possible to create the list of test automatically by scanning the&lt;br /&gt;samples directory e.g.. Making it easier to add sample and extend the&lt;br /&gt;coverage of the test and behaviour.&lt;br /&gt;&lt;br /&gt;This is an iterative process, it is not possible to make everything&lt;br /&gt;testable in one go, take your time and surely step by step the quality&lt;br /&gt;of your code will improve.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4396093936384561136-3982363275851358243?l=morningcofee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://morningcofee.blogspot.com/feeds/3982363275851358243/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4396093936384561136&amp;postID=3982363275851358243' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/3982363275851358243'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/3982363275851358243'/><link rel='alternate' type='text/html' href='http://morningcofee.blogspot.com/2009/02/introducing-unit-testing-in-legacy-code.html' title='Introducing Unit Testing in Legacy code base'/><author><name>Frenchie</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4396093936384561136.post-7191123513410010427</id><published>2008-07-25T05:38:00.000-07:00</published><updated>2008-07-25T05:39:16.763-07:00</updated><title type='text'>Dr. Horrible's Sing-Along Lyrics</title><content type='html'>&lt;a href="http://en.wikiquote.org/wiki/Dr._Horrible's_Sing-Along_Blog"&gt;Here&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4396093936384561136-7191123513410010427?l=morningcofee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://morningcofee.blogspot.com/feeds/7191123513410010427/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4396093936384561136&amp;postID=7191123513410010427' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/7191123513410010427'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/7191123513410010427'/><link rel='alternate' type='text/html' href='http://morningcofee.blogspot.com/2008/07/dr-horribles-sing-along-lyrics.html' title='Dr. Horrible&apos;s Sing-Along Lyrics'/><author><name>Frenchie</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4396093936384561136.post-2472990819758465934</id><published>2008-07-25T01:34:00.001-07:00</published><updated>2008-07-25T01:47:42.119-07:00</updated><title type='text'>The Java Spirit</title><content type='html'>- Composition is better than inheritance&lt;br /&gt;- Constructor are for initialization only&lt;br /&gt;- destructor/finalizer are for debugging only&lt;br /&gt;- Free resource explicitly&lt;br /&gt;- Declare the interface not the type ie List myList; not ArrayList myList&lt;br /&gt;- Optimize on metrics of a real system&lt;br /&gt;- Use a proper development environment&lt;br /&gt;- Don't believe the hype about closure, anonymous inner class cover 90% of the cases&lt;br /&gt;- Properties are private or protected.&lt;br /&gt;- Immutable is your friend.&lt;br /&gt;- Don't pool object, we are in the 21st century&lt;br /&gt;- Elegant code is code that is meaningful&lt;br /&gt;- the most useful api are : Collections, common-lang, java.text&lt;br /&gt;&lt;br /&gt;... To be continued&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4396093936384561136-2472990819758465934?l=morningcofee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://morningcofee.blogspot.com/feeds/2472990819758465934/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4396093936384561136&amp;postID=2472990819758465934' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/2472990819758465934'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/2472990819758465934'/><link rel='alternate' type='text/html' href='http://morningcofee.blogspot.com/2008/07/java-spirit.html' title='The Java Spirit'/><author><name>Frenchie</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4396093936384561136.post-1317630858573894436</id><published>2008-06-11T07:04:00.000-07:00</published><updated>2008-06-11T07:08:45.399-07:00</updated><title type='text'>Too many open file descriptors, leak detection</title><content type='html'>In Java it is good practice to manually free the resources such as Streams, Connection. This is the consequence of the non deterministic property of the Garbage Collector. You object that is not reference might wait minutes before being process - or might even never -, so you can rely and the destructor - the finalize method - to do that - the finalizer make the collection of the object really costly-.&lt;br /&gt;&lt;br /&gt;So if you open a Stream you should ideally do that :&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;InputStream is = null&lt;br /&gt;try {&lt;br /&gt;  is = new FileInputStream(...);&lt;br /&gt;  &lt;br /&gt;  ...&lt;br /&gt;&lt;br /&gt;} finally {&lt;br /&gt;  if (is != null) {&lt;br /&gt;    try { is.close(); ) catch(Exception e) { // IGNORE }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;That's a lot of boiler plate code, and it's probably a good idea to use a Template pattern for that - look af Spring JDBCTemplate for example -.&lt;br /&gt;&lt;br /&gt;What happen if you don't do that? That depends on how many file you are gonna open.  It's really likely that the object is gonna get GC and FileInputStream as a finalizer where it closed itself.&lt;br /&gt;&lt;br /&gt;But if your application uses file intensively you might end up with "Too many open file descriptors" errors. If you're lucky you have few entry points where stream are open, so you can easily fix it. Otherwise you will need a way to take the part of the code that are erronous. &lt;br /&gt;&lt;br /&gt;What I propose under is to use &lt;a href="http://www.csg.is.titech.ac.jp/~chiba/javassist/"&gt;Javassist&lt;/a&gt; to instrument the FileInputStrean and FileOutputStream class.&lt;br /&gt;&lt;br /&gt;First we need a class that we would inject into the FileXStream to capture the states and detect the leaks.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;package io;&lt;br /&gt;&lt;br /&gt;public class LeakDetector {&lt;br /&gt; &lt;br /&gt; private boolean closed;&lt;br /&gt; private Exception trace;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; public LeakDetector() {&lt;br /&gt;  trace = new Exception();&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; public void close() {&lt;br /&gt;  this.closed = true;&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; protected void finalize() {&lt;br /&gt;  if (! closed) {&lt;br /&gt;   printAlert();&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; private void printAlert() {&lt;br /&gt;  if (System.err != null) {&lt;br /&gt;   System.err.println("LeakDetector detected a leak from the object open at the following trace :");&lt;br /&gt;   trace.printStackTrace();&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Then we need a class that instruments the FileXStreams&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;package io;&lt;br /&gt;&lt;br /&gt;import java.io.IOException;&lt;br /&gt;import java.util.concurrent.Callable;&lt;br /&gt;&lt;br /&gt;import javassist.CannotCompileException;&lt;br /&gt;import javassist.ClassPool;&lt;br /&gt;import javassist.CtClass;&lt;br /&gt;import javassist.CtConstructor;&lt;br /&gt;import javassist.CtField;&lt;br /&gt;import javassist.CtMethod;&lt;br /&gt;import javassist.NotFoundException;&lt;br /&gt;&lt;br /&gt;public class Instrumenter implements Callable&amp;lt;Object&amp;gt; {&lt;br /&gt;&lt;br /&gt; private String[] clazzes;&lt;br /&gt; &lt;br /&gt; public Instrumenter(String[] args) {&lt;br /&gt;  this.clazzes = args;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public static void main(String[] args) throws Exception {&lt;br /&gt;  &lt;br /&gt;  if (args == null || args.length == 0) {&lt;br /&gt;   args = new String[] { "java.io.FileInputStream", &lt;br /&gt;     "java.io.FileOutputStream" };&lt;br /&gt;  }&lt;br /&gt; &lt;br /&gt;  new Instrumenter(args).call();&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public Object call() throws NotFoundException, CannotCompileException, IOException {&lt;br /&gt;  ClassPool pool = ClassPool.getDefault();&lt;br /&gt;  for(String clazz : clazzes) {&lt;br /&gt;   instrument(clazz, pool);&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  return null;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; private void instrument(String clazz, ClassPool pool) throws NotFoundException, CannotCompileException, IOException {&lt;br /&gt;  CtClass ctClass = pool.get(clazz);&lt;br /&gt;  &lt;br /&gt;  ctClass.addField(CtField.make("private io.LeakDetector __io_ld;", ctClass));&lt;br /&gt;  &lt;br /&gt;  for(CtConstructor cConst : ctClass.getConstructors()) {&lt;br /&gt;   cConst.insertBefore("__io_ld = new io.LeakDetector();");&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  for(CtMethod cMethod : ctClass.getMethods()) {&lt;br /&gt;   if (cMethod.getName().equals("close")) {&lt;br /&gt;    cMethod.insertBefore("__io_ld.close();");&lt;br /&gt;   } else if (cMethod.getName().equals("finalize")) {&lt;br /&gt;    cMethod.insertBefore("__io_ld._finalize();");&lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  ctClass.writeFile("bin/java");&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This class write the new FileInputStream in the bin/java directory. We need do assemble the LeakDetector and the new FileInputStream, FileOutputStream under the same jar. all you need to next is to run your application with the "-Xbootclasspath/p:leakdetector.jar" on the command line.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Note: Applications that use this technique for the purpose of overriding a system class in rt.jar should not be deployed as doing so would contravene the Java 2 Runtime Environment binary code license.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;If you run the following code, with the bootclasspath set : &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;import java.io.FileInputStream;&lt;br /&gt;import java.io.FileOutputStream;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;public class DodgyIOClass {&lt;br /&gt;&lt;br /&gt; public static void main(String[] args) throws Exception {&lt;br /&gt;  &lt;br /&gt;  &lt;br /&gt;  new FileOutputStream("c:/test.txt");&lt;br /&gt;  &lt;br /&gt;  new FileInputStream("c:/test.txt");&lt;br /&gt;  &lt;br /&gt;  &lt;br /&gt;  Thread.sleep(3000);&lt;br /&gt;  System.gc();&lt;br /&gt;  Thread.sleep(3000);&lt;br /&gt;  &lt;br /&gt;  &lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;It should prints :&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;LeakDetector detected a leak from the object open at the following trace :&lt;br /&gt;java.lang.Exception&lt;br /&gt; at io.LeakDetector.&amp;lt;init&amp;gt;(LeakDetector.java:11)&lt;br /&gt; at java.io.FileOutputStream.&amp;lt;init&amp;gt;(FileOutputStream.java)&lt;br /&gt; at java.io.FileOutputStream.&amp;lt;init&amp;gt;(FileOutputStream.java:70)&lt;br /&gt; at DodgyIOClass.main(DodgyIOClass.java:10)&lt;br /&gt;LeakDetector detected a leak from the object open at the following trace :&lt;br /&gt;java.lang.Exception&lt;br /&gt; at io.LeakDetector.&amp;lt;init&amp;gt;(LeakDetector.java:11)&lt;br /&gt; at java.io.FileInputStream.&amp;lt;init&amp;gt;(FileInputStream.java)&lt;br /&gt; at java.io.FileInputStream.&amp;lt;init&amp;gt;(FileInputStream.java:66)&lt;br /&gt; at DodgyIOClass.main(DodgyIOClass.java:12)&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4396093936384561136-1317630858573894436?l=morningcofee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://morningcofee.blogspot.com/feeds/1317630858573894436/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4396093936384561136&amp;postID=1317630858573894436' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/1317630858573894436'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/1317630858573894436'/><link rel='alternate' type='text/html' href='http://morningcofee.blogspot.com/2008/06/too-many-open-file-descriptors-leak.html' title='Too many open file descriptors, leak detection'/><author><name>Frenchie</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4396093936384561136.post-8167586886096063904</id><published>2008-04-02T08:10:00.000-07:00</published><updated>2008-04-02T08:12:39.834-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='/'/><title type='text'>JSR 203 NIO 2 in Java 7</title><content type='html'>&lt;a href="http://blogs.sun.com/rajendrag/entry/jsr_203_new_file_system" &gt;So it seems&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;That would be probably one of the most awaited fix, a well design file system api.&lt;br /&gt;&lt;br /&gt;no more &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;if (!file.delete())  {&lt;br /&gt; // delete did not work but I don't know why &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4396093936384561136-8167586886096063904?l=morningcofee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://morningcofee.blogspot.com/feeds/8167586886096063904/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4396093936384561136&amp;postID=8167586886096063904' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/8167586886096063904'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/8167586886096063904'/><link rel='alternate' type='text/html' href='http://morningcofee.blogspot.com/2008/04/jsr-203-nio-2-in-java-7.html' title='JSR 203 NIO 2 in Java 7'/><author><name>Frenchie</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4396093936384561136.post-1029933802223540440</id><published>2008-03-28T09:22:00.000-07:00</published><updated>2008-03-28T09:23:46.913-07:00</updated><title type='text'>Java performance improvements touted</title><content type='html'>&lt;a href="http://www.infoworld.com/article/08/03/26/java-speed_1.html" &gt;&lt;i&gt;&lt;br /&gt;&lt;b&gt;Java is not the slowpoke of old days and performance now matches or exceeds applications developed in C&lt;/b&gt;, technologists stressed Wednesday during a presentation at TheServerSide Java Symposium in Las Vegas.&lt;br /&gt;&lt;/i&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;From : &lt;a href="http://www.dzone.com/links/rss/java_performance_improvements_touted_infoworld_ne.html"&gt;DZone&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Nice to see that written again.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4396093936384561136-1029933802223540440?l=morningcofee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://morningcofee.blogspot.com/feeds/1029933802223540440/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4396093936384561136&amp;postID=1029933802223540440' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/1029933802223540440'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/1029933802223540440'/><link rel='alternate' type='text/html' href='http://morningcofee.blogspot.com/2008/03/java-performance-improvements-touted.html' title='Java performance improvements touted'/><author><name>Frenchie</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4396093936384561136.post-973374902577386972</id><published>2008-03-14T03:01:00.000-07:00</published><updated>2008-03-14T03:03:07.904-07:00</updated><title type='text'>IE 6 display = 'none' not working</title><content type='html'>see &lt;a href="http://www.dynamicdrive.com/forums/showthread.php?t=6846"&gt;Here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Using &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  element.style.display = '' &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;instead solve the problem&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4396093936384561136-973374902577386972?l=morningcofee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://morningcofee.blogspot.com/feeds/973374902577386972/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4396093936384561136&amp;postID=973374902577386972' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/973374902577386972'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/973374902577386972'/><link rel='alternate' type='text/html' href='http://morningcofee.blogspot.com/2008/03/ie-6-display-none-not-working.html' title='IE 6 display = &apos;none&apos; not working'/><author><name>Frenchie</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4396093936384561136.post-7767979244056680102</id><published>2008-03-14T02:48:00.001-07:00</published><updated>2008-03-14T02:49:08.437-07:00</updated><title type='text'>How to disable escaping in xslt</title><content type='html'>&lt;pre&gt;&lt;br /&gt; &amp;lt;xsl:text disable-output-escaping="yes"&gt;&amp;lt;!--&amp;lt;/xsl:text&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4396093936384561136-7767979244056680102?l=morningcofee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://morningcofee.blogspot.com/feeds/7767979244056680102/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4396093936384561136&amp;postID=7767979244056680102' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/7767979244056680102'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/7767979244056680102'/><link rel='alternate' type='text/html' href='http://morningcofee.blogspot.com/2008/03/how-to-disble-escaping-in-xslt.html' title='How to disable escaping in xslt'/><author><name>Frenchie</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4396093936384561136.post-1540466182070564831</id><published>2008-03-05T08:53:00.000-08:00</published><updated>2008-03-05T08:56:48.272-08:00</updated><title type='text'>NIO / IO debates</title><content type='html'>More NIO / IO benchmark or evidence &lt;br /&gt;&lt;br /&gt;&lt;a href="http://paultyma.blogspot.com/2008/03/writing-java-multithreaded-servers.html" &gt;Writing Java Multithreaded Servers - whats old is new (PDF Slides)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;See &lt;a href="http://morningcofee.blogspot.com/2007/12/micro-benchmark-channel-vs-inputstream_04.html" &gt;Micro benchmark Channel vs InputStream / 2&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4396093936384561136-1540466182070564831?l=morningcofee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://morningcofee.blogspot.com/feeds/1540466182070564831/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4396093936384561136&amp;postID=1540466182070564831' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/1540466182070564831'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/1540466182070564831'/><link rel='alternate' type='text/html' href='http://morningcofee.blogspot.com/2008/03/nio-io-debates.html' title='NIO / IO debates'/><author><name>Frenchie</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4396093936384561136.post-5492759471938824099</id><published>2008-01-24T01:25:00.001-08:00</published><updated>2008-01-24T01:26:22.671-08:00</updated><title type='text'>String sorting tip</title><content type='html'>Good tip &lt;a href="http://blogs.sun.com/CoreJavaTechTips/entry/sorting_strings"&gt;here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;br /&gt; Collator esCollator =&lt;br /&gt;   Collator.getInstance(new Locale("es"));&lt;br /&gt; Collections.sort(list, esCollator);&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4396093936384561136-5492759471938824099?l=morningcofee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://morningcofee.blogspot.com/feeds/5492759471938824099/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4396093936384561136&amp;postID=5492759471938824099' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/5492759471938824099'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/5492759471938824099'/><link rel='alternate' type='text/html' href='http://morningcofee.blogspot.com/2008/01/string-sorting-tip.html' title='String sorting tip'/><author><name>Frenchie</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4396093936384561136.post-491578277953767509</id><published>2008-01-05T04:13:00.000-08:00</published><updated>2008-04-30T06:04:03.066-07:00</updated><title type='text'>Image Resizer for widescreen picture frame and the main color problem</title><content type='html'>-- UPDate&lt;br /&gt;http://www.comesolvego.com/2008/04/29/resize-images-with-java-high-quality-and-working-solution/&lt;br /&gt;--&lt;br /&gt;&lt;br /&gt;For Xmas I receive a picture frame, unfortunately the image is expanded&lt;br /&gt;to the size of the frame without respecting the ratio.&lt;br /&gt;&lt;br /&gt;I try to find a batch solution to resize and fit the picture so that it&lt;br /&gt;would not be deformed.&lt;br /&gt;&lt;br /&gt;I did not find anything so I decided to try to write a small java&lt;br /&gt;program to do it.&lt;br /&gt;it would take the picture resize it so it fit in the frame and put it&lt;br /&gt;center in a image the size of the frame.&lt;br /&gt;&lt;br /&gt;It was relatively easy.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;package org.srf;&lt;br /&gt;&lt;br /&gt;import java.awt.Color;&lt;br /&gt;import java.awt.Graphics2D;&lt;br /&gt;import java.awt.Rectangle;&lt;br /&gt;import java.awt.RenderingHints;&lt;br /&gt;import java.awt.image.BufferedImage;&lt;br /&gt;&lt;br /&gt;public class FitImage {&lt;br /&gt;&lt;br /&gt; public BufferedImage  scaleImage(BufferedImage image, int width, int height) throws Exception {&lt;br /&gt;&lt;br /&gt;  int originalHeight = image.getHeight();&lt;br /&gt;  int originalWidth = image.getWidth();&lt;br /&gt;  &lt;br /&gt;  &lt;br /&gt;  double scale = Math.min(&lt;br /&gt;    height/ (double)originalHeight,&lt;br /&gt;    originalWidth/ (double)originalWidth&lt;br /&gt;  );&lt;br /&gt;  &lt;br /&gt;  int newWidth = (int)Math.round(scale * originalWidth);&lt;br /&gt;  int newHeight = (int)Math.round(scale * originalHeight);&lt;br /&gt;  &lt;br /&gt;  &lt;br /&gt;  // Draw the scaled image&lt;br /&gt;  BufferedImage thumbImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB);&lt;br /&gt;  &lt;br /&gt;  Graphics2D graphics2D = thumbImage.createGraphics();&lt;br /&gt;  graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION,&lt;br /&gt;    RenderingHints.VALUE_INTERPOLATION_BILINEAR);&lt;br /&gt;  &lt;br /&gt;  graphics2D.drawImage(image, 0, 0, newWidth, newHeight,&lt;br /&gt;    null);&lt;br /&gt;&lt;br /&gt;  return thumbImage;&lt;br /&gt;&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; public BufferedImage frameImage(BufferedImage image, int width, int height, Color backgroundColor) throws Exception {&lt;br /&gt;  &lt;br /&gt;  int paddingX = (width - image.getWidth()) / 2;&lt;br /&gt;  int paddingY = (height - image.getHeight()) / 2;&lt;br /&gt;&lt;br /&gt;  &lt;br /&gt;  // Draw the scaled image&lt;br /&gt;  BufferedImage thumbImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);&lt;br /&gt;  &lt;br /&gt;  &lt;br /&gt;  Graphics2D graphics2D = thumbImage.createGraphics();&lt;br /&gt;  &lt;br /&gt;  graphics2D.setColor(backgroundColor);&lt;br /&gt;  &lt;br /&gt;  graphics2D.fill(new Rectangle(0, 0, width, height));&lt;br /&gt;  &lt;br /&gt;  graphics2D.drawImage(image, paddingX, paddingY, null);&lt;br /&gt;&lt;br /&gt;  return thumbImage;&lt;br /&gt;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Then what color do I want to draw the border. The average color of the&lt;br /&gt;picture? does not seems right if you have a picture with blue and green&lt;br /&gt;you might end up with a yellow ...&lt;br /&gt;&lt;br /&gt;So what about the dominant colour ? the main colour of the picture ?&lt;br /&gt;That quite a fusy concept like that. The color are distributed in a 4&lt;br /&gt;dimension space (red, green, blue, alpha) what would that mean to be the&lt;br /&gt;dominant color? What would be an efficient algorythm to determine it.&lt;br /&gt;&lt;br /&gt;I came up with something that give relatively good result also not sure&lt;br /&gt;about the validity of it.&lt;br /&gt;&lt;br /&gt;It iteratively cut the spaces in 2^4 boxes and keep the one where there&lt;br /&gt;is most color.&lt;br /&gt;It does the same thing on this box reduce it a specific number of time.&lt;br /&gt;As the color are define by a number between 0-256, each iteration&lt;br /&gt;dividing the solution possibilite by to, in 8 iteration I arrived to a&lt;br /&gt;result. What does it mean not sure... but on test I did it seems to work&lt;br /&gt;fine.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;package org.srf;&lt;br /&gt;&lt;br /&gt;import java.awt.Color;&lt;br /&gt;import java.awt.image.BufferedImage;&lt;br /&gt;&lt;br /&gt;public class ColorHelper {&lt;br /&gt; private boolean discardPixelOutOfTheBox = true;&lt;br /&gt; private boolean shiftRange = false;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; public void setDiscardPixelOutOfTheBox(boolean discardPixelOutOfTheBox) {&lt;br /&gt;  this.discardPixelOutOfTheBox = discardPixelOutOfTheBox;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; public void setShiftRange(boolean shiftRange) {&lt;br /&gt;  this.shiftRange = shiftRange;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; public Color getMainColor(BufferedImage image, int refineTo) {&lt;br /&gt;  Color c = null;&lt;br /&gt;  &lt;br /&gt;  int[] rgbs = image.getRGB(0, 0, image.getWidth(), image.getHeight(), null, 0, image.getWidth());&lt;br /&gt;  &lt;br /&gt;  &lt;br /&gt;  int[][] colorRanges = new int[][]{ {0, 0xFF}, {0, 0xFF},{0, 0xFF}, {0, 0xFF}};&lt;br /&gt;  &lt;br /&gt;  for(int refine = 0; refine &lt; refineTo ; refine++) {&lt;br /&gt;   int[] colorSpace = new int[2 * 2 * 2 * 2];&lt;br /&gt;   for(int rgb : rgbs) {&lt;br /&gt;    int gi = calculateSpacePoint(colorRanges, rgb);&lt;br /&gt;    if (gi != -1 ) {&lt;br /&gt;     colorSpace[gi] ++;&lt;br /&gt;    }&lt;br /&gt;   }&lt;br /&gt;   &lt;br /&gt;   int ci = calculateSpacePointWinner(colorSpace);&lt;br /&gt;   &lt;br /&gt;   shrinkSpace(colorRanges, ci);&lt;br /&gt;   &lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  int[] crgbs = new int[4]; &lt;br /&gt;  // take middle of colorRange&lt;br /&gt;  for(int i = 0; i &lt; colorRanges.length; i++) {&lt;br /&gt;   int[] range = colorRanges[i];&lt;br /&gt;   crgbs[i] =  (range[0] +  range[1]) /2  ;&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  c = new Color(crgbs[2],crgbs[1],crgbs[0],   crgbs[3]);&lt;br /&gt;  &lt;br /&gt;  return c;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; private int calculateSpacePointWinner(int[] colorSpace) {&lt;br /&gt;  int ci = 0;&lt;br /&gt;  int ciValue = 0;&lt;br /&gt;  for(int i = 0; i &lt; colorSpace.length; i++) {&lt;br /&gt;   if (colorSpace[i] &gt; ciValue) {&lt;br /&gt;    ci = i;&lt;br /&gt;    ciValue = colorSpace[i];&lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt;  return ci;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; private int calculateSpacePoint(int[][] colorRanges, int rgb) {&lt;br /&gt;  int gi = 0;&lt;br /&gt;  for(int i = 0; gi != - 1 &amp;&amp; i &lt; 4; i++) {&lt;br /&gt;   int v  = (rgb &gt;&gt; (i * 8)) &amp; 0xFF;&lt;br /&gt;   &lt;br /&gt;   if (!discardPixelOutOfTheBox &lt;br /&gt;     || (v &gt;= colorRanges[i][0] &amp;&amp; v &lt;= colorRanges[i][1])) {&lt;br /&gt;    int rangeMiddle = (colorRanges[i][0] + colorRanges[i][1]) / 2;&lt;br /&gt;    &lt;br /&gt;    int vi = v &lt; rangeMiddle ? 0:1;&lt;br /&gt;    &lt;br /&gt;    gi |=  vi &lt;&lt; i;&lt;br /&gt;   } else {&lt;br /&gt;    gi = -1;&lt;br /&gt;   }&lt;br /&gt;   &lt;br /&gt;  }&lt;br /&gt;  return gi;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; private void shrinkSpace(int[][] colorRanges, int ci) {&lt;br /&gt;  // re-adjust colorRange&lt;br /&gt;  for(int i = 0; i &lt; colorRanges.length; i++) {&lt;br /&gt;   int[] range = colorRanges[i];&lt;br /&gt;   int cri = (ci &gt;&gt; i ) &amp; 0x1;&lt;br /&gt;   &lt;br /&gt;   shrinkDimension(range, cri);&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; private void shrinkDimension(int[] range, int cri) {&lt;br /&gt;  int rangeShift = shiftRange  ? (range[1] - range[0]) /4 : 0;&lt;br /&gt;  int middleRange = (range[0] +  range[1]) /2;&lt;br /&gt;  if (cri == 0) {&lt;br /&gt;   range[1] =  middleRange + rangeShift ;&lt;br /&gt;  } else {&lt;br /&gt;   range[0] = middleRange - rangeShift;&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4396093936384561136-491578277953767509?l=morningcofee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://morningcofee.blogspot.com/feeds/491578277953767509/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4396093936384561136&amp;postID=491578277953767509' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/491578277953767509'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/491578277953767509'/><link rel='alternate' type='text/html' href='http://morningcofee.blogspot.com/2008/01/mage-resizer-for-widescreen-picture.html' title='Image Resizer for widescreen picture frame and the main color problem'/><author><name>Frenchie</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4396093936384561136.post-4110108514171027072</id><published>2007-12-11T01:38:00.000-08:00</published><updated>2007-12-11T01:39:24.889-08:00</updated><title type='text'>XML/Castor notes 1</title><content type='html'>Marshal to a document object&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;br /&gt; Document serializeObject(Object o) throws Exception {&lt;br /&gt;&lt;br /&gt;  DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();&lt;br /&gt;  &lt;br /&gt;  Document document = documentBuilder.newDocument();&lt;br /&gt;  &lt;br /&gt;  Marshaller marshaller = new Marshaller(d);&lt;br /&gt;  &lt;br /&gt;  synchronized (mapping) {&lt;br /&gt;   marshaller.setMapping(mapping);&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  marshaller.marshal(o);&lt;br /&gt;  &lt;br /&gt;  return document;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Write the Document to an xml file&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;br /&gt; void write(Document doc, File f) throws Exception {&lt;br /&gt;  Transformer trans = TransformerFactory.newInstance().newTransformer();&lt;br /&gt;  &lt;br /&gt;  Source source = new DOMSource(doc);&lt;br /&gt;  Result result = new StreamResult(new FileOutputStream(f));&lt;br /&gt;  &lt;br /&gt;  trans.transform(source, result);&lt;br /&gt;  &lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4396093936384561136-4110108514171027072?l=morningcofee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://morningcofee.blogspot.com/feeds/4110108514171027072/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4396093936384561136&amp;postID=4110108514171027072' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/4110108514171027072'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/4110108514171027072'/><link rel='alternate' type='text/html' href='http://morningcofee.blogspot.com/2007/12/xmlcastor-notes-1.html' title='XML/Castor notes 1'/><author><name>Frenchie</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4396093936384561136.post-8415037155275251110</id><published>2007-12-10T04:34:00.001-08:00</published><updated>2007-12-10T04:37:24.464-08:00</updated><title type='text'>Acegi 2</title><content type='html'>&lt;a href="http://blog.interface21.com/main/2007/12/06/whats-new-in-spring-security-2/" &gt;does not kill fairy by murder anymore.&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4396093936384561136-8415037155275251110?l=morningcofee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://morningcofee.blogspot.com/feeds/8415037155275251110/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4396093936384561136&amp;postID=8415037155275251110' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/8415037155275251110'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/8415037155275251110'/><link rel='alternate' type='text/html' href='http://morningcofee.blogspot.com/2007/12/acegi-2.html' title='Acegi 2'/><author><name>Frenchie</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4396093936384561136.post-5117738860226710451</id><published>2007-12-10T03:00:00.000-08:00</published><updated>2007-12-10T03:02:04.706-08:00</updated><title type='text'>Map &amp; Reduce explained for dummies</title><content type='html'>&lt;a href="http://www.joelonsoftware.com/items/2006/08/01.html" &gt;Can Your Programming Language Do This?&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Also I'm quite sure the cost of doing it in java is overrated - what about anonymous class, used in the common collection for example - ... This is a nice piece of explanation.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4396093936384561136-5117738860226710451?l=morningcofee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://morningcofee.blogspot.com/feeds/5117738860226710451/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4396093936384561136&amp;postID=5117738860226710451' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/5117738860226710451'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/5117738860226710451'/><link rel='alternate' type='text/html' href='http://morningcofee.blogspot.com/2007/12/map-reduce-explained-for-dummies.html' title='Map &amp; Reduce explained for dummies'/><author><name>Frenchie</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4396093936384561136.post-8606573300715465801</id><published>2007-12-06T07:34:00.001-08:00</published><updated>2007-12-06T07:39:50.763-08:00</updated><title type='text'>Interruptible Call</title><content type='html'>In the not so new concurrent api, a call - Executor.call(new Call()) can be cancel by the Future object return. &lt;br /&gt;&lt;br /&gt;Future.cancel(true) is gonna interrupt the thread. But does that mean that your code gonna stop automatically if it already started? Only if it's on a blocking call, which it's quite unlikely. So that your code is interruptible you need to test it the thread has been interrupted.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;   while(test) {&lt;br /&gt;      if (Thread.interrupted()) {&lt;br /&gt;         throw new InterruptedException();&lt;br /&gt;      }&lt;br /&gt;   }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This way your cancel is more reactive.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4396093936384561136-8606573300715465801?l=morningcofee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://morningcofee.blogspot.com/feeds/8606573300715465801/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4396093936384561136&amp;postID=8606573300715465801' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/8606573300715465801'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/8606573300715465801'/><link rel='alternate' type='text/html' href='http://morningcofee.blogspot.com/2007/12/interruptible-call.html' title='Interruptible Call'/><author><name>Frenchie</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4396093936384561136.post-5640362653304895884</id><published>2007-12-04T07:40:00.000-08:00</published><updated>2007-12-04T07:45:17.295-08:00</updated><title type='text'>Micro benchmark Channel vs InputStream / 2</title><content type='html'>If you follow actually the samples like &lt;a href="http://java.sun.com/j2se/1.4.2/docs/guide/nio/example/Grep.java" &gt;Grep&lt;/a&gt;. Channel are slower than the BufferedReader&lt;br /&gt;&lt;br /&gt;On a directory with 16 files, with a total of 42 MB :&lt;br /&gt;nio direct=Time Taken: 3703ms,&lt;br /&gt;nio=Time Taken: 3781ms,&lt;br /&gt;io=Time Taken: 3063ms&lt;br /&gt;&lt;br /&gt;So ?&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; public class NIOReader implements Reader {&lt;br /&gt;&lt;br /&gt;  private ByteBuffer byteBuffer;&lt;br /&gt;  &lt;br /&gt;  public NIOReader(int bufferSize, boolean direct) {&lt;br /&gt;   if (direct) {&lt;br /&gt;    this.byteBuffer = ByteBuffer.allocateDirect(bufferSize);&lt;br /&gt;     &lt;br /&gt;   } else {&lt;br /&gt;    this.byteBuffer = ByteBuffer.allocate(bufferSize);&lt;br /&gt;   }&lt;br /&gt;   &lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public String readFile(File f) throws IOException {&lt;br /&gt;   FileInputStream fis = null;&lt;br /&gt;   FileChannel channel = null;&lt;br /&gt;   &lt;br /&gt;   try {&lt;br /&gt;    fis = new FileInputStream(f);&lt;br /&gt;    &lt;br /&gt;    channel = fis.getChannel();&lt;br /&gt;    &lt;br /&gt;    MappedByteBuffer buffer = channel.map(MapMode.READ_ONLY, 0, channel.size());&lt;br /&gt;    &lt;br /&gt;    CharBuffer charBuffer = Charset.defaultCharset().decode(buffer);&lt;br /&gt;&lt;br /&gt;    return charBuffer.toString();&lt;br /&gt;    &lt;br /&gt;   } finally {&lt;br /&gt;    if (fis != null)&lt;br /&gt;     fis.close();&lt;br /&gt;   }&lt;br /&gt;   &lt;br /&gt;   &lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt; }&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4396093936384561136-5640362653304895884?l=morningcofee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://morningcofee.blogspot.com/feeds/5640362653304895884/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4396093936384561136&amp;postID=5640362653304895884' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/5640362653304895884'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/5640362653304895884'/><link rel='alternate' type='text/html' href='http://morningcofee.blogspot.com/2007/12/micro-benchmark-channel-vs-inputstream_04.html' title='Micro benchmark Channel vs InputStream / 2'/><author><name>Frenchie</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4396093936384561136.post-2106998711846491458</id><published>2007-12-04T02:27:00.000-08:00</published><updated>2007-12-04T02:40:20.267-08:00</updated><title type='text'>Micro benchmark Channel vs InputStream</title><content type='html'>I wrote a little non representative test to check is it was worth rewriting the IO, in an application that write and read a lot of data from the file system, using the not so new NIO api.&lt;br /&gt;&lt;br /&gt;On a directory with containing 8 305 files all around 1 to 4 KB the result are around :&lt;br /&gt;nio direct=Time Taken: 5610ms&lt;br /&gt;nio=Time Taken: 5766ms &lt;br /&gt;io=Time Taken: 5578ms&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;On a directory with 16 files, with a total of 42 MB :&lt;br /&gt;nio direct=Time Taken: 875ms&lt;br /&gt;nio=Time Taken: 906ms&lt;br /&gt;io=Time Taken: 3079ms&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So for big files it's definitly worth it, but not for small file. &lt;br /&gt;&lt;br /&gt;It's tested under windows XP, would the result be the same under a Unix OS? Don't know ...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;br /&gt;import java.io.File;&lt;br /&gt;import java.io.FileInputStream;&lt;br /&gt;import java.io.IOException;&lt;br /&gt;import java.nio.ByteBuffer;&lt;br /&gt;import java.nio.channels.FileChannel;&lt;br /&gt;import java.util.HashMap;&lt;br /&gt;import java.util.Map;&lt;br /&gt;&lt;br /&gt;import junit.framework.TestCase;&lt;br /&gt;&lt;br /&gt;import org.apache.log4j.Logger;&lt;br /&gt;&lt;br /&gt;public class NIOTest  extends TestCase {&lt;br /&gt; &lt;br /&gt; private static Logger  logger= Logger.getLogger(NIOTest.class);&lt;br /&gt; public class NIOReader implements Reader {&lt;br /&gt;&lt;br /&gt;  private ByteBuffer byteBuffer;&lt;br /&gt;  &lt;br /&gt;  public NIOReader(int bufferSize, boolean direct) {&lt;br /&gt;   if (direct) {&lt;br /&gt;    this.byteBuffer = ByteBuffer.allocateDirect(bufferSize);&lt;br /&gt;     &lt;br /&gt;   } else {&lt;br /&gt;    this.byteBuffer = ByteBuffer.allocate(bufferSize);&lt;br /&gt;   }&lt;br /&gt;   &lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public String readFile(File f) throws IOException {&lt;br /&gt;   FileInputStream fis = null;&lt;br /&gt;   FileChannel channel = null;&lt;br /&gt;   StringBuilder sb = new StringBuilder((int)f.length());&lt;br /&gt;   &lt;br /&gt;   try {&lt;br /&gt;    fis = new FileInputStream(f);&lt;br /&gt;    &lt;br /&gt;    channel = fis.getChannel();&lt;br /&gt;    &lt;br /&gt;    &lt;br /&gt;    while(channel.read(byteBuffer) != -1) {&lt;br /&gt;     byteBuffer.flip();&lt;br /&gt;     sb.append(byteBuffer.toString());&lt;br /&gt;     byteBuffer.clear();&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;   } finally {&lt;br /&gt;    if (fis != null)&lt;br /&gt;     fis.close();&lt;br /&gt;   }&lt;br /&gt;   &lt;br /&gt;   &lt;br /&gt;   return sb.toString();&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt; }&lt;br /&gt; public class IOReader implements Reader {&lt;br /&gt;&lt;br /&gt;  private byte[] buffer;&lt;br /&gt;&lt;br /&gt;  public IOReader(int bufferSize) {&lt;br /&gt;   this.buffer = new byte[bufferSize];&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public String readFile(File f) throws IOException {&lt;br /&gt;   FileInputStream fis = null;&lt;br /&gt;   &lt;br /&gt;   StringBuilder sb = new StringBuilder((int)f.length());&lt;br /&gt;   &lt;br /&gt;   try {&lt;br /&gt;    fis = new FileInputStream(f);&lt;br /&gt;    &lt;br /&gt;    int c = -1;&lt;br /&gt;    &lt;br /&gt;    while( (c = fis.read(buffer)) != -1) {&lt;br /&gt;     sb.append(new String(buffer, 0 , c));&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;   } finally {&lt;br /&gt;    if (fis != null)&lt;br /&gt;     fis.close();&lt;br /&gt;   }&lt;br /&gt;   &lt;br /&gt;   &lt;br /&gt;   &lt;br /&gt;   &lt;br /&gt;   return sb.toString();&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; File dir = new File ("C:\\my directory with files");&lt;br /&gt; &lt;br /&gt; int size = 3;&lt;br /&gt; int buffer = 4096;&lt;br /&gt; &lt;br /&gt; public void testIO() throws IOException {&lt;br /&gt;  for (int i = 0 ; i &lt; size; i++) {&lt;br /&gt;   Map&lt;String, StopWatch&gt; stopWatches = new HashMap&lt;String,StopWatch&gt;();&lt;br /&gt;   &lt;br /&gt;   logger.info("test io");&lt;br /&gt;   stopWatches.put("io", testLoop(size, new IOReader(buffer), dir));&lt;br /&gt;   logger.info("test nio");&lt;br /&gt;   stopWatches.put("nio", testLoop(size, new NIOReader(buffer, false), dir));&lt;br /&gt;   logger.info("test nio direct");&lt;br /&gt;   stopWatches.put("nio direct", testLoop(size, new NIOReader(buffer, true), dir));&lt;br /&gt;   &lt;br /&gt;   &lt;br /&gt;   logger.info(stopWatches.toString());&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; public StopWatch testLoop(int size, Reader reader, File dir) throws IOException {&lt;br /&gt;  StopWatch stopWatch = new StopWatch();&lt;br /&gt;  &lt;br /&gt;  stopWatch.start();&lt;br /&gt;  &lt;br /&gt;  for(int i = 0; i &lt; size; i ++) {&lt;br /&gt;   test(reader, dir);&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  stopWatch.stop();&lt;br /&gt;  &lt;br /&gt;  logger.info("end loop " +stopWatch);&lt;br /&gt;  return stopWatch;&lt;br /&gt;  &lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; public void test(Reader r, File dir) throws IOException {&lt;br /&gt;  for(File f: dir.listFiles()) {&lt;br /&gt;   if (f.isFile()) {&lt;br /&gt;    String str = r.readFile(f);&lt;br /&gt;    //logger.debug("read "+ str.length()+" in "+f);&lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; interface Reader {&lt;br /&gt;  String readFile(File f) throws IOException;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4396093936384561136-2106998711846491458?l=morningcofee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://morningcofee.blogspot.com/feeds/2106998711846491458/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4396093936384561136&amp;postID=2106998711846491458' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/2106998711846491458'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/2106998711846491458'/><link rel='alternate' type='text/html' href='http://morningcofee.blogspot.com/2007/12/micro-benchmark-channel-vs-inputstream.html' title='Micro benchmark Channel vs InputStream'/><author><name>Frenchie</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4396093936384561136.post-5383540155554805674</id><published>2007-11-29T09:39:00.001-08:00</published><updated>2007-11-29T09:39:47.412-08:00</updated><title type='text'>7.4 Preventing Castor from checking for a default constructor (since 0.9.5)</title><content type='html'>Sometimes it's useful to prevent Castor from checking for a default constructor, such as when trying to write a mapping for an interface or type-safe enum. You can use the "undocumented" verify-constructable="false" attribute on the &lt;class&gt; element to prevent Castor from looking for the default constructor. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;been looking for this one ...&lt;br /&gt;&lt;a href="http://castor.codehaus.org/xml-mapping.html" &gt;See&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4396093936384561136-5383540155554805674?l=morningcofee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://morningcofee.blogspot.com/feeds/5383540155554805674/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4396093936384561136&amp;postID=5383540155554805674' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/5383540155554805674'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/5383540155554805674'/><link rel='alternate' type='text/html' href='http://morningcofee.blogspot.com/2007/11/74-preventing-castor-from-checking-for.html' title='7.4 Preventing Castor from checking for a default constructor (since 0.9.5)'/><author><name>Frenchie</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4396093936384561136.post-991875526381644589</id><published>2007-11-28T01:36:00.000-08:00</published><updated>2007-11-28T01:37:04.337-08:00</updated><title type='text'>Interesting post ab out Database Partitioning using Spring</title><content type='html'>&lt;a href="http://www.jroller.com/kenwdelong/entry/horizontal_database_partitioning_with_spring" &gt;Horizontal Database Partitioning with Spring and Hibernate&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4396093936384561136-991875526381644589?l=morningcofee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://morningcofee.blogspot.com/feeds/991875526381644589/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4396093936384561136&amp;postID=991875526381644589' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/991875526381644589'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/991875526381644589'/><link rel='alternate' type='text/html' href='http://morningcofee.blogspot.com/2007/11/interesting-post-ab-out-database.html' title='Interesting post ab out Database Partitioning using Spring'/><author><name>Frenchie</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4396093936384561136.post-1882850638841656570</id><published>2007-11-01T06:10:00.000-07:00</published><updated>2007-11-01T06:18:35.815-07:00</updated><title type='text'>Castor elusive StackOverflowError</title><content type='html'>On one of my project, I'm using Casor - 1.1.2.1 - to serialize an object tree to xml. At the beginning of the week I had a weird StackOverflowError when writing a big set of objects. I did not pay much attention do it, was not a priority. &lt;br /&gt;&lt;br /&gt;Today I had the same error, on a very reasonably size object tree. So I try to find where it was comming from - a cycling mapping maybe ... -. I putted my eclipse in debug mode, and add a breakpoint on the error. And then no more SOE ... but a error when setting the mapping in the Marshaller... weird ...&lt;br /&gt;&lt;br /&gt;What can it be? that looks like a multi thread issue... But the Marshaler are both distinct, the only common thing is the Mapping. Could it be ? &lt;br /&gt;So I replaced&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; Marshaller marshaller = new Marshaller(serializer&lt;br /&gt;   .asDocumentHandler());&lt;br /&gt; if (mapping != null) {&lt;br /&gt;     marshaller.setMapping(mapping);&lt;br /&gt; }&lt;br /&gt; marshaller.marshal(o);&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;with &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; Marshaller marshaller = new Marshaller(serializer&lt;br /&gt;   .asDocumentHandler());&lt;br /&gt; if (mapping != null) {&lt;br /&gt;  synchronized (mapping) {&lt;br /&gt;   marshaller.setMapping(mapping);&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt; marshaller.marshal(o);&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And it solve my problem.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Conclusion&lt;/b&gt;&lt;br /&gt;Castor Mapping object is not Thread Safe...&lt;br /&gt;&lt;br /&gt;How weird....&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4396093936384561136-1882850638841656570?l=morningcofee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://morningcofee.blogspot.com/feeds/1882850638841656570/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4396093936384561136&amp;postID=1882850638841656570' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/1882850638841656570'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/1882850638841656570'/><link rel='alternate' type='text/html' href='http://morningcofee.blogspot.com/2007/11/castor-elusive-stackoverflowerror.html' title='Castor elusive StackOverflowError'/><author><name>Frenchie</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4396093936384561136.post-406849925342735405</id><published>2007-09-27T02:11:00.001-07:00</published><updated>2007-09-27T03:33:04.511-07:00</updated><title type='text'>Comparing double with relative precision</title><content type='html'>&lt;pre&gt;&lt;br /&gt;  private static final int DOUBLE_PRECISION = Math.getExponent(0.00000000000001);&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;  public static boolean equalsDouble(double d1, double d2) {&lt;br /&gt;    double diff = Math.abs(d1 - d2);&lt;br /&gt;&lt;br /&gt;    if (diff == 0.0) {&lt;br /&gt;      return true;&lt;br /&gt;    }&lt;br /&gt;  &lt;br /&gt;    int minExp = Math.min(Math.getExponent(d1), Math.getExponent(d2));&lt;br /&gt;  &lt;br /&gt;    int diffExp = Math.getExponent(diff);&lt;br /&gt;  &lt;br /&gt;    int relExp = diffExp - minExp;&lt;br /&gt;  &lt;br /&gt;    return  relExp &lt;= DOUBLE_PRECISION;&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt; &lt;br /&gt; The test :&lt;br /&gt;&lt;br /&gt;&lt;pre&gt; &lt;br /&gt;  public void testDoubleEquals() {&lt;br /&gt;    assertTrue( Utils.equalsDouble(0.0, 0.0));&lt;br /&gt;    assertTrue( Utils.equalsDouble(123.56, 123.56));&lt;br /&gt;    assertTrue( Utils.equalsDouble(15698965.23659898, 15698965.23659898));&lt;br /&gt;&lt;br /&gt;    assertTrue( Utils.equalsDouble(1.000000000000001, 1.000000000000000));&lt;br /&gt;    assertTrue( Utils.equalsDouble(1000000000000001d, 1000000000000000d));&lt;br /&gt;    assertTrue( Utils.equalsDouble(0.000000000000001000000000000001d, 0.000000000000001d));&lt;br /&gt;  &lt;br /&gt;    assertFalse( Utils.equalsDouble(1.00000000000011, 1.00000000000001));&lt;br /&gt;    assertFalse( Utils.equalsDouble(100000000000011d, 100000000000001d));&lt;br /&gt;    assertFalse( Utils.equalsDouble(0.00000000000000100000000000011d, 0.00000000000000100000000000001d));&lt;br /&gt;&lt;br /&gt;    assertFalse( Utils.equalsDouble(15d, 1d));&lt;br /&gt;    assertFalse( Utils.equalsDouble(15d, 15.6d));&lt;br /&gt;&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4396093936384561136-406849925342735405?l=morningcofee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://morningcofee.blogspot.com/feeds/406849925342735405/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4396093936384561136&amp;postID=406849925342735405' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/406849925342735405'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/406849925342735405'/><link rel='alternate' type='text/html' href='http://morningcofee.blogspot.com/2007/09/comparing-double-with-relative.html' title='Comparing double with relative precision'/><author><name>Frenchie</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4396093936384561136.post-5287907882988105316</id><published>2007-09-20T02:24:00.000-07:00</published><updated>2007-09-20T02:26:11.171-07:00</updated><title type='text'>Cursors random walks</title><content type='html'>I was working on an existing database with a simple table like this&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;CREATE TABLE T (&lt;br /&gt; id int,&lt;br /&gt; name varcher(255),&lt;br /&gt; job_id int&lt;br /&gt;)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;there is about 400 rows in this table, and the DB design is quite poor.&lt;br /&gt;&lt;br /&gt;I decided to refactor a procedure that was going through the table T using a counter and assuming that it would match the id. It was working fine but it's kind of hard to imagine a weirder way of parcouring a table. &lt;br /&gt;&lt;br /&gt;It did look like this&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  select @insertRowCount = count(*) from T&lt;br /&gt;    &lt;br /&gt;  while @counter &lt; @insertRowCount&lt;br /&gt;  begin&lt;br /&gt;   select @name = name from T where id = @counter&lt;br /&gt;   &lt;br /&gt;   ...&lt;br /&gt;   &lt;br /&gt;   set @counter = @counter+1&lt;br /&gt;  end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The most obvious modification was using a cursor instead of this counter thing.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  declare Tcursor cursor for &lt;br /&gt;   select  name , id&lt;br /&gt;   from T&lt;br /&gt;&lt;br /&gt;  open jobInfo&lt;br /&gt;&lt;br /&gt;  fetch jobInfo into  @name, @id&lt;br /&gt;&lt;br /&gt;  while(@@sqlstatus=0)&lt;br /&gt;  begin&lt;br /&gt;&lt;br /&gt;   fetch jobInfo into  @name, @id&lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;  close jobInfo&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Looks better, doesn't it?&lt;br /&gt;&lt;br /&gt;except that the cursor did not return all the row ... Kind of weird.&lt;br /&gt;&lt;br /&gt;After a bit of googling I find my answer, it need a unique index, which you've got normaly with a primary key...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  create unique index PK_T on T(id)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;PS: I do know such database is badly design...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4396093936384561136-5287907882988105316?l=morningcofee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://morningcofee.blogspot.com/feeds/5287907882988105316/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4396093936384561136&amp;postID=5287907882988105316' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/5287907882988105316'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/5287907882988105316'/><link rel='alternate' type='text/html' href='http://morningcofee.blogspot.com/2007/09/cursors-random-walks.html' title='Cursors random walks'/><author><name>Frenchie</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4396093936384561136.post-310964634369494077</id><published>2007-08-24T05:17:00.000-07:00</published><updated>2007-08-24T05:23:49.615-07:00</updated><title type='text'>Micro benchmark - Collection sorting</title><content type='html'>What is the most efficient &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;br /&gt;    List&lt;Long&gt; list = new ArrayList&lt;Long&gt;();&lt;br /&gt;    &lt;br /&gt;    for(Long l : array) {&lt;br /&gt;     list.add(l);&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    Collections.sort(list);  &lt;br /&gt;    &lt;br /&gt;    &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Or &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;br /&gt;    TreeSet&lt;Long&gt; list = new TreeSet&lt;Long&gt;();&lt;br /&gt;&lt;br /&gt;    for(Long l : array) {&lt;br /&gt;     list.add(l);&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;After a micro benchmark, on 1000 random arrays of 100 000 element &lt;br /&gt;&lt;br /&gt;&lt;table style="border: 1px solid black;" &gt;&lt;tr&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;Total Time (ms)&lt;/th&gt;&lt;th&gt;Average Time (ms)&lt;/th&gt;&lt;th&gt;Min Time (ms)&lt;/th&gt;&lt;th&gt;Max Time (ms)&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;Collections.sort&lt;/b&gt;&lt;/td&gt;&lt;td style="text-align:right;"&gt;81 893&lt;/td&gt;&lt;td style="text-align:right;"&gt;81&lt;/td&gt;&lt;td style="text-align:right;"&gt;62&lt;/td style="text-align:right;"&gt;&lt;td style="text-align:right;"&gt;125&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;TreeSet&lt;/b&gt;&lt;/td&gt;&lt;td style="text-align:right;"&gt;187 578&lt;/td style="text-align:right;"&gt;&lt;td style="text-align:right;"&gt;187&lt;/td&gt;&lt;td style="text-align:right;"&gt;140&lt;/td&gt;&lt;td style="text-align:right;"&gt;281&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;    &lt;br /&gt;In the Benchmark the Collections.sort takes 43 % of the time that it takes using the Tree.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4396093936384561136-310964634369494077?l=morningcofee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://morningcofee.blogspot.com/feeds/310964634369494077/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4396093936384561136&amp;postID=310964634369494077' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/310964634369494077'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/310964634369494077'/><link rel='alternate' type='text/html' href='http://morningcofee.blogspot.com/2007/08/micro-benchmark-collection-sorting.html' title='Micro benchmark - Collection sorting'/><author><name>Frenchie</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4396093936384561136.post-2787313727519811789</id><published>2007-08-16T01:33:00.001-07:00</published><updated>2007-08-16T01:33:54.962-07:00</updated><title type='text'>Normalization under attack</title><content type='html'>&lt;a href="http://www.infoq.com/news/2007/08/denormalization"&gt;Data normalization, is it really that good?&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4396093936384561136-2787313727519811789?l=morningcofee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://morningcofee.blogspot.com/feeds/2787313727519811789/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4396093936384561136&amp;postID=2787313727519811789' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/2787313727519811789'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/2787313727519811789'/><link rel='alternate' type='text/html' href='http://morningcofee.blogspot.com/2007/08/normalization-under-attack.html' title='Normalization under attack'/><author><name>Frenchie</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4396093936384561136.post-7338672429063097277</id><published>2007-07-02T06:48:00.000-07:00</published><updated>2007-07-02T09:29:21.375-07:00</updated><title type='text'>Xalan-specific output properties nightmare</title><content type='html'>At work we are using Xalan 2.7.0, it works fine except that for some reason we would like to modify a bit the html output method. This method strip the attribute value for readonly and disabled attribute. E.g :&lt;br /&gt;&lt;br /&gt;&lt;div&gt;   &lt;table style="color: rgb(0, 0, 0);" border="1" cellpadding="3" cellspacing="0" width="100%"&gt;     &lt;tbody&gt;     &lt;tr&gt;       &lt;td width="100%"&gt;         &lt;span style="font-family:Courier New;"&gt;&amp;lt;input readonly="readonly" type="checkbox"&amp;gt; &lt;/span&gt;       &lt;/td&gt;     &lt;/tr&gt;     &lt;/tbody&gt;   &lt;/table&gt; &lt;/div&gt; &lt;span style="font-family:Courier New;"&gt;&lt;/span&gt;&lt;br /&gt;is output as&lt;br /&gt;&lt;br /&gt;&lt;div&gt;   &lt;table style="color: rgb(0, 0, 0);" border="1" cellpadding="3" cellspacing="0" width="100%"&gt;     &lt;tbody&gt;     &lt;tr&gt;       &lt;td width="100%"&gt;         &lt;span style="font-family:Courier New;"&gt;&amp;lt;input type="checkbox"&amp;gt; &lt;/span&gt;       &lt;/td&gt;     &lt;/tr&gt;     &lt;/tbody&gt;   &lt;/table&gt; &lt;/div&gt; &lt;span style="font-family:Courier New;"&gt;&lt;/span&gt;&lt;br /&gt;that's fair enough but not the behaviour we need. So I start looking for a way to change that. I quicly found the way the method influence the Serializer. If you like in the output_html.properties you'll find&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;table style="color: rgb(0, 0, 0);" border="1" cellpadding="3" cellspacing="0" width="100%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td width="100%"&gt;&lt;span style="font-family:Courier New;"&gt;# Xalan-specific output properties.  These can be overridden in the stylesheet&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;"&gt;# assigning a xalan namespace.  For example:&lt;/span&gt;  &lt;span style="font-family:Courier New;"&gt;&lt;br /&gt;# &lt;xsl:stylesheet version="1.0"&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;"&gt;#          xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&lt;/span&gt;  &lt;span style="font-family:Courier New;"&gt;&lt;br /&gt;#          xmlns:xalan="http://xml.apache.org/xalan"&gt;&lt;/span&gt;  &lt;span style="font-family:Courier New;"&gt;&lt;br /&gt;# &lt;xsl:output method="html" encoding="UTF-8"&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;"&gt;#              xalan:content-handler="MyContentHandler"/&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;"&gt;#  ...&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;"&gt;# Note that the colon after the protocol needs to be escaped.&lt;/span&gt;&lt;/xsl:output&gt;&lt;/span&gt;&lt;/xsl:stylesheet&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt; &lt;span style="font-family:Courier New;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;"&gt;&lt;/span&gt;That was a great start. So how does the html content handler work ? Would it be possible to easily change its behaviour ? At first I thought so. The code interesting here is in the method protected void processAttribute(java.io.Writer writer, String name, String value, ElemDesc elemDesc) throws IOException&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px solid black" &gt;/**&lt;br /&gt;   * Process an attribute.&lt;br /&gt;   * @param   writer The writer to write the processed output to.&lt;br /&gt;   * @param   name   The name of the attribute.&lt;br /&gt;   * @param   value   The value of the attribute.&lt;br /&gt;   * @param   elemDesc The description of the HTML element&lt;br /&gt;   *           that has this attribute.&lt;br /&gt;   *&lt;br /&gt;   * @throws org.xml.sax.SAXException&lt;br /&gt;   */&lt;br /&gt;  protected void processAttribute(&lt;br /&gt;      java.io.Writer writer,&lt;br /&gt;      String name,&lt;br /&gt;      String value,&lt;br /&gt;      ElemDesc elemDesc)&lt;br /&gt;      throws IOException&lt;br /&gt;  {&lt;br /&gt;      writer.write(' ');&lt;br /&gt;&lt;br /&gt;      if (   ((value.length() == 0) || value.equalsIgnoreCase(name))&lt;br /&gt;          &amp;&amp;amp; elemDesc != null&lt;br /&gt;          &amp;&amp;amp; elemDesc.isAttrFlagSet(name, ElemDesc.ATTREMPTY))&lt;br /&gt;      {&lt;br /&gt;          writer.write(name);&lt;br /&gt;      }&lt;br /&gt;      else&lt;br /&gt;      {&lt;br /&gt;          // %REVIEW% %OPT%&lt;br /&gt;          // Two calls to single-char write may NOT&lt;br /&gt;          // be more efficient than one to string-write...&lt;br /&gt;          writer.write(name);&lt;br /&gt;          writer.write("=\"");&lt;br /&gt;          if (   elemDesc != null&lt;br /&gt;              &amp;&amp;amp; elemDesc.isAttrFlagSet(name, ElemDesc.ATTRURL))&lt;br /&gt;              writeAttrURI(writer, value, m_specialEscapeURLs);&lt;br /&gt;          else&lt;br /&gt;              writeAttrString(writer, value, this.getEncoding());&lt;br /&gt;          writer.write('"');&lt;br /&gt;&lt;br /&gt;      }&lt;br /&gt;  }&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So when the ElemDesc which is defined in the ToHtmlStream got the attribute with the fllag ATTREMPTY it does that. Easy ! so we probably can extend this class and change the behaviour of processAttribute? No! Is there an easy way to change the ElemDesc? No! Maybe we can just copy and past the class? Not really without putting it in the jar, solution a bit to risky because the Xalan Jar is probably shared.&lt;br /&gt;&lt;br /&gt;So the solution? using reflexion to do a deep copy of the specific not very friendly Trie object - we want that only on the specified page -, and create an Handler that gonna delegate to the classic ToHtmlStream to which we are gonna change the root of the Trie object to point to the copy with the modified ElemDesc ... It does work but it's a nightmare of 200 lines of reflexion that used the name of private field of private inner class ...&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px solid black"&gt;&lt;br /&gt;public class NewToHTMLStream implements SerializationHandler {&lt;br /&gt;&lt;br /&gt;    ToHTMLStream stream = null;&lt;br /&gt;&lt;br /&gt;    Object trieCopy = null;&lt;br /&gt;&lt;br /&gt;    static final Set&lt;String&gt; ATTRIBUTES = new HashSet&lt;String&gt;(Arrays.asList(new String[] { "READONLY", "DISABLED" }));&lt;br /&gt;&lt;br /&gt;    static final Object lock = new Object();&lt;br /&gt;&lt;br /&gt;    private static Field fieldm_htmlInfo;&lt;br /&gt;&lt;br /&gt;    private static Field field_trie_root;&lt;br /&gt;&lt;br /&gt;    private static Field field_trie_node_nodes;&lt;br /&gt;&lt;br /&gt;    private static Field field_trie_node_value;&lt;br /&gt;&lt;br /&gt;    private static Field field_m_elementFlags;&lt;br /&gt;&lt;br /&gt;    private static Field field_ElemDesc_m_attrs;&lt;br /&gt;&lt;br /&gt;    private static Field field_ElemDesc_m_Flags;&lt;br /&gt;&lt;br /&gt;    private static Method elementDesc_setAttr;&lt;br /&gt;&lt;br /&gt;    private static Constructor&lt;ElemDesc&gt; eltDescConstructor;&lt;br /&gt;&lt;br /&gt;    private static Constructor nodeConstructor;&lt;br /&gt;&lt;br /&gt;    private static Constructor constructorTrie;&lt;br /&gt;&lt;br /&gt;    private static Field fieldMMap;&lt;br /&gt;&lt;br /&gt;    private static Field fieldMValues;&lt;br /&gt;&lt;br /&gt;    private static Field fieldMFirstFree;&lt;br /&gt;&lt;br /&gt;    public NewToHTMLStream() throws IllegalArgumentException, NoSuchFieldException, IllegalAccessException, SecurityException, NoSuchMethodException, InvocationTargetException, InstantiationException {&lt;br /&gt;&lt;br /&gt;        stream = new ToHTMLStream();&lt;br /&gt;&lt;br /&gt;        synchronized (lock) {&lt;br /&gt;            if (trieCopy == null) {&lt;br /&gt;                trieCopy = copyTrie();&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;br /&gt;        Object htmlInfo = fieldm_htmlInfo.get(stream);&lt;br /&gt;        &lt;br /&gt;        field_trie_root.set(htmlInfo, field_trie_root.get(trieCopy));&lt;br /&gt;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public static Object copyTrie() throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException, SecurityException, NoSuchMethodException, InvocationTargetException, InstantiationException {&lt;br /&gt;        initReflexion();&lt;br /&gt;&lt;br /&gt;        Object m_elementFlags = field_m_elementFlags.get(ToHTMLStream.class);&lt;br /&gt;        Object newTrie = constructorTrie.newInstance(new Object[] { m_elementFlags });&lt;br /&gt;&lt;br /&gt;        Object root = (Object) field_trie_root.get(m_elementFlags);&lt;br /&gt;&lt;br /&gt;        Object newRoot = copyNode(root, newTrie);&lt;br /&gt;&lt;br /&gt;        field_trie_root.set(newTrie, newRoot);&lt;br /&gt;&lt;br /&gt;        return newTrie;&lt;br /&gt;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private static Object copyNode(Object root, Object trie) throws IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException {&lt;br /&gt;        Object copy = nodeConstructor.newInstance(new Object[] { trie });&lt;br /&gt;&lt;br /&gt;        field_trie_node_value.set(copy, copyElementDescription(field_trie_node_value.get(root)));&lt;br /&gt;&lt;br /&gt;        Object[] originalNodes = (Object[]) field_trie_node_nodes.get(root);&lt;br /&gt;        Object[] newNodes = (Object[]) field_trie_node_nodes.get(copy);&lt;br /&gt;&lt;br /&gt;        for (int i = 0; i &lt; originalNodes.length; i++) {&lt;br /&gt;            Object n = originalNodes[i];&lt;br /&gt;            if (n != null) {&lt;br /&gt;                newNodes[i] = copyNode(n, trie);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        return copy;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private static ElemDesc copyElementDescription(Object o) throws IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException {&lt;br /&gt;        if (o == null)&lt;br /&gt;            return null;&lt;br /&gt;&lt;br /&gt;        ElemDesc desc = (ElemDesc) o;&lt;br /&gt;&lt;br /&gt;        ElemDesc desc2 = eltDescConstructor.newInstance(new Object[] { field_ElemDesc_m_Flags.get(desc) });&lt;br /&gt;&lt;br /&gt;        /*&lt;br /&gt;         * m_attrs copy except ATTRIBUTES&lt;br /&gt;         */&lt;br /&gt;&lt;br /&gt;        StringToIntTable m_attrs = (StringToIntTable) field_ElemDesc_m_attrs.get(desc);&lt;br /&gt;&lt;br /&gt;        if (m_attrs != null) {&lt;br /&gt;            String[] m_map = (String[]) fieldMMap.get(m_attrs);&lt;br /&gt;            int[] m_values = (int[]) fieldMValues.get(m_attrs);&lt;br /&gt;            int m_firstFree = (Integer) fieldMFirstFree.get(m_attrs);&lt;br /&gt;&lt;br /&gt;            for (int j = 0; j &lt; m_firstFree; j++) {&lt;br /&gt;                int flag = 0;&lt;br /&gt;                String attributeName = m_map[j];&lt;br /&gt;                if (!ATTRIBUTES.contains(attributeName)) {&lt;br /&gt;                    flag = m_values[j];&lt;br /&gt;                }&lt;br /&gt;&lt;br /&gt;                elementDesc_setAttr.invoke(desc2, new Object[] { attributeName, flag });&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        return desc2;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private static void initReflexion() throws NoSuchFieldException, NoSuchMethodException {&lt;br /&gt;        fieldm_htmlInfo = setAccessible("m_htmlInfo", ToHTMLStream.class);&lt;br /&gt;&lt;br /&gt;        field_m_elementFlags = setAccessible("m_elementFlags", ToHTMLStream.class);&lt;br /&gt;&lt;br /&gt;        constructorTrie = field_m_elementFlags.getType().getDeclaredConstructor(new Class[] { field_m_elementFlags.getType() });&lt;br /&gt;        constructorTrie.setAccessible(true);&lt;br /&gt;&lt;br /&gt;        field_trie_root = setAccessible("m_Root", field_m_elementFlags.getType());&lt;br /&gt;        field_trie_node_nodes = setAccessible("m_nextChar", field_trie_root.getType());&lt;br /&gt;        field_trie_node_value = setAccessible("m_Value", field_trie_root.getType());&lt;br /&gt;&lt;br /&gt;        nodeConstructor = field_trie_root.getType().getDeclaredConstructor(new Class[] { field_m_elementFlags.getType() });&lt;br /&gt;        nodeConstructor.setAccessible(true);&lt;br /&gt;&lt;br /&gt;        field_ElemDesc_m_attrs = setAccessible("m_attrs", ElemDesc.class);&lt;br /&gt;        field_ElemDesc_m_Flags = setAccessible("m_flags", ElemDesc.class);&lt;br /&gt;        elementDesc_setAttr = setAccessible("setAttr", new Class[] { String.class, Integer.TYPE }, ElemDesc.class);&lt;br /&gt;&lt;br /&gt;        eltDescConstructor = ElemDesc.class.getDeclaredConstructor(new Class[] { Integer.TYPE });&lt;br /&gt;        eltDescConstructor.setAccessible(true);&lt;br /&gt;&lt;br /&gt;        fieldMMap = setAccessible("m_map", StringToIntTable.class);&lt;br /&gt;        fieldMValues = setAccessible("m_values", StringToIntTable.class);&lt;br /&gt;        fieldMFirstFree = setAccessible("m_firstFree", StringToIntTable.class);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private static Method setAccessible(String methodName, Class[] paramTypes, Class&lt;? extends Object&gt; clazz) throws SecurityException, NoSuchMethodException {&lt;br /&gt;        Method method = clazz.getDeclaredMethod(methodName, paramTypes);&lt;br /&gt;&lt;br /&gt;        method.setAccessible(true);&lt;br /&gt;        return method;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private static Field setAccessible(String fieldName, Class&lt;? extends Object&gt; clazz) throws NoSuchFieldException {&lt;br /&gt;        Field fieldMAttrs = clazz.getDeclaredField(fieldName);&lt;br /&gt;&lt;br /&gt;        fieldMAttrs.setAccessible(true);&lt;br /&gt;        return fieldMAttrs;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * DELEGATE to stream ...&lt;br /&gt;     */&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4396093936384561136-7338672429063097277?l=morningcofee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://morningcofee.blogspot.com/feeds/7338672429063097277/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4396093936384561136&amp;postID=7338672429063097277' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/7338672429063097277'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/7338672429063097277'/><link rel='alternate' type='text/html' href='http://morningcofee.blogspot.com/2007/07/xalan-specific-output-properties.html' title='Xalan-specific output properties nightmare'/><author><name>Frenchie</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4396093936384561136.post-7007053290229462684</id><published>2007-03-12T09:00:00.000-07:00</published><updated>2007-03-12T09:11:01.607-07:00</updated><title type='text'>Wait for me !</title><content type='html'>In the J2EE world you're not suppose to play with Thread. Some people are even afraid just by the name of it. It's easy to understand why, there are a lot of issues to be aware of if you're using them, security, synchronization, pooling, class loading. Then it's easy to discard threading subjects as irrelevant to web application.&lt;br/&gt; &lt;br/&gt; There is nothing more wrong in my opinion. Because in a J2EE application thread are everywhere, a HTTP Request is served in a Thread, a MessageListener run in a Thread. The spring MessageContainers run n Thread. Etc ... You can't avoid thinking about that. A classic example is in the Old Struts ...&lt;br/&gt; &lt;br/&gt; But it also be really useful to do some integration testing. If you are lucky to use the new Spring 2&amp;nbsp; message container bean, that enable you to have a MessageDrivenBean without an EJB container. All you have to do is implementing the MessageListener interface and a bit of configuration.&lt;br/&gt; &lt;br/&gt; This Listener gonna then be called on the container when a message arrive.&lt;br/&gt; &lt;br/&gt; Now imagine that for integration test purpose you want to know when then listener has been executed.&lt;br/&gt; &lt;br/&gt; Here you have two strategies, &lt;span style="FONT-STYLE:italic"&gt;The I come every n seconds looking if you are finished&lt;/span&gt;&amp;nbsp; and &lt;span style="FONT-STYLE:italic"&gt;The I'm gonna have a nap, just wake me up when you're here&lt;/span&gt;.&lt;br/&gt; &lt;br/&gt; &lt;span style="FONT-FAMILY:Verdana"&gt;Let's write a method &lt;/span&gt;&lt;span style="FONT-FAMILY:Courier New"&gt;&lt;span style="FONT-FAMILY:Verdana"&gt;waitUntilIAmHere on the listener, that the test will call&lt;/span&gt;&lt;br style="FONT-FAMILY:Verdana"/&gt; &lt;/span&gt;&lt;br/&gt; &lt;div&gt;  &lt;br/&gt;  &lt;table bgcolor="#c0c0c0" border="1" bordercolor="#000000" cellpadding="0" cellspacing="0" width="100%"&gt;  &lt;tbody&gt;  &lt;tr&gt;  &lt;td width="100%"&gt;  &lt;span style="FONT-FAMILY:Courier New"&gt; &amp;nbsp; &lt;/span&gt;&lt;br style="FONT-FAMILY:Courier New"/&gt;  &lt;span style="FONT-FAMILY:Courier New"&gt;&amp;nbsp;&amp;nbsp; listener.waitUntilIAmHere();&lt;/span&gt;&lt;br/&gt;  &lt;span style="FONT-FAMILY:Courier New"&gt;&lt;/span&gt;&amp;nbsp;&lt;br/&gt;  &lt;/td&gt;  &lt;/tr&gt;  &lt;/tbody&gt;  &lt;/table&gt; &lt;/div&gt; &amp;nbsp; &amp;nbsp;&lt;br/&gt; &lt;br/&gt; &lt;h3&gt;  The I come every n seconds looking if you are finished&lt;br/&gt; &lt;/h3&gt; &lt;p&gt;  or the stalker one. A loop check every so and then for the state of the object until it changes.&lt;br/&gt; &lt;/p&gt; &lt;br/&gt; &lt;div&gt;  &lt;table bgcolor="#c0c0c0" border="1" bordercolor="#000000" cellpadding="0" cellspacing="0" width="100%"&gt;  &lt;tbody&gt;  &lt;tr&gt;  &lt;td width="100%"&gt;  &lt;span style="FONT-FAMILY:Courier New"&gt; &amp;nbsp; &lt;/span&gt;&lt;br style="FONT-FAMILY:Courier New"/&gt;  &lt;span style="FONT-FAMILY:Courier New"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; boolean weAreThere;&lt;/span&gt;&lt;br style="FONT-FAMILY:Courier New"/&gt;  &lt;span style="FONT-FAMILY:Courier New"&gt; &amp;nbsp;&amp;nbsp;&lt;br/&gt;  &amp;nbsp;&amp;nbsp; &amp;nbsp;public void waitUntilYouAreHere() throws InteruptedException {&lt;/span&gt;&lt;br style="FONT-FAMILY:Courier New"/&gt;  &lt;span style="FONT-FAMILY:Courier New"&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; while(listener.areWeThereYet()) {&lt;/span&gt;&lt;br style="FONT-FAMILY:Courier New"/&gt;  &lt;span style="FONT-FAMILY:Courier New"&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Thread.sleep(sleepTime);&lt;/span&gt;&lt;br style="FONT-FAMILY:Courier New"/&gt;  &lt;span style="FONT-FAMILY:Courier New"&gt;  &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br style="FONT-FAMILY:Courier New"/&gt;  &lt;span style="FONT-FAMILY:Courier New"&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;}&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;br style="FONT-FAMILY:Courier New"/&gt;  &lt;span style="FONT-FAMILY:Courier New"&gt;&lt;br/&gt;  &lt;br/&gt;  &amp;nbsp;&amp;nbsp; &amp;nbsp;public boolean areWeThereYet() throws InteruptedException {&lt;/span&gt;&lt;br style="FONT-FAMILY:Courier New"/&gt;  &lt;span style="FONT-FAMILY:Courier New"&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;synchronized(this) {&lt;/span&gt;&lt;br style="FONT-FAMILY:Courier New"/&gt;  &lt;span style="FONT-FAMILY:Courier New"&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;return weAreThere;&lt;/span&gt;&lt;br style="FONT-FAMILY:Courier New"/&gt;  &lt;span style="FONT-FAMILY:Courier New"&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;br style="FONT-FAMILY:Courier New"/&gt;  &lt;span style="FONT-FAMILY:Courier New"&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;}&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;br style="FONT-FAMILY:Courier New"/&gt;  &lt;span style="FONT-FAMILY:Courier New"&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;br style="FONT-FAMILY:Courier New"/&gt;  &lt;span style="FONT-FAMILY:Courier New"&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;public void onMessage(Message m) {&lt;/span&gt;&lt;br style="FONT-FAMILY:Courier New"/&gt;  &lt;span style="FONT-FAMILY:Courier New"&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;doMyThing();&lt;/span&gt;&lt;br style="FONT-FAMILY:Courier New"/&gt;  &lt;br style="FONT-FAMILY:Courier New"/&gt;  &lt;span style="FONT-FAMILY:Courier New"&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;iAmHere();&lt;/span&gt;&lt;br style="FONT-FAMILY:Courier New"/&gt;  &lt;span style="FONT-FAMILY:Courier New"&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;br style="FONT-FAMILY:Courier New"/&gt;  &lt;br style="FONT-FAMILY:Courier New"/&gt;  &lt;span style="FONT-FAMILY:Courier New"&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;void iAmHere() {&lt;/span&gt;&lt;br style="FONT-FAMILY:Courier New"/&gt;  &lt;span style="FONT-FAMILY:Courier New"&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;synchronized(this) {&lt;/span&gt;&lt;br style="FONT-FAMILY:Courier New"/&gt;  &lt;span style="FONT-FAMILY:Courier New"&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;weAreThere = true;&lt;/span&gt;&lt;br style="FONT-FAMILY:Courier New"/&gt;  &lt;span style="FONT-FAMILY:Courier New"&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;br style="FONT-FAMILY:Courier New"/&gt;  &lt;span style="FONT-FAMILY:Courier New"&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;br/&gt;  &amp;nbsp;&amp;nbsp;&lt;br/&gt;  &lt;/td&gt;  &lt;/tr&gt;  &lt;/tbody&gt;  &lt;/table&gt; &lt;/div&gt; &lt;br/&gt; &amp;nbsp; &amp;nbsp;&lt;br/&gt; That might be OK for a test but it's far from being elegant, and probably far from being efficient.&lt;br/&gt; &lt;br/&gt; &lt;h3&gt;  The I'm gonna have a nap, just wake me up when you're here &lt;/h3&gt; uses some rendez-vous api, wait and notify. Wait sleep the Thread until the object on which it's waiting sends a notification. Notify sends the notification. In this case we are using notifyAll in case two threads are waiting. One thing to be aware with notify is as stated in the documentation : &lt;span style="FONT-WEIGHT:bold"&gt;The choice &lt;/span&gt;[of which thread is awakened]&lt;span style="FONT-WEIGHT:bold"&gt; is arbitrary and occurs at the discretion of the implementation.&lt;/span&gt;&lt;br/&gt; &lt;br/&gt; &lt;div&gt;  &lt;br/&gt;  &lt;table bgcolor="#c0c0c0" border="1" bordercolor="#000000" cellpadding="0" cellspacing="0" width="100%"&gt;  &lt;tbody&gt;  &lt;tr&gt;  &lt;td width="100%"&gt;  &lt;span style="FONT-FAMILY:Courier New"&gt; &amp;nbsp; &lt;/span&gt;&lt;br style="FONT-FAMILY:Courier New"/&gt;  &lt;span style="FONT-FAMILY:Courier New"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; boolean weAreThere;&lt;/span&gt;&lt;br style="FONT-FAMILY:Courier New"/&gt;  &lt;br style="FONT-FAMILY:Courier New"/&gt;  &lt;span style="FONT-FAMILY:Courier New"&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;public void waitUntilYouAreHere() throws InteruptedException {&lt;/span&gt;&lt;br style="FONT-FAMILY:Courier New"/&gt;  &lt;span style="FONT-FAMILY:Courier New"&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;synchronized(this) {&lt;/span&gt;&lt;br style="FONT-FAMILY:Courier New"/&gt;  &lt;span style="FONT-FAMILY:Courier New"&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;if (!weAreThere) {&lt;/span&gt;&lt;br style="FONT-FAMILY:Courier New"/&gt;  &lt;span style="FONT-FAMILY:Courier New"&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;this.wait(timeout);&lt;/span&gt;&lt;br style="FONT-FAMILY:Courier New"/&gt;  &lt;span style="FONT-FAMILY:Courier New"&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;br style="FONT-FAMILY:Courier New"/&gt;  &lt;span style="FONT-FAMILY:Courier New"&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;br style="FONT-FAMILY:Courier New"/&gt; &lt;span style="FONT-FAMILY:Courier New"&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;}&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;br style="FONT-FAMILY:Courier New"/&gt; &lt;span style="FONT-FAMILY:Courier New"&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;br style="FONT-FAMILY:Courier New"/&gt; &lt;span style="FONT-FAMILY:Courier New"&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;public void onMessage(Message m) {&lt;/span&gt;&lt;br style="FONT-FAMILY:Courier New"/&gt; &lt;span style="FONT-FAMILY:Courier New"&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;doMyThing();&lt;/span&gt;&lt;br style="FONT-FAMILY:Courier New"/&gt; &lt;br style="FONT-FAMILY:Courier New"/&gt; &lt;span style="FONT-FAMILY:Courier New"&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;iAmHere();&lt;/span&gt;&lt;br style="FONT-FAMILY:Courier New"/&gt; &lt;span style="FONT-FAMILY:Courier New"&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;br style="FONT-FAMILY:Courier New"/&gt; &lt;br style="FONT-FAMILY:Courier New"/&gt; &lt;span style="FONT-FAMILY:Courier New"&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;void iAmHere() {&lt;/span&gt;&lt;br style="FONT-FAMILY:Courier New"/&gt; &lt;span style="FONT-FAMILY:Courier New"&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;synchronized(this) {&lt;/span&gt;&lt;br style="FONT-FAMILY:Courier New"/&gt; &lt;span style="FONT-FAMILY:Courier New"&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;weAreThere = true;&lt;/span&gt;&lt;br style="FONT-FAMILY:Courier New"/&gt; &lt;span style="FONT-FAMILY:Courier New"&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;this.notifyAll();&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;br style="FONT-FAMILY:Courier New"/&gt; &lt;span style="FONT-FAMILY:Courier New"&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;br style="FONT-FAMILY:Courier New"/&gt; &lt;span style="FONT-FAMILY:Courier New"&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;br/&gt; &amp;nbsp;&amp;nbsp;&lt;br/&gt; &lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt; &lt;/div&gt; &lt;br/&gt; &amp;nbsp;&amp;nbsp;&lt;br/&gt; This one is in number of effective line as complex as the precedent, except that it's much cleaner. The interruption is easily deal with, so is the timeout.&lt;br/&gt; &lt;br/&gt; wait and notify are key methods to work with Thread, if you look in any Thread Pool implementation they more than probably deal with the thread waiting for a new task to execute.&lt;br/&gt; &amp;nbsp;&lt;br/&gt; &lt;br/&gt; Some Resources :&lt;br style="COLOR:#3366ff"/&gt; &lt;p&gt; &lt;a href="http://www-128.ibm.com/developerworks/java/library/j-jtp05236.html" title="Java theory and practice: Dealing with InterruptedException"&gt;Java theory and practice: Dealing with InterruptedException&lt;/a&gt; &lt;/p&gt; &lt;p&gt; &lt;a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Object.html#wait%28%29" title="Java theory and practice: Dealing with InterruptedException"&gt;Object.wait()&lt;/a&gt; &lt;/p&gt; &lt;p&gt; &lt;a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Object.html#notifyAll%28%29" title="Java theory and practice: Dealing with InterruptedException"&gt;Object.notifyAll()&lt;/a&gt; &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4396093936384561136-7007053290229462684?l=morningcofee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://morningcofee.blogspot.com/feeds/7007053290229462684/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4396093936384561136&amp;postID=7007053290229462684' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/7007053290229462684'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/7007053290229462684'/><link rel='alternate' type='text/html' href='http://morningcofee.blogspot.com/2007/03/wait-for-me.html' title='Wait for me !'/><author><name>Frenchie</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4396093936384561136.post-3373162707065227043</id><published>2007-03-02T08:51:00.000-08:00</published><updated>2007-03-02T09:50:07.817-08:00</updated><title type='text'>New Google Mail feature : the mail fetcher</title><content type='html'>If you're like me and got more than one email account, you're gonna appreciate this &lt;a href="http://mail.google.com/support/bin/answer.py?ctx=%67mail&amp;hl=en&amp;amp;answer=21288"&gt;new &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;fu&lt;/span&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;nctionality&lt;/span&gt;&lt;/a&gt; ! no need to check all the different web mail, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;google&lt;/span&gt; now offer the possibility to fetch your email for you.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4396093936384561136-3373162707065227043?l=morningcofee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://morningcofee.blogspot.com/feeds/3373162707065227043/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4396093936384561136&amp;postID=3373162707065227043' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/3373162707065227043'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/3373162707065227043'/><link rel='alternate' type='text/html' href='http://morningcofee.blogspot.com/2007/03/new-google-mail-feature-mail-fetcher.html' title='New Google Mail feature : the mail fetcher'/><author><name>Frenchie</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4396093936384561136.post-5871767697321103518</id><published>2007-02-22T01:17:00.000-08:00</published><updated>2007-03-07T01:39:31.516-08:00</updated><title type='text'>Autowire is not your friend</title><content type='html'>Imagine you have an application that is working fine. It uses spring as a DI container and for the AOP nothing extraordinary except that for some reason the &lt;span style="font-style: italic;"&gt;default-autowire&lt;/span&gt; is set to &lt;span style="font-style: italic;"&gt;"autodetect"&lt;/span&gt;. Part of the config is the following, a MBean exporter that take a map as a property - JMX is really nice integrated in spring, &lt;a title="doc here" href="http://www.springframework.org/docs/reference/jmx.html"&gt;doc here&lt;/a&gt; - .&lt;br&gt;&lt;br&gt; &lt;div&gt;&lt;table bgcolor="#cccccc" border="0" cellpadding="3" cellspacing="0" width="100%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td width="100%"&gt;&lt;br&gt;    &amp;lt;bean id="exporter" class="org.springframework.jmx.export.MBeanExporter" lazy-init="false"&amp;gt;&lt;br&gt;       &amp;lt;property name="beans"&amp;gt;&lt;br&gt;         &amp;lt;map&amp;gt;&lt;br&gt;           &amp;lt;entry key="bean:name=log4j_exchange" value-ref="log4jAdminService"/&amp;gt;&lt;br&gt;         &amp;lt;/map&amp;gt;&lt;br&gt;       &amp;lt;/property&amp;gt;&lt;br&gt;       &amp;lt;property name="assembler" ref="assembler"/&amp;gt;&lt;br&gt;     &amp;lt;/bean&amp;gt;&lt;br&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;br&gt;Weeks later somebody makes some modification, and everything breaks. He just had a Properties in the config :&lt;br&gt;&lt;br&gt;&lt;div&gt;&lt;table bgcolor="#cccccc" border="0" cellpadding="3" cellspacing="0" width="100%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td width="100%"&gt;&lt;br&gt;    &amp;lt;bean id="environmentProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean"&amp;gt;&lt;br&gt;         &amp;lt;property name="location" value="classpath:environment.properties" /&amp;gt;&lt;br&gt;         &amp;lt;property name="singleton" value="true" /&amp;gt;&lt;br&gt;     &amp;lt;/bean&amp;gt;&lt;br&gt;&lt;br&gt; &lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;br&gt;And now MBeanExporter complain that the map does not contains the proper kind of object.&lt;br&gt;&lt;br&gt;So what happened here ? &lt;br&gt;&lt;br&gt;The response is simple, the autowiring overwrite - I yes i think it's a strange behaviour - the map of the exporter with the environmentProperties  - Properties extends Hashtable implements Map -. Fortunately you can had an attritbute to the bean &lt;span style="font-style: italic;"&gt;autowire="no"&lt;/span&gt; to save the day, but my feeling is that you should not activate auto wiring by default as recommanded I think but documentation ?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4396093936384561136-5871767697321103518?l=morningcofee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://morningcofee.blogspot.com/feeds/5871767697321103518/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4396093936384561136&amp;postID=5871767697321103518' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/5871767697321103518'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/5871767697321103518'/><link rel='alternate' type='text/html' href='http://morningcofee.blogspot.com/2007/02/autowire-is-not-your-friend-imagine-you.html' title='Autowire is not your friend'/><author><name>Frenchie</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4396093936384561136.post-5932145274778952718</id><published>2007-02-20T04:22:00.000-08:00</published><updated>2007-02-20T04:39:16.088-08:00</updated><title type='text'>Cruise control label incrementor</title><content type='html'>I wanted to tag cvs after each succesful build in cruise. All you need to do is add a task to add a task a the end of the build script :&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; &amp;lt;target name="cvstag" if="label"&gt;&lt;br /&gt;  &amp;lt;cvs command="tag ${label}" quiet="false" reallyquiet="false" /&gt;&lt;br /&gt; &amp;lt;/target&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;label is set by cruisecontrol. You need to add the labelincrementor plugin. You can miss this point as it is the default one though.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;cruisecontrol&gt;&lt;br /&gt;        &amp;lt;plugin name="labelincrementer"&lt;br /&gt;         classname="net.sourceforge.cruisecontrol.labelincrementers.DefaultLabelIncrementer"/&gt;&lt;br /&gt;&lt;br /&gt;...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;and in your project configure the defaultLabel and the separator - must be change to '-' - &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;...&lt;br /&gt;    &amp;lt;project name="myproject"&gt;&lt;br /&gt;        &amp;lt;labelincrementer defaultLabel="cruise_${project.name}-1" separator="-"/&gt;&lt;br /&gt;&lt;br /&gt;...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;If the tag already exists it's not gonna move it.&lt;br /&gt;&lt;br /&gt;Last point to reset the label in your project, the only way I found was to delete the {project.name}.ser and it's gonna restart at the defaultLabel.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4396093936384561136-5932145274778952718?l=morningcofee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://morningcofee.blogspot.com/feeds/5932145274778952718/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4396093936384561136&amp;postID=5932145274778952718' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/5932145274778952718'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/5932145274778952718'/><link rel='alternate' type='text/html' href='http://morningcofee.blogspot.com/2007/02/cruise-control-label-incrementor.html' title='Cruise control label incrementor'/><author><name>Frenchie</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4396093936384561136.post-8127644903151513282</id><published>2007-02-20T00:21:00.000-08:00</published><updated>2007-02-20T01:59:22.431-08:00</updated><title type='text'>The PermGen daemon.</title><content type='html'>The life of Java Web application developers is most of the time a quiet and smooth road, on which minor hole makes the trip exiting. Until you end up facing some big ugly monster, the OutOfMemory ones are part of the very nasty. There is 3 types of OutOfMemory monster:&lt;br/&gt;     - the stack OutOfMemory, also known as the classic. It can be due to a memory leak or to the dwarfish heap, which I've rarely seen this days. Check your code and  get  a normal heap.&lt;br/&gt;     - the native stack OutOfMemory, this one is nastier than the precedent, also far less common. It happens when some native code failed to release memory. Oracle App Server used to have one when you had link to some nonexistent file - nice fail safe ... -.&lt;br/&gt;     - and the 3rd one and the one of interest here, the PermGen daemon. It introduces it self with a loud and devastating &lt;span style="FONT-WEIGHT:bold; FONT-STYLE:italic"&gt;"&lt;/span&gt;&lt;font size="-1" style="FONT-WEIGHT:bold; FONT-STYLE:italic"&gt;OutOfMemoryError: PermGen space"&lt;/font&gt;&lt;font size="-1"&gt;. This one is probably due to a nasty daemon that keep the ClassLoader in its grip.&lt;br /&gt;&lt;br /&gt;First what is this PermGen ? The PermGen is a specific place of the java memory used to store "permanent object", like class definition. There is more info in what is it specifically elsewhere this is an enough approximation for the story that follow.&lt;br/&gt; &lt;br/&gt; So when you deploy your web app into your web container - Tomcat for example - this webapp is load in memory, the classes definition are loaded too. The classes definition can be Garbage Collected and they will when their ClassLoader gonna be collected. That happen normally when there is no more reference to the class loader, which is when there is no more class instantiated by it. That's what normally happen when you undeploy or stop your application, freeing all the memory used by your impressive work of art.&lt;br/&gt; &lt;br/&gt; But sometimes for a reason known only by yourself - asynchronous processing, report, show off, ... - you use a Thread in your application to do some stuff. Check that the database is up, or count the time, or whatever it is it's running. And the thread it does not really know about the web app and when the web app stop are undeploy. So To avoid any problem the shutdown of your application server - killing it is harder that just a quick Ctrl-C - you set the thread as &lt;span style="FONT-WEIGHT:bold"&gt;daemon&lt;/span&gt;. Meaning that when the app server stop the thread gonna stop what it was doing by whatever magic it is -  so stop is deprecated but setDeamon which in fine gonna do something equivalent to a stop is not ... -.&lt;br/&gt; &lt;br/&gt; When you're developing you don't really won't to stop and start your tomcat each time you deploy, you probably got a neaty script that undeploy and deploy the application for you !  Or you one of this heretics who believe in peace not war and use a exploded web app. Every time your touching your web.xml, your web-app restart magically.&lt;br/&gt; &lt;br/&gt; This work fine, except if you introduce the daemon in your webapp. After 2, 3 maybe 4 restart your web server shout in despair &lt;/font&gt;&lt;span style="FONT-WEIGHT:bold; FONT-STYLE:italic"&gt;"&lt;/span&gt;&lt;font size="-1" style="FONT-WEIGHT:bold; FONT-STYLE:italic"&gt;OutOfMemoryError: PermGen space" !&lt;br/&gt; &lt;/font&gt;&lt;font size="-1"&gt;&lt;br/&gt; What happened ? It works fine for days, it's only when I redeploy ! That's the work of the PermGen Daemon. And here is what happens :&lt;br/&gt;     - My web app v1 starts, my Thread named daemon1 - it's quite comfy to name your thread - are her dong there work. The classes definition, the class loader, and deamon1 all happy in the play ground.&lt;br/&gt;     - Developer after improving dramatically the design of his application wants to update the version in his Tomcat. Touch down, undeploy, deploy here it goes.&lt;br/&gt;        web app v1 stops, daemon1 does not give a shit, class loader still reference by daemon 1. web app v2 starts. with daemon 2 and a new class loader&lt;br style="FONT-WEIGHT:bold; FONT-STYLE:italic"/&gt; &lt;/font&gt;&lt;br/&gt; So now you've got two daemon, 2 classloader that contains almost the same class definitions. you do that another couple of time and here is you permgen error.&lt;br/&gt; &lt;br/&gt; So please, please when the web app stop make you thread stop too - that also means the Executor in java 5 -. This problem is quite common, the Active MQ connection factory has that in the 4.0.2 and probably 4.1.0 ... It's easy to ignore this error, and blame web container bug, but it's not. I'd guess the main problem is this notion of daemon Thread ...&lt;br/&gt; &lt;br/&gt; &lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4396093936384561136-8127644903151513282?l=morningcofee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://morningcofee.blogspot.com/feeds/8127644903151513282/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4396093936384561136&amp;postID=8127644903151513282' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/8127644903151513282'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/8127644903151513282'/><link rel='alternate' type='text/html' href='http://morningcofee.blogspot.com/2007/02/permgen-daemon.html' title='The PermGen daemon.'/><author><name>Frenchie</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4396093936384561136.post-5261638670870774411</id><published>2007-02-19T09:17:00.000-08:00</published><updated>2007-02-19T09:18:41.418-08:00</updated><title type='text'>London Java Meetup - 27 Feb 2007</title><content type='html'>Never been there yet, but gonna have a couple of guinness with London Geeks.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://javanicus.com/londonjava/items/206-index.html" &gt;&lt;i&gt;some geeks, some beer, some rain... &lt;/i&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4396093936384561136-5261638670870774411?l=morningcofee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://morningcofee.blogspot.com/feeds/5261638670870774411/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4396093936384561136&amp;postID=5261638670870774411' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/5261638670870774411'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/5261638670870774411'/><link rel='alternate' type='text/html' href='http://morningcofee.blogspot.com/2007/02/london-java-meetup-27-feb-2007.html' title='London Java Meetup - 27 Feb 2007'/><author><name>Frenchie</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4396093936384561136.post-2885246249645862452</id><published>2007-02-15T06:10:00.000-08:00</published><updated>2007-02-15T06:13:27.825-08:00</updated><title type='text'>Hibernate 3.2 broke the custom types</title><content type='html'>A repost from my old blog :&lt;br /&gt;&lt;br /&gt;This &lt;a href="http://fisheye.jboss.org/browse/~br=tag:v321/Hibernate/tags/v321/Hibernate3/src/org/hibernate/action/EntityUpdateAction.java?r1=10125&amp;r2=10614" &gt;change&lt;/a&gt; on hibernate 3.2 can cause hibernate to not detect change in custom type on a collection property. e.g.  if you want to map a comma separated list of string to a Set :&lt;br /&gt;&lt;br /&gt;&lt;div style="background-color:grey; border:solid black 1px; padding 5px;" &gt;&lt;br /&gt; "String1, String2, String3" &lt;=&gt; { "String1", "String2", "String3" }.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;After an update the loadedState gonna reference the set in the entity. So a change in this Set by the application gonna change also the Set in the loaded state as they are the same. So hibernate is not gonna be able to check if the Entity is dirty properly.&lt;br /&gt;&lt;br /&gt;Solution stay in 3.1 or mark your object as hasUpdateGeneratedProperties, which might not be good for performances ...&lt;br /&gt;&lt;br /&gt;I reported the &lt;a href="http://opensource.atlassian.com/projects/hibernate/browse/HHH-2314"&gt;Issue posted&lt;/a&gt;, still no change...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4396093936384561136-2885246249645862452?l=morningcofee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://morningcofee.blogspot.com/feeds/2885246249645862452/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4396093936384561136&amp;postID=2885246249645862452' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/2885246249645862452'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/2885246249645862452'/><link rel='alternate' type='text/html' href='http://morningcofee.blogspot.com/2007/02/hibernate-32-broke-custom-type.html' title='Hibernate 3.2 broke the custom types'/><author><name>Frenchie</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4396093936384561136.post-4626121070487039835</id><published>2007-02-14T01:57:00.000-08:00</published><updated>2007-02-14T02:02:37.225-08:00</updated><title type='text'>Welcome</title><content type='html'>At that end of the cyber space, here come a new node. It's gonna be mainly about Java and other IT stuff. What I need to write about :&lt;br /&gt; - how to deal with Thread in a web app, and what happens when it's not done properly.&lt;br /&gt; - some stuff about thread management and how it can be useful in your test&lt;br /&gt; - JMX and lo4j&lt;br /&gt; - the beauty of XA Transaction&lt;br /&gt; - JMS is my friend, but redilivery policy does not seems to work properly in active mq&lt;br /&gt; - how struts 2 is wonderful and JSF sucks :)&lt;br /&gt; - should I reconcile myself with maven&lt;br /&gt; - cruise control easy&lt;br /&gt;&lt;br /&gt;that's some ideas ...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4396093936384561136-4626121070487039835?l=morningcofee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://morningcofee.blogspot.com/feeds/4626121070487039835/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4396093936384561136&amp;postID=4626121070487039835' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/4626121070487039835'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4396093936384561136/posts/default/4626121070487039835'/><link rel='alternate' type='text/html' href='http://morningcofee.blogspot.com/2007/02/welcome.html' title='Welcome'/><author><name>Frenchie</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
