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 <p...@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: cib...@redhat.com
Twitter: davsclaus
Blog: http://davsclaus.com
Author of Camel in Action: http://www.manning.com/ibsen

Reply via email to