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&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