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

  • hello World batch

    Is there something wrong with this configuration?
    Code:
      <bean id="hello" class="org.springframework.batch.sample.tasklet.PrintTasklet">  
          <property name="message" value="Hello"/>  
      </bean>
      <bean id="space" class="org.springframework.batch.sample.tasklet.PrintTasklet">  
          <property name="message" value=" ## "/>  
      </bean>
      <bean id="world" class="org.springframework.batch.sample.tasklet.PrintTasklet">  
          <property name="message" value="World!!!"/>  
      </bean>
      <bean id="taskletStep" abstract="true"  
          class="org.springframework.batch.core.step.tasklet.TaskletStep">  
          <property name="jobRepository" ref="jobRepository"/>  
      </bean>  
      <bean id="simpleJob" class="org.springframework.batch.core.job.SimpleJob">  
          <property name="name" value="simpleJob" />  
          <property name="steps">  
           <list> 
                  <bean parent="taskletStep">  
                      <property name="tasklet" ref="hello"/>  
                  </bean>  
                   <bean parent="taskletStep">  
                      <property name="tasklet" ref="space"/>  
                  </bean>  
                  <bean parent="taskletStep">;   
                      <property name="tasklet" ref="world"/>  
                  </bean>  
           </list> 
          </property>  
          <property name="jobRepository" ref="jobRepository"/>  
      </bean>
    I am getting this exception:
    Code:
    org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Failed to import bean definitions from URL location [classpath:/jobs/helloWorld.xml]
    Offending resource: class path resource [org/springframework/batch/sample/HelloWorldFunctionalTests-context.xml]; nested exception is org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: Line 49 in XML document from class path resource [jobs/helloWorld.xml] is invalid; nested exception is org.xml.sax.SAXParseException: cvc-complex-type.2.3: Element 'bean' cannot have character [children], because the type's content type is element-only.	at org.springframework.beans.factory.parsing.FailFastProblemReporter.error(FailFastProblemReporter.java:68)
    	at org.springframework.beans.factory.parsing.ReaderContext.error(ReaderContext.java:85)
    	at org.springframework.beans.factory.parsing.ReaderContext.error(ReaderContext.java:76)
    	at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.importBeanDefinitionResource(DefaultBeanDefinitionDocumentReader.java:182)
    	at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.parseDefaultElement(DefaultBeanDefinitionDocumentReader.java:147)
    	at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.parseBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:132)
    	at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.registerBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:92)
    	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.registerBeanDefinitions(XmlBeanDefinitionReader.java:507)
    	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:398)
    	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:342)
    	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:310)
    	at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:143)
    	at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:178)
    	at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:149)
    	at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:212)
    	at org.springframework.test.AbstractSingleSpringContextTests.createApplicationContext(AbstractSingleSpringContextTests.java:242)
    	at org.springframework.test.AbstractSingleSpringContextTests.loadContextLocations(AbstractSingleSpringContextTests.java:212)
    	at org.springframework.test.AbstractSingleSpringContextTests.loadContext(AbstractSingleSpringContextTests.java:187)
    	at org.springframework.test.AbstractSpringContextTests.getContext(AbstractSpringContextTests.java:140)
    	at org.springframework.test.AbstractSingleSpringContextTests.setUp(AbstractSingleSpringContextTests.java:100)
    	at junit.framework.TestCase.runBare(TestCase.java:132)
    	at org.springframework.test.ConditionalTestCase.runBare(ConditionalTestCase.java:76)
    	at junit.framework.TestResult$1.protect(TestResult.java:110)
    	at junit.framework.TestResult.runProtected(TestResult.java:128)
    	at junit.framework.TestResult.run(TestResult.java:113)
    	at junit.framework.TestCase.run(TestCase.java:124)
    	at junit.framework.TestSuite.runTest(TestSuite.java:232)
    	at junit.framework.TestSuite.run(TestSuite.java:227)
    	at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:81)
    	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:38)
    	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
    [B]Caused by: org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: Line 49 in XML document from class path resource [jobs/helloWorld.xml] is invalid; nested exception is org.xml.sax.SAXParseException: cvc-complex-type.2.3: Element 'bean' cannot have character [children], because the type's content type is element-only.	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:404)
    	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:342)
    	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:310)
    	at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:143)
    	at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:178)
    	at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.importBeanDefinitionResource(DefaultBeanDefinitionDocumentReader.java:174)
    	... 31 more
    Caused by: org.xml.sax.SAXParseException: cvc-complex-type.2.3: Element 'bean' cannot have character [children], because the type's content type is element-only.
    	at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source)
    	at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.error(Unknown Source)
    	at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source)
    	at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source)
    	at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator$XSIErrorReporter.reportError(Unknown Source)
    	at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.reportSchemaError(Unknown Source)
    	at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.elementLocallyValidComplexType(Unknown Source)
    	at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.elementLocallyValidType(Unknown Source)
    	at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.processElementContent(Unknown Source)
    	at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.handleEndElement(Unknown Source)
    	at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.endElement(Unknown Source)
    	at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanEndElement(Unknown Source)
    	at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
    	at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
    	at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
    	at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
    	at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
    	at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(Unknown Source)
    	at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(Unknown Source)
    	at org.springframework.beans.factory.xml.DefaultDocumentLoader.loadDocument(DefaultDocumentLoader.java:75)
    	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:396)
    	... 36 more

  • #2
    Go to line 49 as the stacktrace guides you and watch for special characters that need to be escaped in the enclosing bean definition (not really batch related btw).

    UPDATE: even better look for trailing semicolon

    Comment


    • #3
      Well how stupid can i get!

      I was thinking there is an issue with simpleJob Bean because if I use a single step, it works. was thinking its not able to take a <List>

      Sorry abt that...

      Comment


      • #4
        Don't worry, it's no stupider than the author of the
        "Hello World" Spring Batch article on dzone, Tareq Abed Rabbo,
        who had those typos in the original article and on his blog.

        -Paul

        p.s. For those who find this post before his article, I haven't been posting long enough to link externally so just search for the second line of this post and you'll find his article.

        Comment


        • #5
          The blog link is http://java.dzone.com/news/spring-batch-hello-world-1. It's a useful contribution (despite using only TaskletStep, which is not the majority use case).

          Comment


          • #6
            Corrections

            Thanks Dave. I also thought to mention that a few other coding typos are listed by me on a reply to the DZone article. I don't know about others but I'm sometimes ready to bite someone (not necessarily the author mind you*) when I can't get through a "Hello World" program without finding code typos in things I don't yet understand, so I spend too long figuring out where the problem is.

            -P

            *I'm sure the author is wondering how how the heck those typos got in his article.

            Comment


            • #7
              spring batch

              Hi,

              I'm beginner with spring quartz and i have a problem for my project.

              I'would whan my job is failed or sleep, the scheduler relance it and the job can retake
              where it has stopped.

              This is a differents steps how i was did :
              In the first i have m y class scheduler:

              Code:
              @DisallowConcurrentExecution
              public class JobLauncherDetails extends QuartzJobBean /*implements JobExecutionListener*/ {
              
              	private static final String JOB_DATA_MAP_MAX_RETRY = "maxRetry";
              	//private static final String JOB_DATA_MAP_NB_RETRIES = "nbRetries";
              	private final static String JOB_LOCATOR_CONTEXT_KEY = "jobLocator";
              	private final static String JOB_LAUNCHER_CONTEXT_KEY = "jobLauncher";
              	private static final String JOB_DATA_MAP_START_DATE = "startDate";
              	private static final String JOB_PARAM_LISTENER_DELAY_KEY = "listenerDelay";
              	private static final long JOB_PARAM_DEFAULT_LISTENER_DELAY = 1000;
              
              	private static Logger log = LoggerFactory.getLogger(JobLauncherDetails.class);
              
              	/**
              	 * Special key in job data map for the name of a job to run.
              	 */
              	private static final String JOB_NAME = "jobName";
              
              	private JobLocator jobLocator;
              	private JobLauncher jobLauncher;
              	private String jobName;
                  private JobListener MyjobListener;
              	/**
              	 * Method called by Quartz trigger. The given {@link JobExecutionContext}
              	 * gives info on the Job to run.
              	 */
              	protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
              		try {
              			jobLocator = (JobLocator) context.getScheduler().getContext().get(JOB_LOCATOR_CONTEXT_KEY);
              			jobLauncher = (JobLauncher) context.getScheduler().getContext().get(JOB_LAUNCHER_CONTEXT_KEY);
              			MyjobListener=(JobListener)context.getScheduler().getContext().get(MyjobListener);
              			
              		
              		} catch (SchedulerException se) {
              			log.error("Unable to get jobLocator and jobLauncher from scheduler context.", se);
              		}
              
              		if (jobLocator == null || jobLauncher == null) {
              			log.error("Unable to run a job without valids jobLocator and jobLauncher.");
              		} else {
              			JobDetail jobDetail = context.getJobDetail();
              			Map<String, Object> jobDataMap = context.getMergedJobDataMap();
              			
              			if (jobDataMap == null || jobDataMap.size() == 0) {
              				log.error("Unable to run a job without a valid jobDataMap (no job name provided...).");
              			} else {
              				
              				jobName = (String) jobDataMap.get(JOB_NAME);
              
              				if (jobName == null || jobName.isEmpty()) {
              					log.error("Unable to run a job: no job name provided...");
              				} else {
              					
              					if(context.getRefireCount()==0) {
              						// Add a date to the jobDataMap so that the job is unique.
              						// It is useful to distinguish 2 instances of the same trigger.
              						// Otherwise, a JobExecutionAlreadyRunningException will be launched
              						// (no need to modify this parameter for a refired job)
              						jobDataMap.put(JOB_DATA_MAP_START_DATE, new Date());
              					}
              
              					JobParameters jobParameters = getJobParametersFromJobMap(jobDataMap);
              					Scheduler sched= context.getScheduler();
              					try {
              						sched.getListenerManager().addJobListener(new NcaJobListener());
              						
              					} catch (SchedulerException e) {
              						// TODO Auto-generated catch block
              						e.printStackTrace();
              					}	
              					
              					if (log.isInfoEnabled())
              						log.info("\n**********************************************************************\n" 
              								+ "* Quartz trigger - start job: {}. Key: {}\n"
              								+ "* Firing unique ID: {}\n" 
              								+ "* Refire count: {}\n" 
              								+ "* Job parameters: {}\n"
              								+ "* isConcurrentExectionDisallowed: {}\n"
              								+ "**********************************************************************\n",
              								new Object[] { jobName, jobDetail==null?"":jobDetail.getKey(), context.getFireInstanceId(), 
              												context.getRefireCount(), jobParameters==null?"":jobParameters.toString(), 
              												context.getJobDetail().isConcurrentExectionDisallowed() });
              					
              					JobExecution jobExec = null;
              					BatchStatus jobStatus = BatchStatus.UNKNOWN;
              
              					try {
              						jobExec = jobLauncher.run(jobLocator.getJob(jobName), jobParameters);
              						log.info("Job Id: {}", jobExec.getId());
              
              					}
              
              					} catch (Exception ex) {
              						if(!(ex instanceof JobExecutionException)) {
              							log.error("Error while running Job [{}]. Rescheduling if possible.\nError: {}\n******************************", jobName, ex.toString());
              							// TODO: retirer ce log...
              							log.error("Error full stack:", ex);
              							
              						} else {
              							throw (JobExecutionException) ex;
              						}
              					}
              
              					if (log.isInfoEnabled())
              						log.info("\n**********************************************************************\n" 
              								+ "* Quartz trigger - end job: {}\n"
              								+ "* Firing unique ID: {}\n" 
              								+ "* Refire count: {}\n" 
              								+ "* Job parameters: {}\n"
              								+ "* Start date: {}\n"
              								+ "* End date: {}\n"
              								+ "* Status: {}\n"
              								+ "**********************************************************************\n",
              								new Object[] { jobName, context.getFireInstanceId(), context.getRefireCount(), 
              												jobParameters==null?"":jobParameters.toString(),
              												jobExec==null?"":jobExec.getStartTime(),
              												jobExec==null?"":jobExec.getEndTime(),
              												jobStatus });
              				}
              			}
              		}
              	}
              
              	/**
              	 * Copy parameters that are of the correct type over to
              	 * {@link JobParameters}, ignoring jobName.
              	 * 
              	 * @return a {@link JobParameters} instance
              	 */
              	private JobParameters getJobParametersFromJobMap(Map<String, Object> jobDataMap) {
              
              		JobParametersBuilder builder = new JobParametersBuilder();
              
              		for (Entry<String, Object> entry : jobDataMap.entrySet()) {
              			String key = entry.getKey();
              			Object value = entry.getValue();
              			if (value instanceof String && !key.equals(JOB_NAME)) {
              				builder.addString(key, (String) value);
              			} else if (value instanceof Float || value instanceof Double) {
              				builder.addDouble(key, ((Number) value).doubleValue());
              			} else if (value instanceof Integer || value instanceof Long) {
              				builder.addLong(key, ((Number) value).longValue());
              			} else if (value instanceof Date) {
              				builder.addDate(key, (Date) value);
              			} else {
              				log.debug("JobDataMap contains values which are not job parameters (ignoring).");
              			}
              		}
              
              		return builder.toJobParameters();
              	}
              
              	/*@Override
              	public void afterJob(JobExecution jobExecution) {
              		// TODO Auto-generated method stub
              		log.info("*************************** Job ended with status: {} ********************", jobExecution.getExitStatus());
              
              		if (ExitStatus.FAILED.equals(jobExecution.getExitStatus())) {
              			log.error("******************************\nJob [{}] failed. Reschedule if possible.\n******************************", jobName);
              
              			// rescheduleJob(jobExecution);
              		}
              	}
              
              	@Override
              	public void beforeJob(JobExecution jobExecution) {
              		log.info("************** Before running job {} **************", jobName);
              	}*/
              
              }

              Comment


              • #8
                In the second i have a class jobfaileur:

                Code:
                public class JobFailureListener implements JobExecutionListener {
                	private static Logger log = LoggerFactory.getLogger(JobFailureListener.class);
                	private static final String JOB_DATA_MAP_MAX_RETRY = "maxRetry";
                	private static final String JOB_NAME = "jobName";
                	private String jobName;
                	public void beforeJob(JobExecution jobExecution) {
                	// nothing to do
                		log.info("*************************** Job ended with status: {} ********************", jobExecution.getExitStatus());
                	}
                
                	public void afterJob(JobExecution jobExecution, JobExecutionContext context) throws JobExecutionException {
                	
                		if( jobExecution.getStatus() == BatchStatus.COMPLETED ){
                			System.out.println("!!!!!!!!!!!!!!!!!  sa	 marche !!!!!!!!!!!!!!!!");
                	    }
                		
                		else
                		
                			if (!jobExecution.getAllFailureExceptions().isEmpty()) {
                	ExitStatus exitStatus = ExitStatus.FAILED;
                	log.error("******************************\nJob [{}] failed. Reschedule if possible.\n******************************");
                	
                	//rescheduler if possible
                	rescheduleJob(jobExecution, context);
                	
                	for (Throwable e : jobExecution.getAllFailureExceptions()) {
                
                	exitStatus = exitStatus.addExitDescription(e);
                
                	}
                
                	jobExecution.setExitStatus(exitStatus);
                
                	}
                
                	}
                
                	private void rescheduleJob(JobExecution jobExec, JobExecutionContext context) throws JobExecutionException {
                		rescheduleJob(jobExec, context, null);
                	}
                
                	private void rescheduleJob(JobExecution jobExec, JobExecutionContext context, Throwable excep) throws JobExecutionException {
                		// TODO: Gérer la politique de réessai, ex :
                		// http://stackoverflow.com/questions/4408858/quartz-retry-when-failure
                	
                		if(jobExec == null)
                			throw new IllegalArgumentException("jobExec cannot be null.");
                		
                		if(context == null)
                			throw new IllegalArgumentException("context cannot be null.");
                		
                		String fireInstanceId =   context.getFireInstanceId();
                		int refireCount = context.getRefireCount();
                		
                		if (log.isInfoEnabled())
                			log.info("\n**********************************************************************\n" 
                					+ "* Quartz trigger - rescheduling job: {}\n"
                					+ "* Firing unique ID: {}\n" 
                					+ "* Refire count: {}\n" 
                					+ "**********************************************************************\n",
                					new Object[] { jobName, fireInstanceId, refireCount});
                		
                		JobDataMap dataMap = context.getJobDetail().getJobDataMap();
                		int maxRetry = dataMap.getIntValue(JOB_DATA_MAP_MAX_RETRY);
                		
                		JobExecutionException jobExecutionException = null;
                		
                        if(maxRetry>0 && refireCount<maxRetry) {        	
                        	jobExecutionException = new JobExecutionException("Error: the job [" + jobName + "] didn't end properly, refire it immediately.", excep);
                        	jobExecutionException.setRefireImmediately(true);
                        	//boolean refireImmediatelyResult = jobExecutionException.refireImmediately();
                        	
                        	log.info("************** Job Id: {} - rescheduled. ", jobExec.getId());
                        	
                        	throw jobExecutionException;
                        } else {
                        	//jobExecutionException = new JobExecutionException("Error: the job [" + jobName + "] didn't end properly. No more retry possible, sending alarm.", excep);
                        	
                        	log.error("\n**********************************************************************\n" 
                					+ "* Quartz trigger - No more retry possible for job: {}\n"
                					+ "* Firing unique ID: {}\n" 
                					+ "* UNSCHEDULING TRIGGER + SENDING EXPLOIT ALARM...\n"
                					+ "**********************************************************************\n",
                					jobName, fireInstanceId);
                        	
                        	AlarmDef alarmDef = AlarmExploit.searchBatchFailedAlarmDefByBatchName(jobName);
                        	AlarmExploit.generateAlarmWithoutTemplate(alarmDef, "Batch failed", "The following batch failed (no more retry possible): " + jobName, Locale.ENGLISH.toString(), null);
                        }
                	}
                
                	@Override
                	public void afterJob(JobExecution jobExecution) {
                		// TODO Auto-generated method stub
                			}
                	
                }
                I also add an sleep for my job and when i run i have a message who said that my job is finished or it's nnot there but juste sleep.
                Please can i have a response, exemple or others suggestions , i need some one to help me please

                Thanks a lot

                Comment

                Working...
                X