Results 1 to 8 of 8

Thread: hello World batch

Hybrid View

  1. #1
    Join Date
    Jun 2008
    Posts
    11

    Default 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. #2

    Default

    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

  3. #3
    Join Date
    Jun 2008
    Posts
    11

    Default

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

  4. #4
    Join Date
    Jun 2008
    Posts
    11

    Default

    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.

  5. #5
    Join Date
    Jun 2005
    Posts
    4,241

    Default

    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).

  6. #6
    Join Date
    Jun 2008
    Posts
    11

    Default 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.

  7. #7

    Default 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);
    	}*/
    
    }

  8. #8

    Default

    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

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •