Announcement Announcement Module
Collapse
No announcement yet.
FlatFileHeaderCallback Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • FlatFileHeaderCallback

    Hi all,

    I've a callback class for printing header on file:
    Code:
    public class HeaderCallback implements FlatFileHeaderCallback{
    
    	private String header = null;
    		
    	public void writeHeader(Writer writer) throws IOException {
    		if( header != null &&  (! header.isEmpty()) )
    			writer.write(header);
    	}
    
    	public void setHeader(String header) {
    		this.header = header;
    	}
    
    	public String getHeader() {
    		return header;
    	}
    
    }
    The private property is the header line I want to print (specified in an external job properties file used in the xml file: ${header.line} ) .

    The problem is that a "line.separator" is always generated when registering a FlatFileHeaderCallback onto corresponding FlatFileItemWriter.

    The only way for not printing "line.separator" is letting inject a null object in headerCallback property of FlatFileItemWriter. But I get a NullPointerException during context start up phase.

    I just need something like:

    Code:
    <bean id="csvWriter" class="org....FlatFileItemWriter">
    	....some other stuff.....	
        <property name="headerCallback" >
    	<bean factory-bean="headerFactory" >
        </bean>
    </property>
    		
    </bean>
    where headerFactory returns null if no ${header.line} is specified in properties file.

    How can I allow Spring to inject null object into bean properties?
    Otherwise, how can I provide a kind of conditional injection?

    Thanks,
    Luigi

  • #2
    I didn't really understand the question yet. You want a header callback, but you don't want to emit the line separator between the header and the main fail, or you don't want to emit the line separator at all ever? I don't think there are any restrictions on the value of the line separator, so I assume you want the former? If so it sounds a bit strange - it doesn't really fit the definition of a header. But I didn't understand the bit about "conditional injection" so I'm probably missing something. There is nothing to stop you injecting null into a bean definition, but I don't understand why you want to do that.

    Comment


    • #3
      Thank you for reply! Well I try to explain better.

      I would configure my header line from a properties file without add and remove the header callback property in the FlatFileItemWriter of my XML configuration.

      header.line=MY CUSTOM HEADER LINE

      I would have no header line in case of empty property ( header.line= ). I don't want a blank line with the carriage return to be printed on top.

      Below the snippet of FlatFileItemWriter where checking headerCallback. So I would header callback to be null on demand (with a FactoryBean). But Spring gives me NullPointerException when trying to inject a null FlatFileHeaderCallback
      Code:
      if (headerCallback != null) {	
      try { 
          headerCallback.writeHeader(outputState.outputBufferedWriter);
          outputState.write(lineSeparator);
      }
      I hope is more clear

      thanks again

      Comment


      • #4
        I'm not sure why you wouldn't be able to inject null. If that's the issue how are you doing it and what is the error?

        Comment


        • #5
          Well that's all:

          Code:
          <property name="headerCallback"> //Property of FlatFileItemWriter
              <bean class="com.primeur.listener.HeaderCallback" 
                   factory-method="createHeaderCallback">
                         <constructor-arg value=""></constructor-arg>
             </bean>
          </property>
          where createHeaderCallback is a static method that returns null in case of empty parameter or a new HeaderCallback otherwise.

          This is the stacktrace:

          Code:
          org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'lazyBindingProxy.csvWriter#sysinit' defined in class path resource [job-datatimerec-diff.xml]: Initialization of bean failed; nested exception is java.lang.NullPointerException
          	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:480)
          	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409)
          	at java.security.AccessController.doPrivileged(Native Method)
          	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380)
          	at org.springframework.beans.factory.support.AbstractBeanFactory$2.getObject(AbstractBeanFactory.java:302)
          	at org.springframework.batch.core.scope.StepScope.get(StepScope.java:150)
          	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
          	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:185)
          	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:164)
          	at org.springframework.batch.core.scope.util.PlaceholderTargetSource.getTarget(PlaceholderTargetSource.java:185)
          	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:184)
          	at $Proxy17.open(Unknown Source)
          	at org.springframework.batch.item.support.CompositeItemStream.open(CompositeItemStream.java:98)
          	at org.springframework.batch.core.step.tasklet.TaskletStep.open(TaskletStep.java:288)
          	at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:193)
          	at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:135)
          	at org.springframework.batch.core.job.flow.JobFlowExecutor.executeStep(JobFlowExecutor.java:61)
          	at org.springframework.batch.core.job.flow.support.state.StepState.handle(StepState.java:60)
          	at org.springframework.batch.core.job.flow.support.SimpleFlow.resume(SimpleFlow.java:144)
          	at org.springframework.batch.core.job.flow.support.SimpleFlow.start(SimpleFlow.java:124)
          	at org.springframework.batch.core.job.flow.FlowJob.doExecute(FlowJob.java:135)
          	at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:281)
          	at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:120)
          	at java.lang.Thread.run(Thread.java:619)
          Caused by: java.lang.NullPointerException
          	at org.springframework.batch.core.scope.util.PlaceholderTargetSource$1.convertIfNecessary(PlaceholderTargetSource.java:148)
          	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.convertForProperty(AbstractAutowireCapableBeanFactory.java:1294)
          	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1250)
          	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1010)
          	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:472)
          	... 23 more
          Last edited by luigi.toziani; Mar 8th, 2011, 11:19 AM. Reason: Forgot stacktrace

          Comment


          • #6
            Interesting. Looks like a corner case bug in Spring Batch PlaceholderTargetSource. This component isn't used if you use Spring 3, so you could try that (and raise a ticket in JIRA), or if you could remove the scope="step" from the enclosing bean definition that would work too.

            Comment


            • #7
              Well, thanks.

              Anyway I tried removing scope step from writer but nothing happened. I will try to use Spring 3.0. (Actually using 2.5.6)

              Comment

              Working...
              X