Updated Branches:
  refs/heads/camel-2.11.x 9795a32f1 -> 4aeb44a84
  refs/heads/camel-2.12.x c388c53e8 -> b347ad0b3
  refs/heads/master 952ec4b04 -> e494f725b


CAMEL-7001: Avro dataformat classloading issue in OSGi.


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/e494f725
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/e494f725
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/e494f725

Branch: refs/heads/master
Commit: e494f725b3325cc0c405f875f14afdd3c65fd70e
Parents: 952ec4b
Author: Claus Ibsen <davscl...@apache.org>
Authored: Sat Nov 23 13:39:45 2013 +0100
Committer: Claus Ibsen <davscl...@apache.org>
Committed: Sat Nov 23 13:39:45 2013 +0100

----------------------------------------------------------------------
 .../camel/dataformat/avro/AvroDataFormat.java   | 62 +++++++++++---------
 .../avro/AvroMarshalAndUnmarshallTest.java      |  3 +-
 2 files changed, 36 insertions(+), 29 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/e494f725/components/camel-avro/src/main/java/org/apache/camel/dataformat/avro/AvroDataFormat.java
----------------------------------------------------------------------
diff --git 
a/components/camel-avro/src/main/java/org/apache/camel/dataformat/avro/AvroDataFormat.java
 
b/components/camel-avro/src/main/java/org/apache/camel/dataformat/avro/AvroDataFormat.java
index 3e1ed05..5c158d9 100644
--- 
a/components/camel-avro/src/main/java/org/apache/camel/dataformat/avro/AvroDataFormat.java
+++ 
b/components/camel-avro/src/main/java/org/apache/camel/dataformat/avro/AvroDataFormat.java
@@ -37,11 +37,14 @@ import org.apache.camel.CamelException;
 import org.apache.camel.Exchange;
 import org.apache.camel.spi.DataFormat;
 import org.apache.camel.support.ServiceSupport;
+import org.apache.camel.util.ObjectHelper;
 
 public class AvroDataFormat extends ServiceSupport implements DataFormat, 
CamelContextAware {
 
+    private static final String GENERIC_CONTAINER_CLASSNAME = 
GenericContainer.class.getName();
     private CamelContext camelContext;
-    private Schema schema;
+    private Object schema;
+    private transient Schema actualSchema;
     private String instanceClassName;
 
     public AvroDataFormat() {
@@ -61,8 +64,14 @@ public class AvroDataFormat extends ServiceSupport 
implements DataFormat, CamelC
 
     @Override
     protected void doStart() throws Exception {
-        if (instanceClassName != null) {
-            schema = loadDefaultSchema(instanceClassName, camelContext);
+        if (schema != null) {
+            if (schema instanceof Schema) {
+                actualSchema = (Schema) schema;
+            } else {
+                actualSchema = loadSchema(schema.getClass().getName());
+            }
+        } else if (instanceClassName != null) {
+            actualSchema = loadSchema(instanceClassName);
         }
     }
 
@@ -71,56 +80,55 @@ public class AvroDataFormat extends ServiceSupport 
implements DataFormat, CamelC
         // noop
     }
 
-    public Schema getSchema(Exchange exchange, Object graph) throws Exception {
-        if (schema == null) {
-            if (graph != null && graph instanceof GenericContainer) {
-                return loadDefaultSchema(graph.getClass().getName(), 
exchange.getContext());
-            } else {
-                throw new CamelException("There is not schema for avro 
marshaling / unmarshaling");
-            }
-        }
-        return schema;
+    // the getter/setter for Schema is Object type in the API
+
+    public Object getSchema() {
+        return actualSchema != null ? actualSchema : schema;
     }
 
     public void setSchema(Object schema) {
-        if (schema instanceof Schema) {
-            this.schema = (Schema) schema;
-        } else {
-            throw new IllegalArgumentException("The argument for 
setDefaultInstance should be subClass of " + Schema.class.getName());
-        }
+        this.schema = schema;
+    }
+
+    public String getInstanceClassName() {
+        return instanceClassName;
     }
 
     public void setInstanceClass(String className) throws Exception {
         instanceClassName = className;
     }
 
-    public String getInstanceClassName() {
-        return instanceClassName;
-    }
+    protected Schema loadSchema(String className) throws CamelException, 
ClassNotFoundException {
+        // must use same class loading procedure to ensure working in OSGi
+        Class<?> instanceClass = 
camelContext.getClassResolver().resolveMandatoryClass(className);
+        Class<?> genericContainer = 
camelContext.getClassResolver().resolveMandatoryClass(GENERIC_CONTAINER_CLASSNAME);
 
-    protected Schema loadDefaultSchema(String className, CamelContext context) 
throws CamelException, ClassNotFoundException {
-        Class<?> instanceClass = 
context.getClassResolver().resolveMandatoryClass(className);
-        if (GenericContainer.class.isAssignableFrom(instanceClass)) {
+        if (genericContainer.isAssignableFrom(instanceClass)) {
             try {
                 Method method = instanceClass.getMethod("getSchema", new 
Class[0]);
-                return (Schema) method.invoke(instanceClass.newInstance(), new 
Object[0]);
+                return (Schema) 
method.invoke(camelContext.getInjector().newInstance(instanceClass));
             } catch (Exception ex) {
                 throw new CamelException("Error calling getSchema on " + 
instanceClass, ex);
             }
         } else {
-            throw new CamelException("Class " + instanceClass + " must be 
instanceof org.apache.avro.generic.GenericContainer");
+            throw new CamelException("Class " + instanceClass + " must be 
instanceof " + GENERIC_CONTAINER_CLASSNAME);
         }
     }
 
     public void marshal(Exchange exchange, Object graph, OutputStream 
outputStream) throws Exception {
-        DatumWriter<Object> datum = new 
SpecificDatumWriter<Object>(getSchema(exchange, graph));
+        // the schema should be from the graph class name
+        Schema useSchema = actualSchema != null ? actualSchema : 
loadSchema(graph.getClass().getName());
+
+        DatumWriter<Object> datum = new SpecificDatumWriter<Object>(useSchema);
         Encoder encoder = EncoderFactory.get().binaryEncoder(outputStream, 
null);
         datum.write(graph, encoder);
         encoder.flush();
     }
 
     public Object unmarshal(Exchange exchange, InputStream inputStream) throws 
Exception {
-        DatumReader<GenericRecord> reader = new 
SpecificDatumReader<GenericRecord>(getSchema(exchange, null));
+        ObjectHelper.notNull(actualSchema, "schema", this);
+
+        DatumReader<GenericRecord> reader = new 
SpecificDatumReader<GenericRecord>(actualSchema);
         Decoder decoder = DecoderFactory.get().binaryDecoder(inputStream, 
null);
         Object result = reader.read(null, decoder);
         return result;

http://git-wip-us.apache.org/repos/asf/camel/blob/e494f725/components/camel-avro/src/test/java/org/apache/camel/dataformat/avro/AvroMarshalAndUnmarshallTest.java
----------------------------------------------------------------------
diff --git 
a/components/camel-avro/src/test/java/org/apache/camel/dataformat/avro/AvroMarshalAndUnmarshallTest.java
 
b/components/camel-avro/src/test/java/org/apache/camel/dataformat/avro/AvroMarshalAndUnmarshallTest.java
index 2bb7d3c..99b4c36 100644
--- 
a/components/camel-avro/src/test/java/org/apache/camel/dataformat/avro/AvroMarshalAndUnmarshallTest.java
+++ 
b/components/camel-avro/src/test/java/org/apache/camel/dataformat/avro/AvroMarshalAndUnmarshallTest.java
@@ -54,8 +54,7 @@ public class AvroMarshalAndUnmarshallTest extends 
CamelTestSupport {
             });
             fail("Expect the exception here");
         } catch (Exception ex) {
-            assertTrue("Expect FailedToCreateRouteException", ex instanceof 
FailedToCreateRouteException);
-            assertTrue("Get a wrong reason", ex.getCause() instanceof 
IllegalArgumentException);
+            // expected
         }
     }
 

Reply via email to