why my security strategy works once on 2 calls - java

I upload file with REST API (with Spring boot and Jhipster), and launch treatment in Async method.
#Async("taskExecutor")
public void importArticle(HttpServletRequest request,
ImportFichierDTO importFichierDTO,
List<Article> articles,
Boolean update,
Long userId) {
log.debug("Request to importCompteur pour article");
In this treatmen, I need to do data control with connected user (with JWT).
I use this link (https://github.com/eugenp/tutorials/blob/master/spring-security-rest/src/main/java/org/baeldung/spring/SecurityJavaConfig.java) for configure Strategy
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
#Import(SecurityProblemSupport.class)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
private final AuthenticationManagerBuilder authenticationManagerBuilder;
private final UserDetailsService userDetailsService;
private final TokenProvider tokenProvider;
private final CorsFilter corsFilter;
private final SecurityProblemSupport problemSupport;
public SecurityConfiguration(AuthenticationManagerBuilder authenticationManagerBuilder, UserDetailsService userDetailsService, TokenProvider tokenProvider, CorsFilter corsFilter, SecurityProblemSupport problemSupport) {
this.authenticationManagerBuilder = authenticationManagerBuilder;
this.userDetailsService = userDetailsService;
this.tokenProvider = tokenProvider;
this.corsFilter = corsFilter;
this.problemSupport = problemSupport;
SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL);
}
when I call the first time my API, all works. The second time, I have an exception with null data of connected User
The third time, all works, and so on...
There is the stacktrace :
java.util.NoSuchElementException: No value present
at java.util.Optional.get(Optional.java:135)
at fr.yoni.yvidya.security.AccessChecker.checkUserAccessToEntityThroughtWebService(AccessChecker.java:59)
at fr.yoni.yvidya.service.impl.EntiteServiceImpl.checkRightsByEntite(EntiteServiceImpl.java:188)
at fr.yoni.yvidya.service.impl.EntiteServiceImpl.checkExistAndAccess(EntiteServiceImpl.java:238)
at fr.yoni.yvidya.service.impl.EntiteServiceImpl$$FastClassBySpringCGLIB$$24d83d44.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:746)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:88)
at fr.yoni.yvidya.aop.logging.LoggingAspect.logAround(LoggingAspect.java:85)
at sun.reflect.GeneratedMethodAccessor430.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:644)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:633)
at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:62)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)
at fr.yoni.yvidya.service.impl.EntiteServiceImpl$$EnhancerBySpringCGLIB$$d8e4bae5.checkExistAndAccess(<generated>)
at fr.yoni.yvidya.service.impl.ArticleServiceImpl.update(ArticleServiceImpl.java:251)
at fr.yoni.yvidya.service.impl.ArticleServiceImpl$$FastClassBySpringCGLIB$$7ebdd41.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:746)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:88)
at fr.yoni.yvidya.aop.logging.LoggingAspect.logAround(LoggingAspect.java:85)
at sun.reflect.GeneratedMethodAccessor430.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:644)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:633)
at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:62)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)
at fr.yoni.yvidya.service.impl.ArticleServiceImpl$$EnhancerBySpringCGLIB$$809100fc.update(<generated>)
at fr.yoni.yvidya.service.thread.ImportFichier.importArticle(ImportFichier.java:539)
at fr.yoni.yvidya.service.thread.ImportFichier$$FastClassBySpringCGLIB$$c2f0d691.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:746)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:88)
at fr.yoni.yvidya.aop.logging.LoggingAspect.logAround(LoggingAspect.java:85)
at sun.reflect.GeneratedMethodAccessor430.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:644)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:633)
at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:62)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:115)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at io.github.jhipster.async.ExceptionHandlingAsyncTaskExecutor.lambda$createWrappedRunnable$1(ExceptionHandlingAsyncTaskExecutor.java:68)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
here is the line that triggers the exception :
String login = SecurityUtils.getCurrentUserLogin().get();
have you an explanation?

There were at least 2 bug reports raised for this, before and after your post:
SecurityUtils.getCurrentUserLogin() with oauth2 does not return the current user
SecurityUtils .getCurrentUserLogin in a microservice returns "null" with OAuth2 and Okta
If you still have this issue you could try a work-around to get the user's Authentication:
SecurityContextHolder.getContext().getAuthentication()
Have a look at Baeldung - Retrieve User Information in Spring Security
This bad bit of code (no type / null checks) gets all the attributes of the Authentication ie everything in the token:
Map<String, Object> attrs = ((OAuth2AuthenticatedPrincipal)SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getAttributes();

Related

Spring data Cassandra not able to perform Paginaton, after passing the CassandraPageRequest

Issue:
nextPageStateString is being passed to the client and during the next request its is converted back to Bytebuffer
below line
feedRepository.findAll(cassandraPageRequest); is throwing exception
I was just converting the serializing and deserializing the PageState, not sure why its complaining as I didn't modified the PagingState object.
Questions:
Am i doing the correctly serializing and deserializing the the byte buffer?
if not what are other ways of doing it.
com.datastax.oss.driver.api.core.servererrors.ProtocolError: Invalid value for the paging state
at com.datastax.oss.driver.api.core.servererrors.ProtocolError.copy(ProtocolError.java:52) ~[java-driver-core-4.13.0.jar:na]
at com.datastax.oss.driver.internal.core.util.concurrent.CompletableFutures.getUninterruptibly(CompletableFutures.java:149) ~[java-driver-core-4.13.0.jar:na]
at com.datastax.oss.driver.internal.core.cql.CqlRequestSyncProcessor.process(CqlRequestSyncProcessor.java:53) ~[java-driver-core-4.13.0.jar:na]
at com.datastax.oss.driver.internal.core.cql.CqlRequestSyncProcessor.process(CqlRequestSyncProcessor.java:30) ~[java-driver-core-4.13.0.jar:na]
at com.datastax.oss.driver.internal.core.session.DefaultSession.execute(DefaultSession.java:230) ~[java-driver-core-4.13.0.jar:na]
at com.datastax.oss.driver.api.core.cql.SyncCqlSession.execute(SyncCqlSession.java:54) ~[java-driver-core-4.13.0.jar:na]
at org.springframework.data.cassandra.core.cql.CqlTemplate.query(CqlTemplate.java:540) ~[spring-data-cassandra-3.3.0.jar:3.3.0]
at org.springframework.data.cassandra.core.CassandraTemplate.doExecute(CassandraTemplate.java:959) ~[spring-data-cassandra-3.3.0.jar:3.3.0]
at org.springframework.data.cassandra.core.CassandraTemplate.doQueryForResultSet(CassandraTemplate.java:951) ~[spring-data-cassandra-3.3.0.jar:3.3.0]
at org.springframework.data.cassandra.core.CassandraTemplate.slice(CassandraTemplate.java:404) ~[spring-data-cassandra-3.3.0.jar:3.3.0]
at org.springframework.data.cassandra.core.CassandraTemplate.slice(CassandraTemplate.java:478) ~[spring-data-cassandra-3.3.0.jar:3.3.0]
at org.springframework.data.cassandra.repository.support.SimpleCassandraRepository.findAll(SimpleCassandraRepository.java:241) ~[spring-data-cassandra-3.3.0.jar:3.3.0]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
at org.springframework.data.repository.core.support.RepositoryMethodInvoker$RepositoryFragmentMethodInvoker.lambda$new$0(RepositoryMethodInvoker.java:289) ~[spring-data-commons-2.6.0.jar:2.6.0]
at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:137) ~[spring-data-commons-2.6.0.jar:2.6.0]
at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:121) ~[spring-data-commons-2.6.0.jar:2.6.0]
at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:529) ~[spring-data-commons-2.6.0.jar:2.6.0]
at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:285) ~[spring-data-commons-2.6.0.jar:2.6.0]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:638) ~[spring-data-commons-2.6.0.jar:2.6.0]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.13.jar:5.3.13]
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:163) ~[spring-data-commons-2.6.0.jar:2.6.0]
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:138) ~[spring-data-commons-2.6.0.jar:2.6.0]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.13.jar:5.3.13]
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:80) ~[spring-data-commons-2.6.0.jar:2.6.0]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.13.jar:5.3.13]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97) ~[spring-aop-5.3.13.jar:5.3.13]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.13.jar:5.3.13]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215) ~[spring-aop-5.3.13.jar:5.3.13]
at jdk.proxy2/jdk.proxy2.$Proxy89.findAll(Unknown Source) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344) ~[spring-aop-5.3.13.jar:5.3.13]
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198) ~[spring-aop-5.3.13.jar:5.3.13]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.3.13.jar:5.3.13]
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137) ~[spring-tx-5.3.13.jar:5.3.13]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.13.jar:5.3.13]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215) ~[spring-aop-5.3.13.jar:5.3.13]
at jdk.proxy2/jdk.proxy2.$Proxy89.findAll(Unknown Source) ~[na:na]
at com.example.FeedService.service.impl.FeedServiceImpl.getUserFeed(FeedServiceImpl.java:60) ~[classes/:na]
at com.example.FeedService.api.FeedApi.getFeed(FeedApi.java:39)
#Service
public class FeedServiceImpl implements FeedService {
private static final char[] HEX_CODE = "0123456789ABCDEF".toCharArray();
#Autowired
private FeedRepository feedRepository;
#Override
public SlicedResult<UserFeed> getUserFeed(String userId, Optional<String> pagingState) {
// reference
// https://github.com/JSextonn/spring-cassandra-pagination-example
final PageRequest pageRequest = PageRequest.of(0, constants.PAGE_SIZE);
CassandraPageRequest cassandraPageRequest =
pagingState.
map(pageState ->{
int len = pageState.length();
ByteBuffer bytes = ByteBuffer.allocate(len / 2);
for (int i = 0; i < len; i += 2) {
bytes.put((byte) ((Character.digit(pageState.charAt(i), 16) << 4)
+ Character.digit(pageState.charAt(i+1), 16)));
}
return CassandraPageRequest.of(pageRequest,bytes);
}
)
.orElse(CassandraPageRequest.first(constants.PAGE_SIZE));
Slice<UserFeed> userFeedSlice = feedRepository.findAll(cassandraPageRequest);
CassandraPageRequest nextPageable = ((CassandraPageRequest)userFeedSlice.getPageable());
ByteBuffer nextPagingState = nextPageable.getPagingState();
String nextPageStateString = toHexString(nextPagingState);
userFeedSlice = feedRepository.findAll(userFeedSlice.nextPageable());
return SlicedResult.<UserFeed>builder().pageState(nextPageStateString).content(userFeedSlice.getContent())
.build();
}
public static String toHexString(ByteBuffer buffer) {
final StringBuilder r = new StringBuilder(buffer.remaining() * 2);
while (buffer.hasRemaining()) {
final byte b = buffer.get();
r.append(HEX_CODE[(b >> 4) & 0xF]);
r.append(HEX_CODE[(b & 0xF)]);
}
return r.toString();
}
}
Calling bytes.position(0); before CassandraPageRequest.of(pageRequest, bytes); has resolved the issue.

Access execution context from StaxWriterCallback

I'm implementing a job that will load data from a database and write the result to xml files. The xml files will have a header that is based on some attributes that are stored in the execution context. Therefore, I want to acces the execution context. I've done this in other beans in this job, but I can't figure out how to access the execution context from within my StaxWriterCallback.
In the job my writer is currently implemented as:
#Bean(name = "writer")
#StepScope
public StaxEventItemWriter<Data> writer(#Value("#{jobParameters['path']}") String path) {
StaxEventItemWriter<Data> itemWriter = new StaxEventItemWriter<Data>();
itemWriter.setVersion("1.0");
itemWriter.setEncoding("UTF-8");
itemWriter.setStandalone(false);
itemWriter.setHeaderCallback(headerCallback());
itemWriter.setFooterCallback(new CustomXMLFooterCallback());
itemWriter.setMarshaller(new XStreamMarshaller());
FileSystemResource file = new FileSystemResource(path + "test.xml");
itemWriter.setResource(file);
return itemWriter;
}
The header callback is implemented as:
#Component
public class CustomXMLHeaderCallback implements StaxWriterCallback {
private StepExecution stepExecution;
#BeforeStep
public void beforeStep(StepExecution stepExecution) {
this.stepExecution = stepExecution;
}
#Override
public void write(XMLEventWriter writer) throws IOException {
String currentFile = stepExecution.getExecutionContext().getString("currentFile");
try {
XMLEventFactory eventFactory = XMLEventFactory.newInstance();
XMLEvent end = eventFactory.createDTD("\n");
XMLEvent tab = eventFactory.createDTD("\t");
writer.add(eventFactory.createStartElement("", "", "file"));
writer.add(eventFactory.createCharacters(currentFile.substring(19, 31)));
writer.add(eventFactory.createEndElement("", "", "file"));
writer.add(end);
} catch (Exception e) {
e.printStackTrace();
}
}
}
The header callback is added to the batch job with:
#Bean
#StepScope
public CustomXMLHeaderCallback headerCallback() {
return new CustomXMLHeaderCallback();
}
Unfortunately I get the following error:
java.lang.NullPointerException: Cannot invoke "org.springframework.batch.core.StepExecution.getExecutionContext()" because "this.stepExecution" is null
at com.test.xml.callback.CustomXMLHeaderCallback.write(CustomXMLHeaderCallback.java:39) ~[classes/:na]
at com.test.xml.callback.CustomXMLHeaderCallback$$FastClassBySpringCGLIB$$e0795ecb.invoke(<generated>) ~[classes/:na]
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.3.3.jar:5.3.3]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:779) ~[spring-aop-5.3.3.jar:5.3.3]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.3.3.jar:5.3.3]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750) ~[spring-aop-5.3.3.jar:5.3.3]
at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:137) ~[spring-aop-5.3.3.jar:5.3.3]
at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:124) ~[spring-aop-5.3.3.jar:5.3.3]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.3.jar:5.3.3]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750) ~[spring-aop-5.3.3.jar:5.3.3]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:692) ~[spring-aop-5.3.3.jar:5.3.3]
at com.test.xml.callback.CustomXMLHeaderCallback$$EnhancerBySpringCGLIB$$e9083311.write(<generated>) ~[classes/:na]
at org.springframework.batch.item.xml.StaxEventItemWriter.open(StaxEventItemWriter.java:447) ~[spring-batch-infrastructure-4.3.1.jar:4.3.1]
at org.springframework.batch.item.xml.StaxEventItemWriter$$FastClassBySpringCGLIB$$d105dd1.invoke(<generated>) ~[spring-batch-infrastructure-4.3.1.jar:4.3.1]
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.3.3.jar:5.3.3]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:779) ~[spring-aop-5.3.3.jar:5.3.3]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.3.3.jar:5.3.3]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750) ~[spring-aop-5.3.3.jar:5.3.3]
at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:137) ~[spring-aop-5.3.3.jar:5.3.3]
at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:124) ~[spring-aop-5.3.3.jar:5.3.3]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.3.jar:5.3.3]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750) ~[spring-aop-5.3.3.jar:5.3.3]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:692) ~[spring-aop-5.3.3.jar:5.3.3]
at org.springframework.batch.item.xml.StaxEventItemWriter$$EnhancerBySpringCGLIB$$599f2f97.open(<generated>) ~[spring-batch-infrastructure-4.3.1.jar:4.3.1]
at org.springframework.batch.item.support.CompositeItemStream.open(CompositeItemStream.java:104) ~[spring-batch-infrastructure-4.3.1.jar:4.3.1]
at org.springframework.batch.core.step.tasklet.TaskletStep.open(TaskletStep.java:311) ~[spring-batch-core-4.3.1.jar:4.3.1]
at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:205) ~[spring-batch-core-4.3.1.jar:4.3.1]
at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:148) ~[spring-batch-core-4.3.1.jar:4.3.1]
at org.springframework.batch.core.job.AbstractJob.handleStep(AbstractJob.java:411) ~[spring-batch-core-4.3.1.jar:4.3.1]
at org.springframework.batch.core.job.SimpleJob.doExecute(SimpleJob.java:136) ~[spring-batch-core-4.3.1.jar:4.3.1]
at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:320) ~[spring-batch-core-4.3.1.jar:4.3.1]
at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:147) ~[spring-batch-core-4.3.1.jar:4.3.1]
at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50) ~[spring-core-5.3.3.jar:5.3.3]
at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:140) ~[spring-batch-core-4.3.1.jar:4.3.1]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:564) ~[na:na]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344) ~[spring-aop-5.3.3.jar:5.3.3]
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198) ~[spring-aop-5.3.3.jar:5.3.3]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.3.3.jar:5.3.3]
at org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration$PassthruAdvice.invoke(SimpleBatchConfiguration.java:128) ~[spring-batch-core-4.3.1.jar:4.3.1]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.3.jar:5.3.3]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215) ~[spring-aop-5.3.3.jar:5.3.3]
at com.sun.proxy.$Proxy62.run(Unknown Source) ~[na:na]
at org.springframework.boot.autoconfigure.batch.JobLauncherApplicationRunner.execute(JobLauncherApplicationRunner.java:199) ~[spring-boot-autoconfigure-2.4.2.jar:2.4.2]
at org.springframework.boot.autoconfigure.batch.JobLauncherApplicationRunner.executeLocalJobs(JobLauncherApplicationRunner.java:173) ~[spring-boot-autoconfigure-2.4.2.jar:2.4.2]
at org.springframework.boot.autoconfigure.batch.JobLauncherApplicationRunner.launchJobFromProperties(JobLauncherApplicationRunner.java:160) ~[spring-boot-autoconfigure-2.4.2.jar:2.4.2]
at org.springframework.boot.autoconfigure.batch.JobLauncherApplicationRunner.run(JobLauncherApplicationRunner.java:155) ~[spring-boot-autoconfigure-2.4.2.jar:2.4.2]
at org.springframework.boot.autoconfigure.batch.JobLauncherApplicationRunner.run(JobLauncherApplicationRunner.java:150) ~[spring-boot-autoconfigure-2.4.2.jar:2.4.2]
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:795) ~[spring-boot-2.4.2.jar:2.4.2]
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:785) ~[spring-boot-2.4.2.jar:2.4.2]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:333) ~[spring-boot-2.4.2.jar:2.4.2]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1311) ~[spring-boot-2.4.2.jar:2.4.2]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1300) ~[spring-boot-2.4.2.jar:2.4.2]
at com.test.main(MainOutboundDatins.java:18) ~[classes/:na]
If you want the beforeStep method to be called before the step in your CustomXMLHeaderCallback, you need to register that component as a listener in your step with one of the step builder's listener methods. This is explained in the docs here: Intercepting Step Execution.
Otherwise, you can inject the step execution with #Value:
#Value("#{StepExecution}")
private StepExecution stepExecution;
A third option is to inject the required attribute from the step execution context:
// define your header as follows:
public class CustomXMLHeaderCallback implements StaxWriterCallback {
private String currentFile;
public CustomXMLHeaderCallback(String currentFile) {
this.currentFile = currentFile;
}
#Override
public void write(XMLEventWriter writer) throws IOException {
// use this.currentFile as needed here
}
}
// decalre your bean as follows:
#Bean
#StepScope
public CustomXMLHeaderCallback headerCallback(#Value("#{stepExecutionContext['currentFile']}") String currentFile) {
return new CustomXMLHeaderCallback(currentFile);
}
I recommend the third option as it injects only the required attribute and not the whole step execution object.

Spring batch and SystemCommandTasklet: cannot pass parameter

I am trying to trigger a spring batch job from a rest controller, and I need to pass parameters to the Step. I used a SystemCommandTasklet and, as suggested here I added the Tasklet as a StepListener, but I keep getting a NPE.
I have created a sample project here: if you run the test you will see this on the output:
java.lang.NullPointerException: null
at org.springframework.batch.core.step.tasklet.SystemCommandTasklet.execute(SystemCommandTasklet.java:133) ~[spring-batch-core-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344) ~[spring-aop-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198) ~[spring-aop-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:136) ~[spring-aop-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:124) ~[spring-aop-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212) ~[spring-aop-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at com.sun.proxy.$Proxy87.execute(Unknown Source) ~[na:na]
at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:407) ~[spring-batch-core-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:331) ~[spring-batch-core-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:140) ~[spring-tx-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.batch.core.step.tasklet.TaskletStep$2.doInChunkContext(TaskletStep.java:273) ~[spring-batch-core-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.batch.core.scope.context.StepContextRepeatCallback.doInIteration(StepContextRepeatCallback.java:82) ~[spring-batch-core-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:375) ~[spring-batch-infrastructure-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:215) ~[spring-batch-infrastructure-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:145) ~[spring-batch-infrastructure-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.batch.core.step.tasklet.TaskletStep.doExecute(TaskletStep.java:258) ~[spring-batch-core-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:208) ~[spring-batch-core-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:148) ~[spring-batch-core-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.batch.core.job.AbstractJob.handleStep(AbstractJob.java:410) ~[spring-batch-core-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.batch.core.job.SimpleJob.doExecute(SimpleJob.java:136) ~[spring-batch-core-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:319) ~[spring-batch-core-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:147) ~[spring-batch-core-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na]
The method beforeStep in the Tasklet is never invoked, and that leads to the NPE.
This is my batch configuration:
#Configuration
#EnableBatchProcessing
public class BatchConfiguration extends DefaultBatchConfigurer {
private final JobBuilderFactory jobBuilderFactory;
private final StepBuilderFactory stepBuilderFactory;
public BatchConfiguration(JobBuilderFactory jobBuilderFactory, StepBuilderFactory stepBuilderFactory) {
this.jobBuilderFactory = jobBuilderFactory;
this.stepBuilderFactory = stepBuilderFactory;
}
#Override
public JobLauncher getJobLauncher() {
SimpleJobLauncher jobLauncher = new SimpleJobLauncher();
jobLauncher.setJobRepository(getJobRepository());
jobLauncher.setTaskExecutor(new SimpleAsyncTaskExecutor());
return jobLauncher;
}
#Bean
public Job myJob(Step myStep) {
return jobBuilderFactory.get("myJob")
.incrementer(new RunIdIncrementer())
.start(myStep)
.build();
}
#Bean
public Step myStep(Tasklet myServiceTasklet) {
return this.stepBuilderFactory.get("myStep")
.listener(myServiceTasklet)
.tasklet(myServiceTasklet)
.build();
}
#Bean
#StepScope
public Tasklet myServiceTasklet(
#Value("#{jobParameters['my_param']}") String param
) {
SystemCommandTasklet tasklet = new SystemCommandTasklet();
System.out.println(param);
tasklet.setCommand("sleep 10");
tasklet.setTimeout(20000);
return tasklet;
}
}
I tried dozens of different ways to do this, but I still can't figure out why the beforeStep method in the Tasklet is not invoked and the field execution remains null
The return type of your tasklet bean definition method should be SystemCommandTasklet:
#Bean
#StepScope
public SystemCommandTasklet myServiceTasklet(
#Value("#{jobParameters['my_param']}") String param
) {
SystemCommandTasklet tasklet = new SystemCommandTasklet();
System.out.println(param);
tasklet.setCommand("sleep 10");
tasklet.setTimeout(20000);
return tasklet;
}
Currently, it returns Tasklet and hence it is not proxied by Spring Batch as a StepExecutionListener (that's why it is not registered as a listener and the beforeStep method is not invoked).
You need to be as specific as possible for the return type of bean definition methods so that Spring Batch can correctly proxy your beans and register them with the correct type. More details here: https://stackoverflow.com/a/21941127/5019386.
NB: I downloaded your code and noticed that you do not disable jobs at startup for production code as you do in test code. You need to add the same application.properties in src/main/resources as well.

Spring RestTemplate gives $InternalServerError: 500 null. Same works in POSTMAN and for SMALL FILES

I have a Spring batch application which does the below operations,
Read a file from AmazonS3 bucket.
Write it to local
Zip the file and send to Rest API as byte array (API accepts byte[])
when the job runs for small Files (below 2 MB), it is working fine and I am getting the response from API
But when it is trying to hit large files, API throws below exception
org.springframework.web.client.HttpServerErrorException$InternalServerError: 500 null
Same large file if I hit through POSTMAN, I am getting proper response.
My Rest call is as below
ClientHttpRequestFactory requestFactory = new
HttpComponentsClientHttpRequestFactory(HttpClients.createDefault());
RestTemplate restTemplate = new RestTemplate(requestFactory);
URI uri = new URI(submitUrl);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
body.add("inputDoc", byteArray);
body.add("metaData", createOcrSubmitMap(fileName));
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);
ResponseEntity<String> response = restTemplate.postForEntity(uri, requestEntity, String.class);
Note: I am able to write this byte[] to a file and can open and see the file correctly.
The same set of code works fine with small files!!
What would went wrong with large files??
Complete stack trace
org.springframework.web.client.HttpServerErrorException$InternalServerError: 500
at org.springframework.web.client.HttpServerErrorException.create(HttpServerErrorException.java:79)
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:124)
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:102)
at org.springframework.web.client.ResponseErrorHandler.handleError(ResponseErrorHandler.java:63)
at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:778)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:736)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:710)
at org.springframework.web.client.RestTemplate.postForEntity(RestTemplate.java:463)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:749)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:295)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)
at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:407)
at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:331)
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:140)
at org.springframework.batch.core.step.tasklet.TaskletStep$2.doInChunkContext(TaskletStep.java:273)
at org.springframework.batch.core.scope.context.StepContextRepeatCallback.doInIteration(StepContextRepeatCallback.java:82)
at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:375)
at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:215)
at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:145)
at org.springframework.batch.core.step.tasklet.TaskletStep.doExecute(TaskletStep.java:258)
at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:203)
at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:148)
at org.springframework.batch.core.job.AbstractJob.handleStep(AbstractJob.java:399)
at org.springframework.batch.core.job.SimpleJob.doExecute(SimpleJob.java:135)
at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:313)
at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:144)
at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50)
at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:137)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:343)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration$PassthruAdvice.invoke(SimpleBatchConfiguration.java:127)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
at com.sun.proxy.$Proxy94.run(Unknown Source)
at com.test.batch.config.JobLauncherConfig.jjob1(JobLauncherConfig.java:56)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:84)
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:93)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Exception is thrown at:
ResponseEntity<String> response = restTemplate.postForEntity(uri, requestEntity, String.class);
Issue resolved. Instead of passing the byte[] as it is, we should pass it as ByteArrayResource.
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
ByteArrayResource contentsAsResource = new ByteArrayResource(byteArray){
#Override
public String getFilename() {
return fileName;
}
};
body.add("inputDoc", contentsAsResource);
body.add("metaData", createOcrSubmitMap(fileName));

Is there anything special about configuring the use of multiple buckets in a spring-data-couchbase Java application?

I'm working on a Java-based spring-data-couchbase application that connects to multiple buckets to do its work. We are seeing TimeoutExceptions being thrown when trying to retrieve documents from the buckets with a stack trace like this:
10-17-2016 14:28:10 (WebContainer : 9) ERROR [com.cars.ss.cp.resources.ProfileResource] - [RESOURCE] [ERROR] Service com.sun.proxy.$Proxy195.getConsumerProfileSummaryVersion throws org.springframework.dao.QueryTimeoutException.
org.springframework.dao.QueryTimeoutException: java.util.concurrent.TimeoutException; nested exception is java.lang.RuntimeException: java.util.concurrent.TimeoutException
at org.springframework.data.couchbase.core.CouchbaseExceptionTranslator.translateExceptionIfPossible(CouchbaseExceptionTranslator.java:122)
at org.springframework.data.couchbase.core.CouchbaseTemplate.execute(CouchbaseTemplate.java:500)
at org.springframework.data.couchbase.core.CouchbaseTemplate.exists(CouchbaseTemplate.java:464)
at org.springframework.data.couchbase.repository.support.SimpleCouchbaseRepository.exists(SimpleCouchbaseRepository.java:110)
at sun.reflect.GeneratedMethodAccessor241.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:55)
at java.lang.reflect.Method.invoke(Method.java:613)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:503)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:488)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:460)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.couchbase.repository.support.ViewPostProcessor$ViewInterceptor.invoke(ViewPostProcessor.java:87)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208)
at com.sun.proxy.$Proxy148.exists(Unknown Source)
at sun.reflect.GeneratedMethodAccessor240.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:55)
at java.lang.reflect.Method.invoke(Method.java:613)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:302)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208)
at com.sun.proxy.$Proxy174.exists(Unknown Source)
at com.cars.ss.cp.service.impl.ProfilePhotoService.findByConsumerId(ProfilePhotoService.java:43)
at com.cars.ss.cp.dao.impl.ConsumerAccountDAO.findConsumerAccountByPartyId(ConsumerAccountDAO.java:77)
at sun.reflect.GeneratedMethodAccessor287.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:55)
at java.lang.reflect.Method.invoke(Method.java:613)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:302)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208)
at com.sun.proxy.$Proxy186.findConsumerAccountByPartyId(Unknown Source)
at com.cars.ss.cp.service.impl.ProfileService.getBOConsumerProfileVersion(ProfileService.java:235)
at com.cars.ss.cp.service.impl.ProfileService.getProfileSummaryByPersonPartyId(ProfileService.java:489)
at com.cars.ss.cp.service.impl.ProfileService.getProfileSummaryByConsumerId(ProfileService.java:479)
at sun.reflect.GeneratedMethodAccessor286.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:55)
at java.lang.reflect.Method.invoke(Method.java:613)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:302)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
at com.sun.proxy.$Proxy195.getProfileSummaryByConsumerId(Unknown Source)
at com.cars.ss.cp.resources.ProfileResource.getSummaryReadByConsumerId(ProfileResource.java:362)
at com.cars.ss.cp.resources.ProfileResource.getConsumerProfileSummaryVersion(ProfileResource.java:320)
at com.cars.ss.cp.resources.ProfileResource.getConsumerProfile(ProfileResource.java:252)
at sun.reflect.GeneratedMethodAccessor261.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:55)
at java.lang.reflect.Method.invoke(Method.java:613)
at org.apache.wink.server.internal.handlers.InvokeMethodHandler.handleRequest(InvokeMethodHandler.java:63)
...
at javax.servlet.http.HttpServlet.service(HttpServlet.java:668)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1225)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:775)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:457)
at com.ibm.ws.webcontainer.servlet.ServletWrapperImpl.handleRequest(ServletWrapperImpl.java:178)
at com.ibm.ws.webcontainer.filter.WebAppFilterManager.invokeFilters(WebAppFilterManager.java:1032)
at com.ibm.ws.webcontainer.servlet.CacheServletWrapper.handleRequest(CacheServletWrapper.java:87)
at com.ibm.ws.webcontainer.WebContainer.handleRequest(WebContainer.java:908)
at com.ibm.ws.webcontainer.WSWebContainer.handleRequest(WSWebContainer.java:1662)
at com.ibm.ws.webcontainer.channel.WCChannelLink.ready(WCChannelLink.java:195)
at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleDiscrimination(HttpInboundLink.java:459)
at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleNewRequest(HttpInboundLink.java:526)
at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.processRequest(HttpInboundLink.java:312)
at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.ready(HttpInboundLink.java:283)
at com.ibm.ws.tcp.channel.impl.NewConnectionInitialReadCallback.sendToDiscriminators(NewConnectionInitialReadCallback.java:214)
at com.ibm.ws.tcp.channel.impl.NewConnectionInitialReadCallback.complete(NewConnectionInitialReadCallback.java:113)
at com.ibm.ws.tcp.channel.impl.AioReadCompletionListener.futureCompleted(AioReadCompletionListener.java:165)
at com.ibm.io.async.AbstractAsyncFuture.invokeCallback(AbstractAsyncFuture.java:217)
at com.ibm.io.async.AsyncChannelFuture$1.run(AsyncChannelFuture.java:205)
at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1815)
Caused by: java.lang.RuntimeException: java.util.concurrent.TimeoutException
at com.couchbase.client.java.util.Blocking.blockForSingle(Blocking.java:75)
at com.couchbase.client.java.CouchbaseBucket.exists(CouchbaseBucket.java:159)
at com.couchbase.client.java.CouchbaseBucket.exists(CouchbaseBucket.java:154)
at org.springframework.data.couchbase.core.CouchbaseTemplate$5.doInBucket(CouchbaseTemplate.java:467)
at org.springframework.data.couchbase.core.CouchbaseTemplate$5.doInBucket(CouchbaseTemplate.java:464)
at org.springframework.data.couchbase.core.CouchbaseTemplate.execute(CouchbaseTemplate.java:497)
... 120 more
Caused by: java.util.concurrent.TimeoutException
... 126 more
I configured my Couchbase configuration class with multiple buckets like this:
#EnableCouchbaseRepositories(basePackages = { "com.cars.ss.cp.nosql.repository" })
#Configuration
public class CouchbaseConfiguration extends AbstractCouchbaseConfiguration {
private static Logger logger = Logger.getLogger(CouchbaseConfiguration.class);
private static final long TIMEOUT_IN_SECONDS = 10;
#Autowired
#Qualifier("propertyService")
private PropertyService propertyService;
#Bean(name = { "defaultBucket" })
public Bucket defaultBucket() throws Exception {
return couchbaseCluster().openBucket(getBucketName());
}
#Override
protected List<String> getBootstrapHosts() {
String rawPropertyValue = this.propertyService.getPropertyValue(COUCHBASE_HOSTS);
if (StringUtils.isNotBlank(rawPropertyValue)) {
StringTokenizer st = new StringTokenizer(rawPropertyValue, ",");
List<String> returnValue = new ArrayList<>(st.countTokens());
while (st.hasMoreTokens()) {
returnValue.add(st.nextToken().trim());
}
return returnValue;
}
logger.error("Unable to process the couchbaseHosts property. Property value: " + rawPropertyValue);
return Collections.emptyList();
}
#Override
protected String getBucketName() {
return this.propertyService.getPropertyValue(COUCHBASE_BUCKET);
}
#Override
protected String getBucketPassword() {
return null;
}
#Override
protected CouchbaseEnvironment getEnvironment() {
return DefaultCouchbaseEnvironment.builder().connectTimeout(TimeUnit.SECONDS.toMillis(TIMEOUT_IN_SECONDS)).kvTimeout(TimeUnit.SECONDS.toMillis(TIMEOUT_IN_SECONDS)).build();
}
#Bean
public Bucket consumerProfileBucket() throws Exception {
return couchbaseCluster().openBucket(this.propertyService.getPropertyValue(CONSUMER_PROFILE_BUCKET), this.propertyService.getPropertyValue(CONSUMER_PROFILE_BUCKET_PASSWORD));
}
#Bean
public CouchbaseTemplate consumerProfileTemplate() throws Exception {
CouchbaseTemplate template = new CouchbaseTemplate(couchbaseClusterInfo(), consumerProfileBucket(), mappingCouchbaseConverter(), translationService());
template.setDefaultConsistency(getDefaultConsistency());
return template;
}
#Override
protected void configureRepositoryOperationsMapping(RepositoryOperationsMapping baseMapping) {
try {
baseMapping.mapEntity(OwnedVehicle.class, consumerProfileTemplate());
baseMapping.mapEntity(ProfilePhoto.class, consumerProfileTemplate());
} catch (Exception e) {
logger.error("Errors encountered during configuration. Exception: " + e);
}
}
}
I originally didn't have the "getEnvironment" method overridden. Based on some recommendations that I saw online, I overrode that method and increased both the connection timeout and key-value timeout to 10 seconds to see if that might help, but it did not. When I increased the timeout from the defaults to 10 seconds, the timeout of the document retrieval became exactly 10 seconds. The TimeoutException is occurring against a document that is trying to be retrieved using the document's key.
The application has the following specifications:
* Java version: 1.7
* spring-data-couchbase version: 2.1.1.RELEASE
* java-client version: 2.2.5
* IBM WebSphere version: 8.5
Is there something obvious that I am missing in the way I have things configured? Are there any other ideas out there of things that I can look at to repair this problem?
10/24/2016 - Added a thread analysis image from the javacore:
thread analysis image from javacore

Categories