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