Hi Actually the AtomicBoolean cannot safely be used for initializing code blocks?
You can still have concurrent threads invoking the boolean and one thread will see it as false and the other as true. What it helps is that there are only one ever that sees it as false and therefore only one thread that will initialize it. But in the mean time another thread could have seen it as true, but its still not initialized because the first thread is currently doing that. e.g. there are no locks. You have to use the synchronized or a Lock object. See for example camel-jaxb and how it use the synchronized. Its not bad to use as synchronized is heavily optimized in JDK6. A better idea would be to implements Service (extends ServiceSupport) and do initialization in the start method. I am pretty sure Camel will invoke these start/stop on data formats as well. Could you try that? If not we should get that done. Then all kind of initialization can be done using the Service interface. On Fri, Dec 18, 2009 at 10:54 AM, <ningji...@apache.org> wrote: > Author: ningjiang > Date: Fri Dec 18 09:54:30 2009 > New Revision: 892199 > > URL: http://svn.apache.org/viewvc?rev=892199&view=rev > Log: > CAMEL-2148 using the ClassResolver from the CamelContext to load class > > Modified: > > camel/trunk/components/camel-protobuf/src/main/java/org/apache/camel/dataformat/protobuf/ProtobufDataFormat.java > > Modified: > camel/trunk/components/camel-protobuf/src/main/java/org/apache/camel/dataformat/protobuf/ProtobufDataFormat.java > URL: > http://svn.apache.org/viewvc/camel/trunk/components/camel-protobuf/src/main/java/org/apache/camel/dataformat/protobuf/ProtobufDataFormat.java?rev=892199&r1=892198&r2=892199&view=diff > ============================================================================== > --- > camel/trunk/components/camel-protobuf/src/main/java/org/apache/camel/dataformat/protobuf/ProtobufDataFormat.java > (original) > +++ > camel/trunk/components/camel-protobuf/src/main/java/org/apache/camel/dataformat/protobuf/ProtobufDataFormat.java > Fri Dec 18 09:54:30 2009 > @@ -20,10 +20,12 @@ > import java.io.InputStream; > import java.io.OutputStream; > import java.lang.reflect.Method; > +import java.util.concurrent.atomic.AtomicBoolean; > > import com.google.protobuf.Message; > import com.google.protobuf.Message.Builder; > > +import org.apache.camel.CamelContext; > import org.apache.camel.CamelException; > import org.apache.camel.Exchange; > import org.apache.camel.InvalidPayloadException; > @@ -34,6 +36,8 @@ > public class ProtobufDataFormat implements DataFormat { > > private Message defaultInstance; > + private String instanceClassName; > + private AtomicBoolean setDefaultInstanceHasBeenCalled = new > AtomicBoolean(false); > > /** > * @param defaultInstance > @@ -51,11 +55,15 @@ > > public void setInstanceClass(String className) throws Exception { > ObjectHelper.notNull(className, "ProtobufDataFormat instaceClass"); > - Class<?> instanceClass = ObjectHelper.loadClass(className); > + instanceClassName = className; > + } > + > + protected Message loadDefaultInstance(String className, CamelContext > context) throws CamelException, ClassNotFoundException { > + Class<?> instanceClass = > context.getClassResolver().resolveMandatoryClass(className); > if (Message.class.isAssignableFrom(instanceClass)) { > try { > Method method = instanceClass.getMethod("getDefaultInstance", > new Class[0]); > - defaultInstance = (Message) method.invoke(null, new > Object[0]); > + return (Message) method.invoke(null, new Object[0]); > } catch (Exception ex) { > throw new CamelException("Can't set the defaultInstance of > ProtobufferDataFormat with " > + className + ", caused by " + ex); > @@ -64,7 +72,6 @@ > throw new CamelException("Can't set the defaultInstance of > ProtobufferDataFormat with " > + className + ", as the class is not a subClass of > com.google.protobuf.Message"); > } > - > } > > /* > @@ -82,8 +89,15 @@ > * java.io.InputStream) > */ > public Object unmarshal(Exchange exchange, InputStream inputStream) > throws Exception { > + > if (this.defaultInstance == null) { > - throw new CamelException("There is not defaultInstance for > protobuf unmarshaling"); > + if (instanceClassName == null) { > + throw new CamelException("There is not defaultInstance for > protobuf unmarshaling"); > + } else { > + if (!setDefaultInstanceHasBeenCalled.getAndSet(true)) { > + defaultInstance = loadDefaultInstance(instanceClassName, > exchange.getContext()); > + } > + } > } > Builder builder = > this.defaultInstance.newBuilderForType().mergeFrom(inputStream); > if (!builder.isInitialized()) { > > > -- Claus Ibsen Apache Camel Committer Author of Camel in Action: http://www.manning.com/ibsen/ Open Source Integration: http://fusesource.com Blog: http://davsclaus.blogspot.com/ Twitter: http://twitter.com/davsclaus