SimpleGenerator.java Multithreaded access

Daniel Bram <[email protected]> Tue, 4 Nov 2003 14:17:06 +0100 (CET)
Newsgroups gmane.comp.java.enhydra.zeus
Message-ID <12050142.1067951826828.JavaMail.Administrator@pumbaa>
Hi all,

There appears to be a small bug in  org.enhydra.zeus.generator.SimpleGenerator.java 

When java files are generated with attributes that can contain a limited list of values they are declared statically, and initialized upon demand. (by the first usage of get/set method for that attribute).
But in the constructor of the generated object the isInitialized and corresponding vector object is reset to false and null.

This means that the get/setValue correctly checks if the list is initialized and does so if not yet done, but each instance's constructor will reset these values to false and null.
In a single threaded environment this only has a performance side effect, but in a multithreaded environment this can lead to NullPointersExceptions... 

Here is diff of my patch that solves the problem, I think by simple removing the false and null assignment in the constructor it should work correctly...

D:\opensource\zeus\src\java\org\enhydra\zeus\generator>diff SimpleGenerator.java
 SimpleGenerator.java.new
1540,1549d1539
<                     String myName = property.getJavaVariableName();
<                     writer.write("        ");
<                     writer.write(ZeusDefaults.ZEUS_INTERNAL_PREFIX);
<                     writer.write(CapitalizationUtils.initialUpper(myName));
<                     writer.write("Initialized = false;\n");
<                     writer.write("        ");
<                     writer.write(ZeusDefaults.ZEUS_INTERNAL_PREFIX);
<                     writer.write("valid");
<                     writer.write(CapitalizationUtils.initialUpper(myName));
<                     writer.write(" = null;\n");

//here is a (multithreaded) test case that should present the problem  when the patch is not applied.

Regards,

Daniel Bram

---- snip
package com.compea.utils;

import junit.framework.TestCase;

import java.io.IOException;
import java.io.StringReader;
import junit.framework.TestCase;

import java.io.IOException;
import java.io.StringReader;

/**
 * Created by IntelliJ IDEA.
 * User: dbr
 */
public class TestParseBinding extends TestCase
{
    public TestParseBinding(String s)
    {
        super(s);
    }


    public void testStressBinding() throws IOException {
        String message = "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?><XmlElement><test type=\"2\"/></XmlElement>";
        //start 5 threads that will parse it a couple of times
        int parsesPerThread = 20;
        for (int i=0;i<10;i++) {
            new Thread(new ParserRunner("T"+i, message, parsesPerThread)).start();
        }
        //wait for other threads to finishj
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();  //To change body of catch statement use Options | File Templates.
        }
    }

    /**
     * simple thread that parses the messages
     */
    class ParserRunner implements Runnable
    {

        String name;
        String message = null;
        int count =1;

        public ParserRunner()
        {
        }

        public ParserRunner(String name)
        {
            this.name = name;
        }


        public ParserRunner(String name, String message)
        {
            this.name = name;
            this.message = message;
        }

        public ParserRunner(String name, String message, int count)
        {
            this.name = name;
            this.message = message;
            this.count = count;
        }

        public void run()
        {
            for (int i=0;i<count;i++) {
                try {
                    //todo replace this with your generated bind
                    //XMLElement xmlElement = XMLElement.unmarshal(new StringReader(message), false);
                    //System.out.println(name + ", parseNr: " + i + ", "+ xmlElement);
                    throw new IOException("uncomment the lines above with your XmlElement classes, and remove this line");
                } catch (IOException e) {
                    e.printStackTrace();  //To change body of catch statement use Options | File Templates.
                } finally {
                }
            }
        }
    }

}
---- snip


-----------------------------------------------------
Mail.be, WebMail and Virtual Office
http://www.mail.be