I recently deployed a Spring Boot app to Elastic Beanstalk.
Spring starts with no errors.
We are using Firebase for user authentication. On a local machiene or even on other external hosts the Firebase operations worked all fine, but not on EBS.
If i read the logs:
java.lang.IllegalStateException: FirebaseApp with name [DEFAULT] doesn't exist.
at com.google.firebase.FirebaseApp.getInstance(FirebaseApp.java:164) ~[firebase-admin-6.3.0.jar!/:na]
at com.google.firebase.FirebaseApp.getInstance(FirebaseApp.java:135) ~[firebase-admin-6.3.0.jar!/:na]
at com.google.firebase.auth.FirebaseAuth.getInstance(FirebaseAuth.java:100) ~[firebase-admin-6.3.0.jar!/:na]
at com.bodymate.springend.mvc.service.FirebaseService.validateToken(FirebaseService.java:15) ~[classes!/:1.0-SNAPSHOT]
at com.bodymate.springend.mvc.controller.UserController.register(UserController.java:66) ~[classes!/:1.0-SNAPSHOT]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_181]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_181]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_181]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_181]...
This is my firebase config:
#Configuration
public class FirebaseConfig {
#PostConstruct
public void init() {
FirebaseOptions options;
try {
FileInputStream serviceAccount = new FileInputStream("src/main/resources/google-services.json");
options = new FirebaseOptions.Builder()
.setCredentials(GoogleCredentials.fromStream(serviceAccount))
.build();
} catch (java.io.IOException e) {
e.printStackTrace();
return;
}
FirebaseApp.initializeApp(options);
}
}
The point where it gets out of hand:
#Service
public class FirebaseService {
public FirebaseToken validateToken(String token) throws InterruptedException, ExecutionException, InvalidFirebaseTokenException {
FirebaseToken decodedToken = FirebaseAuth.getInstance().verifyIdTokenAsync(token).get();
if( decodedToken != null && decodedToken.getUid() != null && !decodedToken.getUid().isEmpty()){
return decodedToken;
}else{
throw new InvalidFirebaseTokenException();
}
}
}
Does someone has any idea what is going wrong here ?
EDIT
I am using mvn clean install to build my .jar file for EBS.
Is it possible that this build does not contain the "google-services.json" ?
Related
I am trying to implement spring-retry(version - 1.3.1) in my spring boot application. I have to retry webservice operation to read the record if not found in first request.
sample code:
#Retryable(include = {IllegalArgumentException.class}, backoff = #Backoff(500), maxAttempts = 3, recover ="readFallback")
Object read(String Id);
#Recover
Object readFallback(RuntimeException e, String Id);
void deletePayment(String paymentId);
Problem :
I am getting correct response from read method(annotated with #Retryable) in exception scenario but I am getting RetryExhaustedException with nested original exception when I am getting exception on my delete method. As you see, delete method doesn't annotated with #Retryable . Delete method is in different package.
**Sample exception response ** : "Retry exhausted after last attempt with no recovery path; nested exception is exception.NotFoundException: Not found"
Expected : Delete method should not be impacted by #Retryable. Can someone help me to find what am i missing or doing wrong. I have tried but unable to not found the solution of this problem on internet.
Thanks in advance !
Works as expected for me:
#SpringBootApplication
#EnableRetry
public class So71546747Application {
public static void main(String[] args) {
SpringApplication.run(So71546747Application.class, args);
}
#Bean
ApplicationRunner runner(SomeRetryables retrier) {
return args -> {
retrier.foo("testFoo");
try {
Thread.sleep(1000);
retrier.bar("testBar");
}
catch (Exception e) {
e.printStackTrace();
}
};
}
}
#Component
class SomeRetryables {
#Retryable
void foo(String in) {
System.out.println(in);
throw new RuntimeException(in);
}
#Recover
void recover(String in, Exception ex) {
System.out.println("recovered");
}
void bar(String in) {
System.out.println(in);
throw new RuntimeException(in);
}
}
testFoo
testFoo
testFoo
recovered
testBar
java.lang.RuntimeException: testBar
at com.example.demo.SomeRetryables.bar(So71546747Application.java:52)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:789)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753)
at org.springframework.retry.annotation.AnnotationAwareRetryOperationsInterceptor.invoke(AnnotationAwareRetryOperationsInterceptor.java:166)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:698)
at com.example.demo.SomeRetryables$$EnhancerBySpringCGLIB$$e61dd199.bar(<generated>)
at com.example.demo.So71546747Application.lambda$0(So71546747Application.java:26)
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:768)
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:758)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:310)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1312)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1301)
at com.example.demo.So71546747Application.main(So71546747Application.java:17)
Please provide an MCRE that exhibits the behavior you see so we can see what's wrong.
I'm reading multiple files from the S3 bucket using MultiResourceItemReader, I'm getting ClassCastException before executing the myReader() method, Something wrong with MultiResourceItemReader not sure what's going wrong here.
Please find my code below:
#Bean
public MultiResourceItemReader<String> multiResourceReader()
{
String bucket = "mybucket;
String key = "/myfiles";
List<InputStream> resourceList = s3Client.getFiles(bucket, key);
List<InputStreamResource> inputStreamResourceList = new ArrayList<>();
for (InputStream s: resourceList) {
inputStreamResourceList.add(new InputStreamResource(s));
}
Resource[] resources = inputStreamResourceList.toArray(new InputStreamResource[inputStreamResourceList.size()]);
//InputStreamResource[] resources = inputStreamResourceList.toArray(new InputStreamResource[inputStreamResourceList.size()]);
// I'm getting all the stream content - I verified my stream is not null
for (int i = 0; i < resources.length; i++) {
try {
InputStream s = resources[i].getInputStream();
String result = IOUtils.toString(s, StandardCharsets.UTF_8);
System.out.println(result);
} catch (IOException e) {
e.printStackTrace();
}
}
MultiResourceItemReader<String> resourceItemReader = new MultiResourceItemReader<>();
resourceItemReader.setResources(resources);
resourceItemReader.setDelegate(myReader());
resourceItemReader.setDelegate((ResourceAwareItemReaderItemStream<? extends String>) new CustomComparator());
return resourceItemReader;
}
Exception:
Caused by: java.lang.ClassCastException: class CustomComparator cannot be cast to class org.springframework.batch.item.file.ResourceAwareItemReaderItemStream (CustomComparator and org.springframework.batch.item.file.ResourceAwareItemReaderItemStream are in unnamed module of loader org.springframework.boot.loader.LaunchedURLClassLoader #cc285f4)
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244)
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:331)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
... 65 common frames omitted
Can someone please help me to resolve this issue. Appreciated your help in advance. Thanks.
The reason you see the NullPointerException is due to the default comparator used by the MultiResourceItemReader to sort the resources after loading them.
The default compare behavior calls the getFilename() method of the InputStreamResource.
Refer - https://github.com/spring-projects/spring-batch/blob/115c3022147692155d45e23cdd5cef84895bf9f5/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/MultiResourceItemReader.java#L82
But the InputStreamResource just inherits the getFileName() method from its parent AbstractResource, which just returns null.
https://github.com/spring-projects/spring-framework/blob/316e84f04f3dbec3ea5ab8563cc920fb21f49749/spring-core/src/main/java/org/springframework/core/io/AbstractResource.java#L220
The solution is to provide a custom comparator for the MultiResourceItemReader. Here is a simple example, assuming you do not want to sort the resources in a specific way before processing:
public class CustomComparator implements Comparator<InputStream>{
#Override
public int compare(InputStream is1, InputStream is2) {
//comparing based on last modified time
return Long.compare(is1.hashCode(),is2.hashCode());
}
}
MultiResourceItemReader<String> resourceItemReader = new MultiResourceItemReader<>();
resourceItemReader.setResources(resources);
resourceItemReader.setDelegate(myReader());
//UPDATED with correction - set custom Comparator
resourceItemReader.setComparator(new CustomComparator());
Refer this answer for how a Comparator is used by Spring Batch MultiResourceItemReader.
File processing order with Spring Batch
I'm developing a spring boot application which reads data from an ftp connection. Have been referring this article. http://docs.spring.io/spring-integration/reference/html/ftp.html I've added below dependency to pom.xml:
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-ftp</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
Here is my Spring boot application:
#SpringBootApplication
public class FtpApplication {
public static void main(String[] args) {
SpringApplication.run(FtpApplication.class, args);
}
#Bean
public SessionFactory<FTPFile> ftpSessionFactory() {
DefaultFtpSessionFactory sf = new DefaultFtpSessionFactory();
sf.setHost("localhost");
sf.setPort(14147);
sf.setUsername("root");
sf.setPassword("root");
return new CachingSessionFactory<FTPFile>(sf);
}
#Bean
public FtpInboundFileSynchronizer ftpInboundFileSynchronizer() {
FtpInboundFileSynchronizer fileSynchronizer = new FtpInboundFileSynchronizer(ftpSessionFactory());
fileSynchronizer.setDeleteRemoteFiles(false);
fileSynchronizer.setRemoteDirectory("/");
fileSynchronizer.setFilter(new FtpSimplePatternFileListFilter("*.xml"));
return fileSynchronizer;
}
#Bean
#InboundChannelAdapter(channel = "ftpChannel")
public MessageSource<File> ftpMessageSource() {
FtpInboundFileSynchronizingMessageSource source = new FtpInboundFileSynchronizingMessageSource(
ftpInboundFileSynchronizer());
source.setLocalDirectory(new File("ftp-inbound"));
source.setAutoCreateLocalDirectory(true);
source.setLocalFilter(new AcceptOnceFileListFilter<File>());
return source;
}
#Bean
#ServiceActivator(inputChannel = "ftpChannel")
public MessageHandler handler() {
return new MessageHandler() {
#Override
public void handleMessage(Message<?> message) throws MessagingException {
File file = (File) message.getPayload();
BufferedReader br;
String sCurrentLine;
try {
br = new BufferedReader(new FileReader(file.getPath()));
while ((sCurrentLine = br.readLine()) != null) {
System.out.println(sCurrentLine);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(message.getPayload());
}
};
}
#Bean(name = PollerMetadata.DEFAULT_POLLER)
public PollerMetadata defaultPoller() {
PollerMetadata pollerMetadata = new PollerMetadata();
pollerMetadata.setTrigger(new PeriodicTrigger(10));
return pollerMetadata;
}
}
From the windows explorer I'm adding a file. Now when the control comes to the MessageHandler function, I see the below error. But I can neatly get the file and I see the contents correctly when I read it. But I'm unable to figure out what is the error all about:
2016-09-27 08:25:07.548 ERROR 10292 --- [ask-scheduler-1] o.s.integration.handler.LoggingHandler : org.springframework.messaging.MessagingException: Problem occurred while synchronizing remote to local directory; nested exception is org.springframework.messaging.MessagingException: Failed to obtain pooled item; nested exception is java.lang.IllegalStateException: failed to create FTPClient
at org.springframework.integration.file.remote.synchronizer.AbstractInboundFileSynchronizer.synchronizeToLocalDirectory(AbstractInboundFileSynchronizer.java:274)
at org.springframework.integration.file.remote.synchronizer.AbstractInboundFileSynchronizingMessageSource.doReceive(AbstractInboundFileSynchronizingMessageSource.java:193)
at org.springframework.integration.file.remote.synchronizer.AbstractInboundFileSynchronizingMessageSource.doReceive(AbstractInboundFileSynchronizingMessageSource.java:59)
at org.springframework.integration.endpoint.AbstractMessageSource.receive(AbstractMessageSource.java:134)
at org.springframework.integration.endpoint.SourcePollingChannelAdapter.receiveMessage(SourcePollingChannelAdapter.java:209)
at org.springframework.integration.endpoint.AbstractPollingEndpoint.doPoll(AbstractPollingEndpoint.java:245)
at org.springframework.integration.endpoint.AbstractPollingEndpoint.access$000(AbstractPollingEndpoint.java:58)
at org.springframework.integration.endpoint.AbstractPollingEndpoint$1.call(AbstractPollingEndpoint.java:190)
at org.springframework.integration.endpoint.AbstractPollingEndpoint$1.call(AbstractPollingEndpoint.java:186)
at org.springframework.integration.endpoint.AbstractPollingEndpoint$Poller$1.run(AbstractPollingEndpoint.java:353)
at org.springframework.integration.util.ErrorHandlingTaskExecutor$1.run(ErrorHandlingTaskExecutor.java:55)
at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50)
at org.springframework.integration.util.ErrorHandlingTaskExecutor.execute(ErrorHandlingTaskExecutor.java:51)
at org.springframework.integration.endpoint.AbstractPollingEndpoint$Poller.run(AbstractPollingEndpoint.java:344)
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:81)
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:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.springframework.messaging.MessagingException: Failed to obtain pooled item; nested exception is java.lang.IllegalStateException: failed to create FTPClient
at org.springframework.integration.util.SimplePool.getItem(SimplePool.java:178)
at org.springframework.integration.file.remote.session.CachingSessionFactory.getSession(CachingSessionFactory.java:123)
at org.springframework.integration.file.remote.RemoteFileTemplate.execute(RemoteFileTemplate.java:433)
at org.springframework.integration.file.remote.synchronizer.AbstractInboundFileSynchronizer.synchronizeToLocalDirectory(AbstractInboundFileSynchronizer.java:232)
... 22 more
Caused by: java.lang.IllegalStateException: failed to create FTPClient
at org.springframework.integration.ftp.session.AbstractFtpSessionFactory.getSession(AbstractFtpSessionFactory.java:169)
at org.springframework.integration.ftp.session.AbstractFtpSessionFactory.getSession(AbstractFtpSessionFactory.java:41)
at org.springframework.integration.file.remote.session.CachingSessionFactory$1.createForPool(CachingSessionFactory.java:81)
at org.springframework.integration.file.remote.session.CachingSessionFactory$1.createForPool(CachingSessionFactory.java:78)
at org.springframework.integration.util.SimplePool.doGetItem(SimplePool.java:188)
at org.springframework.integration.util.SimplePool.getItem(SimplePool.java:169)
... 25 more
Caused by: org.apache.commons.net.MalformedServerReplyException: Could not parse response code.
Server Reply: FZS ..... some speacial characters here.....
at org.apache.commons.net.ftp.FTP.__getReply(FTP.java:336)
at org.apache.commons.net.ftp.FTP.__getReply(FTP.java:292)
at org.apache.commons.net.ftp.FTP._connectAction_(FTP.java:418)
at org.apache.commons.net.ftp.FTPClient._connectAction_(FTPClient.java:966)
at org.apache.commons.net.ftp.FTPClient._connectAction_(FTPClient.java:954)
at org.apache.commons.net.SocketClient.connect(SocketClient.java:189)
at org.apache.commons.net.SocketClient.connect(SocketClient.java:209)
at org.springframework.integration.ftp.session.AbstractFtpSessionFactory.createClient(AbstractFtpSessionFactory.java:191)
at org.springframework.integration.ftp.session.AbstractFtpSessionFactory.getSession(AbstractFtpSessionFactory.java:166)
... 30 more
I'm new to spring integration, please help. Let me know the concepts that I should still consider preparing.
You are most probably connecting to the FileZilla FTP server administrative port (14147).
That port uses a proprietary protocol used by a "FileZilla Server Interface", not FTP, and you are not supposed to connect to it with your application.
Connect to the FTP port instead. By default that is 21. It is configured in "FileZilla Server Interface" on "General Settings" page of the "FileZilla Server Options" as "Listen to these ports".
This is how I create "AbstractInputStreamContent" from inputstream of file:
final Long length = Long.valueOf(filesData.get(uploadedFileName).get("size")).longValue();
final InputStream fileStream = item.openStream(); //FileItemStream item
AbstractInputStreamContent fileContent = new AbstractInputStreamContent(uploadedFileMimeType) {
#Override
public boolean retrySupported() {
return false;
}
#Override
public long getLength() throws IOException {
return length;
}
#Override
public InputStream getInputStream() throws IOException {
return fileStream;
}
};
And "InputStreamContent" as:
InputStreamContent fileContent = new InputStreamContent(uploadedFileMimeType, item.openStream());
fileContent.setLength(Long.valueOf(filesData.get(uploadedFileName).get("size")).longValue());
To replace old file with new file I use(both files are of .docx format):
Drive.Files.Update update = driveService.files().update(fileIdOfFileToReplace,fileMeta,fileContent);
update.set("uploadType", "resumable");
update.getMediaHttpUploader().setDirectUploadEnabled(false);
update.getMediaHttpUploader().setChunkSize(MediaHttpUploader.DEFAULT_CHUNK_SIZE);
File updatedFile = update.execute();
Uploading a new file works fine whether I use InputStreamContent or AbstractInputStreamContent. But update gives "java.lang.IllegalArgumentException" with both
java.lang.IllegalArgumentException
at com.google.api.client.repackaged.com.google.common.base.Preconditions.checkArgument(Preconditions.java:111)
at com.google.api.client.util.Preconditions.checkArgument(Preconditions.java:37)
at com.google.api.client.googleapis.media.MediaHttpUploader.setInitiationRequestMethod(MediaHttpUploader.java:872)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.initializeMediaUpload(AbstractGoogleClientRequest.java:237)
at com.google.api.services.drive.Drive$Files$Update.<init>(Drive.java:3163)
at com.google.api.services.drive.Drive$Files.update(Drive.java:3113)
at com.util.DocumentsUtil.updateFile(DocumentsUtil.java:22)
at com.controllers.collab.documents.Documents.fileUpload(Documents.java:165)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:44)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
Solved it by giving exclusion of google-api-client from each google api maven dependency. Later added google-api-client-1.22.0-SNAPSHOT dependency from sonatype repo. It works fine
Using spring 4.0.6.RELEASE, Hibernate 4.3.6.Final and hsqldb 2.3.2. My integration test looks like the following;
#Test(expected = DataIntegrityViolationException.class)
public final void testDuplicateItems() {
final ServerEntity serverEntity1 = new ServerEntity("DuplicateItem");
opService.save(serverEntity1);
opService.save(serverEntity1);
}
This works as expected. However, when I run my standalone java component i can save the first item, the second item which is a duplicate is not saved but Im unable to catch the exception. Here is the log file
WARN org.hibernate.engine.jdbc.spi.SqlExceptionHelper: SQL Error: -104, SQLState: 23505
2014-08-27 14:52:06,843 ERROR org.hibernate.engine.jdbc.spi.SqlExceptionHelper: integrity constraint violation: unique constraint or index violation; UK_NFU7LXMMDFVIR1WD08662085N table: SERVERENTITY
[WARNING]
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:293)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [UK_NFU7LXMMDFVIR1WD08662085N]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
at org.springframework.orm.hibernate4.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:161)
at org.springframework.orm.hibernate4.HibernateTransactionManager.convertHibernateAccessException(HibernateTransactionManager.java:681)
at org.springframework.orm.hibernate4.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:563)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:757)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:726)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:478)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:272)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
at com.sun.proxy.$Proxy38.execute(Unknown Source)
at com.opserver.simpleapp.MainApp.start(MainApp.java:60)
at com.opserver.simpleapp.MainApp.main(MainApp.java:37)
... 6 more
Both the service and dao implementations have #Transactional at class level. I've a component class that is calling the service class, this component class is not transactional! The component class prints a response, does the session need to be flushed here?
Need to figure out why the save method in the dao is not throwing the exception, I can actually see it an id being created and then rolled back.
J
My component class is very basic;
boolean isValid = opServerService.loadXMLFile("Server.xml");
try{
if (isValid) {
System.out.println("Entity has been added");
} else {
System.out.println("Entity has not been added");
}
}catch (Exception ex){
System.out.println("that was a focked up");
}
The problem is that "Entity has been added" gets printed to console and then I see the above error in console.
DAO looks like this
#Override
#Transactional
public final void save(final ServerEntity serverEntity) throws DataIntegrityViolationException {
LOGGER.debug(">>start(serverEntity=" + serverEntity + ")");
Preconditions.checkNotNull(serverEntity);
this.getCurrentSession().save(serverEntity);
}
Service method with #Transactional at class level, looks like this
#Override
public final void save(ServerEntity serverEntity) {
opServerDao.save(serverEntity);
}
And Component looks like this
#Component
public class AddCommand implements Command {
#Autowired
OpService opService;
public AddServerCommand() {
super();
}
#Override
public void execute(String[] options) {
try{
boolean isValid = opService.save("Server.xml");
if (isValid) {
System.out.println("Entity has been added");
} else {
System.out.println("Entity has not been added");
}
}catch (Exception ex){
System.out.println("Exception found");
}
}
}
You should catch your exception in the component that's calling the service.
Found the solution, was missing from the applicationContext.xml. The wrapped try/catch around the opService now catches the exception. Need to implement my own custom exception handler but for now at least I know the component class is handling the exception which is being thrown from the service class.
Thanks for your help.
J