You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@camel.apache.org by erj2code <pe...@tetraconcepts.com> on 2013/10/14 20:57:42 UTC

How do I load properties with Spring when also using Camel?

I have a HelloWorld Java project that uses Camel to obtain a Map, and print
out its contents in JSON format.  The Map currently has hardcoded values,
but I really want to change my code so that it uses Spring to load a
sensor.properties file of nested key,value pairs into this Map.

I have another Java project I wrote that only uses Spring, and can load the
sensor.properties file just fine into an Arraylist object.

However, when I try to use code from that project to load the
sensor.properties in my HelloWorld project I get the following Camel error
with a NPE:

    Returning Map
    3310 [hello.world.request.timer] ERROR
org.apache.camel.processor.DefaultErrorHandler      - Failed delivery for
exchangeId: 4e984884-df7f-4b82-a977-f5cf4c311814. Exhausted after    
delivery attempt: 1 caught: java.lang.NullPointerException
    java.lang.NullPointerException
    	at sample.SensorGenerator.getSensors(SensorGenerator.java:17)
    	at sample.HelloWorld.returnMap(HelloWorld.java:22)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    	at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    	at java.lang.reflect.Method.invoke(Method.java:606)
    	at
org.apache.camel.component.bean.MethodInfo.invoke(MethodInfo.java:231)
    	at
org.apache.camel.component.bean.MethodInfo$1.proceed(MethodInfo.java:146)
    	at
org.apache.camel.component.bean.BeanProcessor.process(BeanProcessor.java:138)
   
org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:67)
    	at
org.apache.camel.processor.DelegateProcessor.processNext(DelegateProcessor.java:53)
    	at
org.apache.camel.processor.DelegateProcessor.proceed(DelegateProcessor.java:82)
    	at
org.apache.camel.processor.interceptor.TraceInterceptor.process(TraceInterceptor.java:97)
    	at
org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:67)
        at
org.apache.camel.processor.RedeliveryErrorHandler.processExchange(RedeliveryErrorHandler.java:185)
     at
org.apache.camel.processor.RedeliveryErrorHandler.processErrorHandler(RedeliveryErrorHandler.java:151)
    	at    
org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:89)
    	at    
org.apache.camel.processor.DefaultErrorHandler.process(DefaultErrorHandler.java:49)
    	at
org.apache.camel.processor.DefaultChannel.process(DefaultChannel.java:228)
    	at org.apache.camel.processor.Pipeline.process(Pipeline.java:75)
    	at    
org.apache.camel.processor.UnitOfWorkProcessor.processNext(UnitOfWorkProcessor.java:70)
    	at
org.apache.camel.processor.DelegateProcessor.process(DelegateProcessor.java:48)
    	at org.   
apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:67)
    	at    
org.apache.camel.component.timer.TimerConsumer.sendTimerExchange(TimerConsumer.java:102)
    	at
org.apache.camel.component.timer.TimerConsumer$1.run(TimerConsumer.java:49)
    	at java.util.TimerThread.mainLoop(Timer.java:555)
    	at java.util.TimerThread.run(Timer.java:505)
    
Is there something I need to add to my applicationContext.xml to tell Camel
that Spring will load my sensor.properties?  Do I need to use the Spring
integration component specified at
http://camel.apache.org/springintegration.html ?

Here is my current ApplicationContext.xml:

        <?xml version="1.0" encoding="UTF-8"?>
    
    <beans xmlns="http://www.springframework.org/schema/beans"
	    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    
xmlns:camel="http://camel.apache.org/schema/spring"
	    xmlns:context="http://www.springframework.org/schema/context"
	    xmlns:util="http://www.springframework.org/schema/util"
	    xsi:schemaLocation="
            http://www.springframework.org/schema/beans    
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
            http://www.springframework.org/schema/util    
http://www.springframework.org/schema/util/spring-util-3.0.xsd
            http://camel.apache.org/schema/spring    
http://camel.apache.org/schema/spring/camel-spring.xsd
            http://www.springframework.org/schema/context    
http://www.springframework.org/schema/context/spring-context.xsd">

	<bean
	
class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor"
/>
	<context:component-scan base-package="sample" />
	<context:annotation-config />

	<camel:camelContext id="HelloWorldContext">
	
	    
	    <camel:dataFormats>
          <camel:json id="jack" library="Jackson"/>
        </camel:dataFormats>
	
		<camel:route>
			
			<camel:from
				uri="timer://hello.world.request.timer?fixedRate=true&amp;period=10000"
/>
			<camel:to uri="log:hello.world.request?level=INFO?showAll=true" />
			<camel:bean ref="helloWorld" />
			
			
			<camel:marshal ref ="jack"/>
			<camel:convertBodyTo type="java.lang.String" />
			<camel:log message="${body}"/> 
            
            
			<camel:to uri="log:hello.world.response?level=INFO?showAll=true" />
			
		</camel:route>

	</camel:camelContext>
	
	<bean id="jms"
class="org.apache.activemq.camel.component.ActiveMQComponent">
		<property name="configuration" ref="jmsConfig" />
	</bean>

	<bean id="jmsConfig"
class="org.apache.camel.component.jms.JmsConfiguration">
		<property name="connectionFactory" ref="jmsConnectionFactory" />
		<property name="transacted" value="false" />
		<property name="concurrentConsumers" value="1" />
	</bean>

	<bean id="jmsConnectionFactory"
class="org.apache.activemq.ActiveMQConnectionFactory">
		<property name="brokerURL" value="vm://localhost" />
		<property name="redeliveryPolicy" ref="redeliveryPolicy" />
		<property name="prefetchPolicy" ref="prefetchPolicy" />
	</bean>

	<bean id="prefetchPolicy"
class="org.apache.activemq.ActiveMQPrefetchPolicy">
		<property name="queuePrefetch" value="5" />
	</bean>

	<bean id="redeliveryPolicy" class="org.apache.activemq.RedeliveryPolicy">
		<property name="maximumRedeliveries" value="1" />
		<property name="backOffMultiplier" value="2" />
		<property name="initialRedeliveryDelay" value="2000" />
		<property name="useExponentialBackOff" value="true" />
	</bean>
    
    
    <util:properties id="sensorProperties"
location="classpath:/sensor.properties"/>
        <bean class="sample.SensorGenerator">
            <property name="sourceProperties" ref="sensorProperties" />
        </bean>
    
    </beans>

Here is are the four Java Classes I have (HelloWorldMain.java,
HelloWorld.java, Sensor.java, and SensorGenerator.Java):

HelloWorldMain.java:

    package sample;

    import org.springframework.context.support.AbstractApplicationContext;
    import
org.springframework.context.support.ClassPathXmlApplicationContext;
    
    
    public class HelloWorldMain {
    	
	    // define context to load properties with Spring

	    public static void main(String[] args) throws Exception {

		    AbstractApplicationContext context = new
ClassPathXmlApplicationContext(
				"applicationContext.xml");
		    Thread.currentThread().join();
	    }

    }      

HelloWorld.java:

    package sample;
    
    import java.util.*;
    
    import org.apache.camel.Handler;
    import org.springframework.stereotype.Service;
    
    
    /**
     * POJO that returns Hello World string
     *
     */
    @Service
    public class HelloWorld {
    	
    	@Handler
    	public Map<?, ?> returnMap(){
    		SensorGenerator sensorGenerator = new SensorGenerator();
    		System.out.println();
    		System.out.println("Returning Map");
    		// get the map of Sensors
    		Map<String,String> mySensorMap = sensorGenerator.getSensors();
    		// print out the Sensors in the map on the console
    		Set keys = mySensorMap.keySet();
            
            for (Iterator i = keys.iterator(); i.hasNext();) {
    			String key = (String) i.next();
    			String value = (String) mySensorMap.get(key);
    			System.out.println("key= " + key + ", value= " + value);
    		}
    		return mySensorMap;
    	}

    }
    
Sensor.java (which defines the fields I'm reading from sensor.properties):

    package sample;
    
    public class Sensor {
    
    	private String make;
    	private String makeDataType;
    	private String model;
    	private String modelDataType;
    	private String serialNumber;
    	private String serialNumberDataType;
    	private String sensorType;
    	private String sensorTypeDataType;
    	
    	// getters and setters
    	public String getMake() {
    		return make;
    	}
    	public void setMake(String make) {
    		this.make = make;
    	}
    	public String getMakeDataType() {
    		return makeDataType;
    	}
    	public void setMakeDataType(String makeDataType) {
    		this.makeDataType = makeDataType;
    	}
    	public String getModel() {
    		return model;
    	}
    	public void setModel(String model) {
    		this.model = model;
    	}
    	public String getModelDataType() {
    		return modelDataType;
    	}
    	public void setModelDataType(String modelDataType) {
    		this.modelDataType = modelDataType;
    	}
    	public String getSerialNumber() {
    		return serialNumber;
    	}
    	public void setSerialNumber(String serialNumber) {
    		this.serialNumber = serialNumber;
    	}
    	public String getSerialNumberDataType() {
    		return serialNumberDataType;
    	}
    	public void setSerialNumberDataType(String serialNumberDataType) {
    		this.serialNumberDataType = serialNumberDataType;
    	}
    	public String getSensorType() {
    		return sensorType;
    	}
    	public void setSensorType(String sensorType) {
    		this.sensorType = sensorType;
    	}
    	public String getSensorTypeDataType() {
    		return sensorTypeDataType;
    	}
    	public void setSensorTypeDataType(String sensorTypeDataType) {
    		this.sensorTypeDataType = sensorTypeDataType;
    	}
    }

SensorGenerator.java (the class where I current hard-code the properties but
want to have Spring load them from sensor.properties.  If I comment out the
For loop and any lines referencing sourceProperties I can get the map
returned with the hard coded values just fine.  That's why I suspect its
some sort of Spring/Camel integration issue):

  package sample;
    
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Properties;
    
    public class SensorGenerator {
    
    	private Properties sourceProperties;
    
    	// variable to increment key number for each sensor
    	int sensorNumber = 1;
    
    	// method to inject sensor.properties into a Map using Spring
    	Map<String, String> getSensors() {
    		Map<String, String> sensorMap = new HashMap<String, String>();
    		for (Object key : sourceProperties.keySet()) {
    
    			// Separate out each of the key,value pairs as an entry in the
    			// values array
    			String[] values = sourceProperties.getProperty((String) key).split(
    					",");
    			System.out.println("values array size= " + values.length);
    
    			// define string buffer that appends sensor number for each sensor's
    			// keys.  Ex: sensor1 would have s1make, s1makeDataType, etc.
    			StringBuffer sensorNumberStringBuffer = new StringBuffer();
    			sensorNumberStringBuffer.append("s");
    			sensorNumberStringBuffer.append(sensorNumber);
    
    			// make and its data type (with sensor number prefix)
    			StringBuffer makeStringBuffer = new StringBuffer();
    			makeStringBuffer.append(sensorNumberStringBuffer);
    			makeStringBuffer.append("make");
    			StringBuffer makeDataTypeStringBuffer = new StringBuffer();
    			makeDataTypeStringBuffer.append(sensorNumberStringBuffer);
    			makeDataTypeStringBuffer.append("makeDataType");
    
    			// model and its data type (with sensor number prefix)
    			StringBuffer modelStringBuffer = new StringBuffer();
    			modelStringBuffer.append(sensorNumberStringBuffer);
    			modelStringBuffer.append("model");
    			StringBuffer modelDataTypeStringBuffer = new StringBuffer();
    			modelDataTypeStringBuffer.append(sensorNumberStringBuffer);
    			modelDataTypeStringBuffer.append("modelDataType");
    
    			// serialNumber and its data type (with sensor number prefix)
    			StringBuffer serialNumberStringBuffer = new StringBuffer();
    			serialNumberStringBuffer.append(sensorNumberStringBuffer);
    			serialNumberStringBuffer.append("serialNumber");
    			StringBuffer serialNumberDataTypeStringBuffer = new StringBuffer();
    			serialNumberDataTypeStringBuffer.append(sensorNumberStringBuffer);
    			serialNumberDataTypeStringBuffer.append("serialNumberDataType");
    
    			// sensorType and its data type (with sensor number prefix)
    			StringBuffer sensorTypeStringBuffer = new StringBuffer();
    			sensorTypeStringBuffer.append(sensorNumberStringBuffer);
    			sensorTypeStringBuffer.append("sensorType");
    			StringBuffer sensorTypeDataTypeStringBuffer = new StringBuffer();
    			sensorTypeDataTypeStringBuffer.append(sensorNumberStringBuffer);
    			sensorTypeDataTypeStringBuffer.append("sensorTypeDataType");
    
    			/*
    			  put all the key,value pairs for this sensor in the sensorMap
                */
	    		
	    		//TODO: Change all the hard coded values below to be elements
	    		// from the values array once Spring can load spring.properties
	    		
	    		// make and and its data type
	    		sensorMap.put(makeStringBuffer.toString(), "DummyMake");
	    		sensorMap.put(makeDataTypeStringBuffer.toString(), "String");
    
    			// model and and its data type
    			sensorMap.put(modelStringBuffer.toString(), "DummyModel");
    			sensorMap.put(modelDataTypeStringBuffer.toString(), "String");
    
    			// serialNumber and and its data type
    			sensorMap.put(serialNumberStringBuffer.toString(), "1234567890");
    			sensorMap.put(serialNumberDataTypeStringBuffer.toString(), "long");
    
    			// sensorType and its data type
    			sensorMap.put(sensorTypeStringBuffer.toString(), "DummyType");
    			sensorMap.put(sensorTypeDataTypeStringBuffer.toString(), "String");
    
    			// increment for next sensor
    			sensorNumber++;
    		}
    		return sensorMap;
    	}
    
    	public void setSourceProperties(Properties properties) {
    		this.sourceProperties = properties;
    	}
    
    }

Btw: Line 17 of SensorGenerator.java as mentioned in the stack trace above
is:

    		for (Object key : sourceProperties.keySet()) {
     
Here is an example sensor.properties file:

   
sensor1=DummySensor1:String,SensorModel1:String,1234567890:long,SensorType1:String
   
sensor2=DummySensor2:String,SensorModel2:String,8675309123:long,SensorType2:String



--
View this message in context: http://camel.465427.n5.nabble.com/How-do-I-load-properties-with-Spring-when-also-using-Camel-tp5741563.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Re: How do I load properties with Spring when also using Camel?

Posted by Claus Ibsen <cl...@gmail.com>.
Same question also posted on SO
http://stackoverflow.com/questions/19366350/how-do-i-load-properties-with-spring-when-also-using-camel

On Mon, Oct 14, 2013 at 8:57 PM, erj2code <pe...@tetraconcepts.com> wrote:
> I have a HelloWorld Java project that uses Camel to obtain a Map, and print
> out its contents in JSON format.  The Map currently has hardcoded values,
> but I really want to change my code so that it uses Spring to load a
> sensor.properties file of nested key,value pairs into this Map.
>
> I have another Java project I wrote that only uses Spring, and can load the
> sensor.properties file just fine into an Arraylist object.
>
> However, when I try to use code from that project to load the
> sensor.properties in my HelloWorld project I get the following Camel error
> with a NPE:
>
>     Returning Map
>     3310 [hello.world.request.timer] ERROR
> org.apache.camel.processor.DefaultErrorHandler      - Failed delivery for
> exchangeId: 4e984884-df7f-4b82-a977-f5cf4c311814. Exhausted after
> delivery attempt: 1 caught: java.lang.NullPointerException
>     java.lang.NullPointerException
>         at sample.SensorGenerator.getSensors(SensorGenerator.java:17)
>         at sample.HelloWorld.returnMap(HelloWorld.java:22)
>         at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>         at
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
>         at
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>         at java.lang.reflect.Method.invoke(Method.java:606)
>         at
> org.apache.camel.component.bean.MethodInfo.invoke(MethodInfo.java:231)
>         at
> org.apache.camel.component.bean.MethodInfo$1.proceed(MethodInfo.java:146)
>         at
> org.apache.camel.component.bean.BeanProcessor.process(BeanProcessor.java:138)
>
> org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:67)
>         at
> org.apache.camel.processor.DelegateProcessor.processNext(DelegateProcessor.java:53)
>         at
> org.apache.camel.processor.DelegateProcessor.proceed(DelegateProcessor.java:82)
>         at
> org.apache.camel.processor.interceptor.TraceInterceptor.process(TraceInterceptor.java:97)
>         at
> org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:67)
>         at
> org.apache.camel.processor.RedeliveryErrorHandler.processExchange(RedeliveryErrorHandler.java:185)
>      at
> org.apache.camel.processor.RedeliveryErrorHandler.processErrorHandler(RedeliveryErrorHandler.java:151)
>         at
> org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:89)
>         at
> org.apache.camel.processor.DefaultErrorHandler.process(DefaultErrorHandler.java:49)
>         at
> org.apache.camel.processor.DefaultChannel.process(DefaultChannel.java:228)
>         at org.apache.camel.processor.Pipeline.process(Pipeline.java:75)
>         at
> org.apache.camel.processor.UnitOfWorkProcessor.processNext(UnitOfWorkProcessor.java:70)
>         at
> org.apache.camel.processor.DelegateProcessor.process(DelegateProcessor.java:48)
>         at org.
> apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:67)
>         at
> org.apache.camel.component.timer.TimerConsumer.sendTimerExchange(TimerConsumer.java:102)
>         at
> org.apache.camel.component.timer.TimerConsumer$1.run(TimerConsumer.java:49)
>         at java.util.TimerThread.mainLoop(Timer.java:555)
>         at java.util.TimerThread.run(Timer.java:505)
>
> Is there something I need to add to my applicationContext.xml to tell Camel
> that Spring will load my sensor.properties?  Do I need to use the Spring
> integration component specified at
> http://camel.apache.org/springintegration.html ?
>
> Here is my current ApplicationContext.xml:
>
>         <?xml version="1.0" encoding="UTF-8"?>
>
>     <beans xmlns="http://www.springframework.org/schema/beans"
>             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
> xmlns:camel="http://camel.apache.org/schema/spring"
>             xmlns:context="http://www.springframework.org/schema/context"
>             xmlns:util="http://www.springframework.org/schema/util"
>             xsi:schemaLocation="
>             http://www.springframework.org/schema/beans
> http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
>             http://www.springframework.org/schema/util
> http://www.springframework.org/schema/util/spring-util-3.0.xsd
>             http://camel.apache.org/schema/spring
> http://camel.apache.org/schema/spring/camel-spring.xsd
>             http://www.springframework.org/schema/context
> http://www.springframework.org/schema/context/spring-context.xsd">
>
>         <bean
>
> class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor"
> />
>         <context:component-scan base-package="sample" />
>         <context:annotation-config />
>
>         <camel:camelContext id="HelloWorldContext">
>
>
>             <camel:dataFormats>
>           <camel:json id="jack" library="Jackson"/>
>         </camel:dataFormats>
>
>                 <camel:route>
>
>                         <camel:from
>                                 uri="timer://hello.world.request.timer?fixedRate=true&amp;period=10000"
> />
>                         <camel:to uri="log:hello.world.request?level=INFO?showAll=true" />
>                         <camel:bean ref="helloWorld" />
>
>
>                         <camel:marshal ref ="jack"/>
>                         <camel:convertBodyTo type="java.lang.String" />
>                         <camel:log message="${body}"/>
>
>
>                         <camel:to uri="log:hello.world.response?level=INFO?showAll=true" />
>
>                 </camel:route>
>
>         </camel:camelContext>
>
>         <bean id="jms"
> class="org.apache.activemq.camel.component.ActiveMQComponent">
>                 <property name="configuration" ref="jmsConfig" />
>         </bean>
>
>         <bean id="jmsConfig"
> class="org.apache.camel.component.jms.JmsConfiguration">
>                 <property name="connectionFactory" ref="jmsConnectionFactory" />
>                 <property name="transacted" value="false" />
>                 <property name="concurrentConsumers" value="1" />
>         </bean>
>
>         <bean id="jmsConnectionFactory"
> class="org.apache.activemq.ActiveMQConnectionFactory">
>                 <property name="brokerURL" value="vm://localhost" />
>                 <property name="redeliveryPolicy" ref="redeliveryPolicy" />
>                 <property name="prefetchPolicy" ref="prefetchPolicy" />
>         </bean>
>
>         <bean id="prefetchPolicy"
> class="org.apache.activemq.ActiveMQPrefetchPolicy">
>                 <property name="queuePrefetch" value="5" />
>         </bean>
>
>         <bean id="redeliveryPolicy" class="org.apache.activemq.RedeliveryPolicy">
>                 <property name="maximumRedeliveries" value="1" />
>                 <property name="backOffMultiplier" value="2" />
>                 <property name="initialRedeliveryDelay" value="2000" />
>                 <property name="useExponentialBackOff" value="true" />
>         </bean>
>
>
>     <util:properties id="sensorProperties"
> location="classpath:/sensor.properties"/>
>         <bean class="sample.SensorGenerator">
>             <property name="sourceProperties" ref="sensorProperties" />
>         </bean>
>
>     </beans>
>
> Here is are the four Java Classes I have (HelloWorldMain.java,
> HelloWorld.java, Sensor.java, and SensorGenerator.Java):
>
> HelloWorldMain.java:
>
>     package sample;
>
>     import org.springframework.context.support.AbstractApplicationContext;
>     import
> org.springframework.context.support.ClassPathXmlApplicationContext;
>
>
>     public class HelloWorldMain {
>
>             // define context to load properties with Spring
>
>             public static void main(String[] args) throws Exception {
>
>                     AbstractApplicationContext context = new
> ClassPathXmlApplicationContext(
>                                 "applicationContext.xml");
>                     Thread.currentThread().join();
>             }
>
>     }
>
> HelloWorld.java:
>
>     package sample;
>
>     import java.util.*;
>
>     import org.apache.camel.Handler;
>     import org.springframework.stereotype.Service;
>
>
>     /**
>      * POJO that returns Hello World string
>      *
>      */
>     @Service
>     public class HelloWorld {
>
>         @Handler
>         public Map<?, ?> returnMap(){
>                 SensorGenerator sensorGenerator = new SensorGenerator();
>                 System.out.println();
>                 System.out.println("Returning Map");
>                 // get the map of Sensors
>                 Map<String,String> mySensorMap = sensorGenerator.getSensors();
>                 // print out the Sensors in the map on the console
>                 Set keys = mySensorMap.keySet();
>
>             for (Iterator i = keys.iterator(); i.hasNext();) {
>                         String key = (String) i.next();
>                         String value = (String) mySensorMap.get(key);
>                         System.out.println("key= " + key + ", value= " + value);
>                 }
>                 return mySensorMap;
>         }
>
>     }
>
> Sensor.java (which defines the fields I'm reading from sensor.properties):
>
>     package sample;
>
>     public class Sensor {
>
>         private String make;
>         private String makeDataType;
>         private String model;
>         private String modelDataType;
>         private String serialNumber;
>         private String serialNumberDataType;
>         private String sensorType;
>         private String sensorTypeDataType;
>
>         // getters and setters
>         public String getMake() {
>                 return make;
>         }
>         public void setMake(String make) {
>                 this.make = make;
>         }
>         public String getMakeDataType() {
>                 return makeDataType;
>         }
>         public void setMakeDataType(String makeDataType) {
>                 this.makeDataType = makeDataType;
>         }
>         public String getModel() {
>                 return model;
>         }
>         public void setModel(String model) {
>                 this.model = model;
>         }
>         public String getModelDataType() {
>                 return modelDataType;
>         }
>         public void setModelDataType(String modelDataType) {
>                 this.modelDataType = modelDataType;
>         }
>         public String getSerialNumber() {
>                 return serialNumber;
>         }
>         public void setSerialNumber(String serialNumber) {
>                 this.serialNumber = serialNumber;
>         }
>         public String getSerialNumberDataType() {
>                 return serialNumberDataType;
>         }
>         public void setSerialNumberDataType(String serialNumberDataType) {
>                 this.serialNumberDataType = serialNumberDataType;
>         }
>         public String getSensorType() {
>                 return sensorType;
>         }
>         public void setSensorType(String sensorType) {
>                 this.sensorType = sensorType;
>         }
>         public String getSensorTypeDataType() {
>                 return sensorTypeDataType;
>         }
>         public void setSensorTypeDataType(String sensorTypeDataType) {
>                 this.sensorTypeDataType = sensorTypeDataType;
>         }
>     }
>
> SensorGenerator.java (the class where I current hard-code the properties but
> want to have Spring load them from sensor.properties.  If I comment out the
> For loop and any lines referencing sourceProperties I can get the map
> returned with the hard coded values just fine.  That's why I suspect its
> some sort of Spring/Camel integration issue):
>
>   package sample;
>
>     import java.util.HashMap;
>     import java.util.Map;
>     import java.util.Properties;
>
>     public class SensorGenerator {
>
>         private Properties sourceProperties;
>
>         // variable to increment key number for each sensor
>         int sensorNumber = 1;
>
>         // method to inject sensor.properties into a Map using Spring
>         Map<String, String> getSensors() {
>                 Map<String, String> sensorMap = new HashMap<String, String>();
>                 for (Object key : sourceProperties.keySet()) {
>
>                         // Separate out each of the key,value pairs as an entry in the
>                         // values array
>                         String[] values = sourceProperties.getProperty((String) key).split(
>                                         ",");
>                         System.out.println("values array size= " + values.length);
>
>                         // define string buffer that appends sensor number for each sensor's
>                         // keys.  Ex: sensor1 would have s1make, s1makeDataType, etc.
>                         StringBuffer sensorNumberStringBuffer = new StringBuffer();
>                         sensorNumberStringBuffer.append("s");
>                         sensorNumberStringBuffer.append(sensorNumber);
>
>                         // make and its data type (with sensor number prefix)
>                         StringBuffer makeStringBuffer = new StringBuffer();
>                         makeStringBuffer.append(sensorNumberStringBuffer);
>                         makeStringBuffer.append("make");
>                         StringBuffer makeDataTypeStringBuffer = new StringBuffer();
>                         makeDataTypeStringBuffer.append(sensorNumberStringBuffer);
>                         makeDataTypeStringBuffer.append("makeDataType");
>
>                         // model and its data type (with sensor number prefix)
>                         StringBuffer modelStringBuffer = new StringBuffer();
>                         modelStringBuffer.append(sensorNumberStringBuffer);
>                         modelStringBuffer.append("model");
>                         StringBuffer modelDataTypeStringBuffer = new StringBuffer();
>                         modelDataTypeStringBuffer.append(sensorNumberStringBuffer);
>                         modelDataTypeStringBuffer.append("modelDataType");
>
>                         // serialNumber and its data type (with sensor number prefix)
>                         StringBuffer serialNumberStringBuffer = new StringBuffer();
>                         serialNumberStringBuffer.append(sensorNumberStringBuffer);
>                         serialNumberStringBuffer.append("serialNumber");
>                         StringBuffer serialNumberDataTypeStringBuffer = new StringBuffer();
>                         serialNumberDataTypeStringBuffer.append(sensorNumberStringBuffer);
>                         serialNumberDataTypeStringBuffer.append("serialNumberDataType");
>
>                         // sensorType and its data type (with sensor number prefix)
>                         StringBuffer sensorTypeStringBuffer = new StringBuffer();
>                         sensorTypeStringBuffer.append(sensorNumberStringBuffer);
>                         sensorTypeStringBuffer.append("sensorType");
>                         StringBuffer sensorTypeDataTypeStringBuffer = new StringBuffer();
>                         sensorTypeDataTypeStringBuffer.append(sensorNumberStringBuffer);
>                         sensorTypeDataTypeStringBuffer.append("sensorTypeDataType");
>
>                         /*
>                           put all the key,value pairs for this sensor in the sensorMap
>                 */
>
>                         //TODO: Change all the hard coded values below to be elements
>                         // from the values array once Spring can load spring.properties
>
>                         // make and and its data type
>                         sensorMap.put(makeStringBuffer.toString(), "DummyMake");
>                         sensorMap.put(makeDataTypeStringBuffer.toString(), "String");
>
>                         // model and and its data type
>                         sensorMap.put(modelStringBuffer.toString(), "DummyModel");
>                         sensorMap.put(modelDataTypeStringBuffer.toString(), "String");
>
>                         // serialNumber and and its data type
>                         sensorMap.put(serialNumberStringBuffer.toString(), "1234567890");
>                         sensorMap.put(serialNumberDataTypeStringBuffer.toString(), "long");
>
>                         // sensorType and its data type
>                         sensorMap.put(sensorTypeStringBuffer.toString(), "DummyType");
>                         sensorMap.put(sensorTypeDataTypeStringBuffer.toString(), "String");
>
>                         // increment for next sensor
>                         sensorNumber++;
>                 }
>                 return sensorMap;
>         }
>
>         public void setSourceProperties(Properties properties) {
>                 this.sourceProperties = properties;
>         }
>
>     }
>
> Btw: Line 17 of SensorGenerator.java as mentioned in the stack trace above
> is:
>
>                 for (Object key : sourceProperties.keySet()) {
>
> Here is an example sensor.properties file:
>
>
> sensor1=DummySensor1:String,SensorModel1:String,1234567890:long,SensorType1:String
>
> sensor2=DummySensor2:String,SensorModel2:String,8675309123:long,SensorType2:String
>
>
>
> --
> View this message in context: http://camel.465427.n5.nabble.com/How-do-I-load-properties-with-Spring-when-also-using-Camel-tp5741563.html
> Sent from the Camel - Users mailing list archive at Nabble.com.



-- 
Claus Ibsen
-----------------
Red Hat, Inc.
Email: cibsen@redhat.com
Twitter: davsclaus
Blog: http://davsclaus.com
Author of Camel in Action: http://www.manning.com/ibsen

Re: How do I load properties with Spring when also using Camel?

Posted by Christian Posta <ch...@gmail.com>.
well... it looks like you're depending on classpath scanning to declare
your hello world bean... but I don't see any annotations for autowiring the
properties for sourceProperties field. Maybe try adding that? Or try
explicitly wiring up the dependencies, get that to work, then figure out
where in the spring magic it's failing?


On Mon, Oct 14, 2013 at 11:57 AM, erj2code <pe...@tetraconcepts.com> wrote:

> I have a HelloWorld Java project that uses Camel to obtain a Map, and print
> out its contents in JSON format.  The Map currently has hardcoded values,
> but I really want to change my code so that it uses Spring to load a
> sensor.properties file of nested key,value pairs into this Map.
>
> I have another Java project I wrote that only uses Spring, and can load the
> sensor.properties file just fine into an Arraylist object.
>
> However, when I try to use code from that project to load the
> sensor.properties in my HelloWorld project I get the following Camel error
> with a NPE:
>
>     Returning Map
>     3310 [hello.world.request.timer] ERROR
> org.apache.camel.processor.DefaultErrorHandler      - Failed delivery for
> exchangeId: 4e984884-df7f-4b82-a977-f5cf4c311814. Exhausted after
> delivery attempt: 1 caught: java.lang.NullPointerException
>     java.lang.NullPointerException
>         at sample.SensorGenerator.getSensors(SensorGenerator.java:17)
>         at sample.HelloWorld.returnMap(HelloWorld.java:22)
>         at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>         at
>
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
>         at
>
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>         at java.lang.reflect.Method.invoke(Method.java:606)
>         at
> org.apache.camel.component.bean.MethodInfo.invoke(MethodInfo.java:231)
>         at
> org.apache.camel.component.bean.MethodInfo$1.proceed(MethodInfo.java:146)
>         at
>
> org.apache.camel.component.bean.BeanProcessor.process(BeanProcessor.java:138)
>
>
> org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:67)
>         at
>
> org.apache.camel.processor.DelegateProcessor.processNext(DelegateProcessor.java:53)
>         at
>
> org.apache.camel.processor.DelegateProcessor.proceed(DelegateProcessor.java:82)
>         at
>
> org.apache.camel.processor.interceptor.TraceInterceptor.process(TraceInterceptor.java:97)
>         at
>
> org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:67)
>         at
>
> org.apache.camel.processor.RedeliveryErrorHandler.processExchange(RedeliveryErrorHandler.java:185)
>      at
>
> org.apache.camel.processor.RedeliveryErrorHandler.processErrorHandler(RedeliveryErrorHandler.java:151)
>         at
>
> org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:89)
>         at
>
> org.apache.camel.processor.DefaultErrorHandler.process(DefaultErrorHandler.java:49)
>         at
> org.apache.camel.processor.DefaultChannel.process(DefaultChannel.java:228)
>         at org.apache.camel.processor.Pipeline.process(Pipeline.java:75)
>         at
>
> org.apache.camel.processor.UnitOfWorkProcessor.processNext(UnitOfWorkProcessor.java:70)
>         at
>
> org.apache.camel.processor.DelegateProcessor.process(DelegateProcessor.java:48)
>         at org.
>
> apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:67)
>         at
>
> org.apache.camel.component.timer.TimerConsumer.sendTimerExchange(TimerConsumer.java:102)
>         at
> org.apache.camel.component.timer.TimerConsumer$1.run(TimerConsumer.java:49)
>         at java.util.TimerThread.mainLoop(Timer.java:555)
>         at java.util.TimerThread.run(Timer.java:505)
>
> Is there something I need to add to my applicationContext.xml to tell Camel
> that Spring will load my sensor.properties?  Do I need to use the Spring
> integration component specified at
> http://camel.apache.org/springintegration.html ?
>
> Here is my current ApplicationContext.xml:
>
>         <?xml version="1.0" encoding="UTF-8"?>
>
>     <beans xmlns="http://www.springframework.org/schema/beans"
>             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
> xmlns:camel="http://camel.apache.org/schema/spring"
>             xmlns:context="http://www.springframework.org/schema/context"
>             xmlns:util="http://www.springframework.org/schema/util"
>             xsi:schemaLocation="
>             http://www.springframework.org/schema/beans
> http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
>             http://www.springframework.org/schema/util
> http://www.springframework.org/schema/util/spring-util-3.0.xsd
>             http://camel.apache.org/schema/spring
> http://camel.apache.org/schema/spring/camel-spring.xsd
>             http://www.springframework.org/schema/context
> http://www.springframework.org/schema/context/spring-context.xsd">
>
>         <bean
>
>
> class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor"
> />
>         <context:component-scan base-package="sample" />
>         <context:annotation-config />
>
>         <camel:camelContext id="HelloWorldContext">
>
>
>             <camel:dataFormats>
>           <camel:json id="jack" library="Jackson"/>
>         </camel:dataFormats>
>
>                 <camel:route>
>
>                         <camel:from
>
> uri="timer://hello.world.request.timer?fixedRate=true&amp;period=10000"
> />
>                         <camel:to
> uri="log:hello.world.request?level=INFO?showAll=true" />
>                         <camel:bean ref="helloWorld" />
>
>
>                         <camel:marshal ref ="jack"/>
>                         <camel:convertBodyTo type="java.lang.String" />
>                         <camel:log message="${body}"/>
>
>
>                         <camel:to
> uri="log:hello.world.response?level=INFO?showAll=true" />
>
>                 </camel:route>
>
>         </camel:camelContext>
>
>         <bean id="jms"
> class="org.apache.activemq.camel.component.ActiveMQComponent">
>                 <property name="configuration" ref="jmsConfig" />
>         </bean>
>
>         <bean id="jmsConfig"
> class="org.apache.camel.component.jms.JmsConfiguration">
>                 <property name="connectionFactory"
> ref="jmsConnectionFactory" />
>                 <property name="transacted" value="false" />
>                 <property name="concurrentConsumers" value="1" />
>         </bean>
>
>         <bean id="jmsConnectionFactory"
> class="org.apache.activemq.ActiveMQConnectionFactory">
>                 <property name="brokerURL" value="vm://localhost" />
>                 <property name="redeliveryPolicy" ref="redeliveryPolicy" />
>                 <property name="prefetchPolicy" ref="prefetchPolicy" />
>         </bean>
>
>         <bean id="prefetchPolicy"
> class="org.apache.activemq.ActiveMQPrefetchPolicy">
>                 <property name="queuePrefetch" value="5" />
>         </bean>
>
>         <bean id="redeliveryPolicy"
> class="org.apache.activemq.RedeliveryPolicy">
>                 <property name="maximumRedeliveries" value="1" />
>                 <property name="backOffMultiplier" value="2" />
>                 <property name="initialRedeliveryDelay" value="2000" />
>                 <property name="useExponentialBackOff" value="true" />
>         </bean>
>
>
>     <util:properties id="sensorProperties"
> location="classpath:/sensor.properties"/>
>         <bean class="sample.SensorGenerator">
>             <property name="sourceProperties" ref="sensorProperties" />
>         </bean>
>
>     </beans>
>
> Here is are the four Java Classes I have (HelloWorldMain.java,
> HelloWorld.java, Sensor.java, and SensorGenerator.Java):
>
> HelloWorldMain.java:
>
>     package sample;
>
>     import org.springframework.context.support.AbstractApplicationContext;
>     import
> org.springframework.context.support.ClassPathXmlApplicationContext;
>
>
>     public class HelloWorldMain {
>
>             // define context to load properties with Spring
>
>             public static void main(String[] args) throws Exception {
>
>                     AbstractApplicationContext context = new
> ClassPathXmlApplicationContext(
>                                 "applicationContext.xml");
>                     Thread.currentThread().join();
>             }
>
>     }
>
> HelloWorld.java:
>
>     package sample;
>
>     import java.util.*;
>
>     import org.apache.camel.Handler;
>     import org.springframework.stereotype.Service;
>
>
>     /**
>      * POJO that returns Hello World string
>      *
>      */
>     @Service
>     public class HelloWorld {
>
>         @Handler
>         public Map<?, ?> returnMap(){
>                 SensorGenerator sensorGenerator = new SensorGenerator();
>                 System.out.println();
>                 System.out.println("Returning Map");
>                 // get the map of Sensors
>                 Map<String,String> mySensorMap =
> sensorGenerator.getSensors();
>                 // print out the Sensors in the map on the console
>                 Set keys = mySensorMap.keySet();
>
>             for (Iterator i = keys.iterator(); i.hasNext();) {
>                         String key = (String) i.next();
>                         String value = (String) mySensorMap.get(key);
>                         System.out.println("key= " + key + ", value= " +
> value);
>                 }
>                 return mySensorMap;
>         }
>
>     }
>
> Sensor.java (which defines the fields I'm reading from sensor.properties):
>
>     package sample;
>
>     public class Sensor {
>
>         private String make;
>         private String makeDataType;
>         private String model;
>         private String modelDataType;
>         private String serialNumber;
>         private String serialNumberDataType;
>         private String sensorType;
>         private String sensorTypeDataType;
>
>         // getters and setters
>         public String getMake() {
>                 return make;
>         }
>         public void setMake(String make) {
>                 this.make = make;
>         }
>         public String getMakeDataType() {
>                 return makeDataType;
>         }
>         public void setMakeDataType(String makeDataType) {
>                 this.makeDataType = makeDataType;
>         }
>         public String getModel() {
>                 return model;
>         }
>         public void setModel(String model) {
>                 this.model = model;
>         }
>         public String getModelDataType() {
>                 return modelDataType;
>         }
>         public void setModelDataType(String modelDataType) {
>                 this.modelDataType = modelDataType;
>         }
>         public String getSerialNumber() {
>                 return serialNumber;
>         }
>         public void setSerialNumber(String serialNumber) {
>                 this.serialNumber = serialNumber;
>         }
>         public String getSerialNumberDataType() {
>                 return serialNumberDataType;
>         }
>         public void setSerialNumberDataType(String serialNumberDataType) {
>                 this.serialNumberDataType = serialNumberDataType;
>         }
>         public String getSensorType() {
>                 return sensorType;
>         }
>         public void setSensorType(String sensorType) {
>                 this.sensorType = sensorType;
>         }
>         public String getSensorTypeDataType() {
>                 return sensorTypeDataType;
>         }
>         public void setSensorTypeDataType(String sensorTypeDataType) {
>                 this.sensorTypeDataType = sensorTypeDataType;
>         }
>     }
>
> SensorGenerator.java (the class where I current hard-code the properties
> but
> want to have Spring load them from sensor.properties.  If I comment out the
> For loop and any lines referencing sourceProperties I can get the map
> returned with the hard coded values just fine.  That's why I suspect its
> some sort of Spring/Camel integration issue):
>
>   package sample;
>
>     import java.util.HashMap;
>     import java.util.Map;
>     import java.util.Properties;
>
>     public class SensorGenerator {
>
>         private Properties sourceProperties;
>
>         // variable to increment key number for each sensor
>         int sensorNumber = 1;
>
>         // method to inject sensor.properties into a Map using Spring
>         Map<String, String> getSensors() {
>                 Map<String, String> sensorMap = new HashMap<String,
> String>();
>                 for (Object key : sourceProperties.keySet()) {
>
>                         // Separate out each of the key,value pairs as an
> entry in the
>                         // values array
>                         String[] values =
> sourceProperties.getProperty((String) key).split(
>                                         ",");
>                         System.out.println("values array size= " +
> values.length);
>
>                         // define string buffer that appends sensor number
> for each sensor's
>                         // keys.  Ex: sensor1 would have s1make,
> s1makeDataType, etc.
>                         StringBuffer sensorNumberStringBuffer = new
> StringBuffer();
>                         sensorNumberStringBuffer.append("s");
>                         sensorNumberStringBuffer.append(sensorNumber);
>
>                         // make and its data type (with sensor number
> prefix)
>                         StringBuffer makeStringBuffer = new StringBuffer();
>                         makeStringBuffer.append(sensorNumberStringBuffer);
>                         makeStringBuffer.append("make");
>                         StringBuffer makeDataTypeStringBuffer = new
> StringBuffer();
>
> makeDataTypeStringBuffer.append(sensorNumberStringBuffer);
>                         makeDataTypeStringBuffer.append("makeDataType");
>
>                         // model and its data type (with sensor number
> prefix)
>                         StringBuffer modelStringBuffer = new
> StringBuffer();
>                         modelStringBuffer.append(sensorNumberStringBuffer);
>                         modelStringBuffer.append("model");
>                         StringBuffer modelDataTypeStringBuffer = new
> StringBuffer();
>
> modelDataTypeStringBuffer.append(sensorNumberStringBuffer);
>                         modelDataTypeStringBuffer.append("modelDataType");
>
>                         // serialNumber and its data type (with sensor
> number prefix)
>                         StringBuffer serialNumberStringBuffer = new
> StringBuffer();
>
> serialNumberStringBuffer.append(sensorNumberStringBuffer);
>                         serialNumberStringBuffer.append("serialNumber");
>                         StringBuffer serialNumberDataTypeStringBuffer =
> new StringBuffer();
>
> serialNumberDataTypeStringBuffer.append(sensorNumberStringBuffer);
>
> serialNumberDataTypeStringBuffer.append("serialNumberDataType");
>
>                         // sensorType and its data type (with sensor
> number prefix)
>                         StringBuffer sensorTypeStringBuffer = new
> StringBuffer();
>
> sensorTypeStringBuffer.append(sensorNumberStringBuffer);
>                         sensorTypeStringBuffer.append("sensorType");
>                         StringBuffer sensorTypeDataTypeStringBuffer = new
> StringBuffer();
>
> sensorTypeDataTypeStringBuffer.append(sensorNumberStringBuffer);
>
> sensorTypeDataTypeStringBuffer.append("sensorTypeDataType");
>
>                         /*
>                           put all the key,value pairs for this sensor in
> the sensorMap
>                 */
>
>                         //TODO: Change all the hard coded values below to
> be elements
>                         // from the values array once Spring can load
> spring.properties
>
>                         // make and and its data type
>                         sensorMap.put(makeStringBuffer.toString(),
> "DummyMake");
>                         sensorMap.put(makeDataTypeStringBuffer.toString(),
> "String");
>
>                         // model and and its data type
>                         sensorMap.put(modelStringBuffer.toString(),
> "DummyModel");
>
> sensorMap.put(modelDataTypeStringBuffer.toString(), "String");
>
>                         // serialNumber and and its data type
>                         sensorMap.put(serialNumberStringBuffer.toString(),
> "1234567890");
>
> sensorMap.put(serialNumberDataTypeStringBuffer.toString(), "long");
>
>                         // sensorType and its data type
>                         sensorMap.put(sensorTypeStringBuffer.toString(),
> "DummyType");
>
> sensorMap.put(sensorTypeDataTypeStringBuffer.toString(), "String");
>
>                         // increment for next sensor
>                         sensorNumber++;
>                 }
>                 return sensorMap;
>         }
>
>         public void setSourceProperties(Properties properties) {
>                 this.sourceProperties = properties;
>         }
>
>     }
>
> Btw: Line 17 of SensorGenerator.java as mentioned in the stack trace above
> is:
>
>                 for (Object key : sourceProperties.keySet()) {
>
> Here is an example sensor.properties file:
>
>
>
> sensor1=DummySensor1:String,SensorModel1:String,1234567890:long,SensorType1:String
>
>
> sensor2=DummySensor2:String,SensorModel2:String,8675309123:long,SensorType2:String
>
>
>
> --
> View this message in context:
> http://camel.465427.n5.nabble.com/How-do-I-load-properties-with-Spring-when-also-using-Camel-tp5741563.html
> Sent from the Camel - Users mailing list archive at Nabble.com.
>



-- 
*Christian Posta*
http://www.christianposta.com/blog
twitter: @christianposta