Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose contextToJobNames from DefaultJobLoader [BATCH-2864] #751

Open
spring-issuemaster opened this issue Dec 16, 2019 · 0 comments
Open

Expose contextToJobNames from DefaultJobLoader [BATCH-2864] #751

spring-issuemaster opened this issue Dec 16, 2019 · 0 comments

Comments

@spring-issuemaster
Copy link
Collaborator

@spring-issuemaster spring-issuemaster commented Dec 16, 2019

Yanming Zhou opened BATCH-2864 and commented

I'm using AutomaticJobRegistrar to register job per xml application context

<bean id="jobLoader" class="org.springframework.batch.core.configuration.support.DefaultJobLoader"/>
<bean id="automaticJobRegistrar" class="org.springframework.batch.core.configuration.support.AutomaticJobRegistrar">
     <property name="applicationContextFactories">
          <bean class="org.springframework.batch.core.configuration.support.ClasspathXmlApplicationContextsFactoryBean">
               <property name="resources" value="resources/batch/*.xml" />
          </bean>
     </property>
     <property name="jobLoader" ref="jobLoader"/>
</bean>

Currently there is no way to get bean from job context since context instances are hold by private field contextToJobNames, such feature is required by execute step via remote invocation to locate step instance, I had to use the dangerous reflection.

@Component
public class JobStepExecutor {

	@Autowired
	private ApplicationContext rootApplicationContext;

	@Autowired
	private JobLoader jobLoader;

	@Autowired
	private JobExplorer jobExplorer;

	public void execute(Long jobExecutionId, Long stepExecutionId, String stepName)
			throws JobInterruptedException, NoSuchJobException {
		String jobName = jobExplorer.getJobExecution(jobExecutionId).getJobInstance().getJobName();
		Map<ConfigurableApplicationContext, Collection<String>> contextToJobNames = ReflectionUtils
				.getFieldValue(jobLoader, "contextToJobNames");
		Step step = contextToJobNames.entrySet().stream().filter(entry -> entry.getValue().contains(jobName))
				.map(entry -> entry.getKey()).findAny().map(ctx -> ctx.getBean(stepName, Step.class))
				.orElseGet(() -> rootApplicationContext.getBean(stepName, Step.class));
		StepExecution stepExecution = jobExplorer.getStepExecution(jobExecutionId, stepExecutionId);
		step.execute(stepExecution);
	}

}

Affects: 4.2.1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
1 participant
You can’t perform that action at this time.