How to enable IMAPFolder read-write mode in Spring Mail Integration - java

I am using the following Java code in my Spring Boot App (v2.1.6.RELEASE):
#Bean
public IntegrationFlow mailListener() {
SearchTermStrategy searchTermStrategy = (supportedFlags, folder) -> {
SearchTerm search = new AndTerm(new SubjectTerm("trigger the build"), new FlagTerm(new Flags(Flags.Flag.SEEN), false));
return search;
};
return IntegrationFlows.from(Mail.imapInboundAdapter("imaps://usr:pwd#imap.host.com/INBOX").searchTermStrategy(searchTermStrategy).shouldMarkMessagesAsRead(true).get(),
e -> e.poller(Pollers.fixedRate(5000).maxMessagesPerPoll(1)))
.<Message>handle((payload, header) -> logMail(payload))
.get();
}
But this throws an exception com.sun.mail.iap.CommandFailedException: A7 NO Command received in Invalid state. when there is a matching message. This seems to be an issue with the IMAP folder being set as Read-only by default.
There is an onInit protected method in the AbstractMailReceiver class which opens the Folder in Read-Write mode. And I have tried to call the ImapMailReceiver.afterPropertiesSet() which eventually calls the onInit method but that gives me An external 'receiver' ... can't be modified.:
#Bean
private ImapMailReceiver receiver() {
ImapMailReceiver receiver = new ImapMailReceiver("...URL...");
receiver.afterPropertiesSet();
//receiver.setJavaMailProperties(javaMailProperties);
return receiver;
}
Can someone please guide me on how to set the folder in read-write mode?
P.S. In plain Java code I could set the same using inbox.open(Folder.READ_WRITE) and this works.
EDIT 1
If I use the code like this:
#Bean
public IntegrationFlow mailListener() {
SearchTermStrategy searchTermStrategy = (supportedFlags, folder) -> {
SearchTerm search = new AndTerm(new SubjectTerm("trigger the build"),
new FlagTerm(new Flags(Flags.Flag.SEEN), false));
return search;
};
return IntegrationFlows.from(Mail.imapInboundAdapter(receiver()))
.log()
.get();
}
#Bean
public ImapMailReceiver receiver() {
return new ImapMailReceiver(IMAP_URL);
}
I get the following error:
Caused by: java.lang.IllegalArgumentException: No poller has been defined for channel-adapter 'mailListener.org.springframework.integration.config.SourcePollingChannelAdapterFactoryBean#0', and no default poller is available within the context.
at org.springframework.util.Assert.notNull(Assert.java:198) ~[spring-core-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.integration.config.SourcePollingChannelAdapterFactoryBean.initializeAdapter(SourcePollingChannelAdapterFactoryBean.java:186) ~[spring-integration-core-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.integration.config.SourcePollingChannelAdapterFactoryBean.afterPropertiesSet(SourcePollingChannelAdapterFactoryBean.java:144) ~[spring-integration-core-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1837) ~[spring-beans-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1774) ~[spring-beans-5.1.8.RELEASE.jar:5.1.8.RELEASE]
... 26 common frames omitted
EDIT 2
If I use the code as below:
#Bean
public IntegrationFlow mailListener() {
SearchTermStrategy searchTermStrategy = (supportedFlags, folder) -> {
SearchTerm search = new AndTerm(new SubjectTerm("trigger the build"),
new FlagTerm(new Flags(Flags.Flag.SEEN), false));
return search;
};
return IntegrationFlows.from(Mail.imapInboundAdapter(receiver()).searchTermStrategy(searchTermStrategy).shouldMarkMessagesAsRead(true).get(),
e -> e.poller(Pollers.fixedRate(5000).maxMessagesPerPoll(1)))
.<Message>handle((payload, header) -> logMail(payload))
.get();
}
#Bean
public ImapMailReceiver receiver() {
return new ImapMailReceiver(IMAP_URL);
}
I get the following error:
Caused by: java.lang.IllegalStateException: An external 'receiver' [imaps://.../INBOX] can't be modified.
at org.springframework.util.Assert.state(Assert.java:94) ~[spring-core-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.integration.mail.dsl.MailInboundChannelAdapterSpec.assertReceiver(MailInboundChannelAdapterSpec.java:85) ~[spring-integration-mail-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.integration.mail.dsl.ImapMailInboundChannelAdapterSpec.searchTermStrategy(ImapMailInboundChannelAdapterSpec.java:51) ~[spring-integration-mail-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at com.xxx.emailapp.InboundEmailConfig.mailListener(InboundEmailConfig.java:33) ~[classes/:na]
at com.xxx.emailapp.InboundEmailConfig$$EnhancerBySpringCGLIB$$7ab01b59.CGLIB$mailListener$1(<generated>) ~[classes/:na]
at com.xxx.emailapp.InboundEmailConfig$$EnhancerBySpringCGLIB$$7ab01b59$$FastClassBySpringCGLIB$$8ee22ea2.invoke(<generated>) ~[classes/:na]
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244) ~[spring-core-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:363) ~[spring-context-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at com.xxx.emailapp.InboundEmailConfig$$EnhancerBySpringCGLIB$$7ab01b59.mailListener(<generated>) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_161]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_161]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_161]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_161]
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154) ~[spring-beans-5.1.8.RELEASE.jar:5.1.8.RELEASE]
... 19 common frames omitted

Declaring an explicit receiver bean works
#Bean
public IntegrationFlow mailListener() {
SearchTermStrategy searchTermStrategy = (supportedFlags, folder) -> {
SearchTerm search = new AndTerm(new SubjectTerm("trigger the build"),
new FlagTerm(new Flags(Flags.Flag.SEEN), false));
return search;
};
return IntegrationFlows.from(Mail.imapInboundAdapter(receiver()))
.log()
.get();
}
#Bean
public ImapMailReceiver receiver() {
return new ImapMailReceiver("imaps://usr:pwd#imap.host.com/INBOX");
}
EDIT
You must not call get() on the receiver spec; the framework needs a reference to the spec itself to properly initialize the bean(s).

Related

Could not find class [de.flapdoodle.embed.process.config.IRuntimeConfig]

After upgrading to embeded MongoDB with version 3.0.0, I am getting the following exception.
I am using the following in build.gradle.
testImplementation group: 'de.flapdoodle.embed', name: 'de.flapdoodle.embed.mongo', version: '3.0.0'
The exception is given below.
Caused by: java.lang.ClassNotFoundException: de.flapdoodle.embed.process.config.IRuntimeConfig
at java.net.URLClassLoader.findClass(URLClassLoader.java:382) ~[na:1.8.0_261]
at java.lang.ClassLoader.loadClass(ClassLoader.java:418) ~[na:1.8.0_261]
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:355) ~[na:1.8.0_261]
at java.lang.ClassLoader.loadClass(ClassLoader.java:351) ~[na:1.8.0_261]
at java.lang.Class.forName0(Native Method) ~[na:1.8.0_261]
at java.lang.Class.forName(Class.java:348) ~[na:1.8.0_261]
at org.springframework.util.ClassUtils.forName(ClassUtils.java:284) ~[spring-core-5.2.10.RELEASE.jar:5.2.10.RELEASE]
at org.springframework.util.ClassUtils.resolveClassName(ClassUtils.java:324) ~[spring-core-5.2.10.RELEASE.jar:5.2.10.RELEASE]
I provide below the code. I want to use embeded mongoDB for the MongoDB transaction feature in the integration test in spring boot.
#Profile("test")
#ActiveProfiles("test")
public class TestMongoConfig1 implements InitializingBean, DisposableBean {
MongodForTestsFactory factory = null;
MongodConfig mongodConfig = MongodConfig.builder().version(Version.Main.PRODUCTION).build();
MongodStarter runtime = MongodStarter.getDefaultInstance();
MongodExecutable mongodExecutable = null;
MongodProcess mongod = null;
#Override
public void destroy() throws Exception {
mongodExecutable.stop();
}
#Override
public void afterPropertiesSet() throws Exception {
mongodExecutable = runtime.prepare(mongodConfig);
mongod = mongodExecutable.start();
}
#Bean(name = "test1")
public MongoClient mongoClient() {
MongoClient mongoClient = MongoClients.create();
System.out.println("============================================");
System.out.println(mongoClient);
System.out.println("============================================");
return mongoClient;
}
}
First you have to use the following dependencies in build.gradle apart from other dependencies if you are using #DataMongoTest.
implementation("org.springframework.boot:spring-boot-starter-data-mongodb")
testImplementation("de.flapdoodle.embed:de.flapdoodle.embed.mongo")
To test with embeded MongoDB, you have to use the following snippet which may work.
#Profile("test")
#ActiveProfiles("test")
#Configuration
public class TestMongoConfig1 implements InitializingBean, DisposableBean {
private MongodExecutable executable;
#Override
public void afterPropertiesSet() throws Exception {
IFeatureAwareVersion version = Versions.withFeatures(new GenericVersion("4.0.0"),
Version.Main.PRODUCTION.getFeatures());
IMongoCmdOptions cmdOptions = new
MongoCmdOptionsBuilder().useNoPrealloc(false).useSmallFiles(false)
.master(false).verbose(false).useNoJournal(false).syncDelay(0).build();
int port = Network.getFreeServerPort();
IMongodConfig mongodConfig = new MongodConfigBuilder().version(version)
.net(new Net(port, Network.localhostIsIPv6())).replication(new Storage(null, "testRepSet", 5000))
.configServer(false).cmdOptions(cmdOptions).build();
MongodStarter starter = MongodStarter.getDefaultInstance();
executable = starter.prepare(mongodConfig);
executable.start();
}

Signing SOAP header using Wss4j in Spring throwing errors "Caused by: java.security.UnrecoverableKeyException: Given final block not properly padded"

I am implementing a SOAP client using Spring Boot for the below configuration to connect with third party web server. Below is my WS-security outgoing configuration used with SOAPUI Client.
and timestamp and username configuration is as follows
I have written Wss4jSecurityInterceptor for the above configuration which is as follows.
#Configuration
public class Config {
private static final Logger LOGGER = LoggerFactory.getLogger(Config.class);
#Bean
public Jaxb2Marshaller marshaller() {
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
// this is the package name specified in the <generatePackage> specified in
// pom.xml
marshaller.setContextPath("co.yabx.bureau.wsdl");
return marshaller;
}
#Bean
public ExecuteStrategy executeStrategy(Jaxb2Marshaller jaxb2Marshaller) throws Exception {
ExecuteStrategy soapClient = new ExecuteStrategy();
soapClient.setDefaultUri("https://demo-abc/dummy/url");
soapClient.setMarshaller(jaxb2Marshaller);
soapClient.setUnmarshaller(jaxb2Marshaller);
ClientInterceptor[] interceptors = new ClientInterceptor[] { wss4jSecurityInterceptor() };
soapClient.setInterceptors(interceptors);
return soapClient;
}
#Bean
public CryptoFactoryBean cryptoFactoryBean() throws IOException {
CryptoFactoryBean cryptoFactoryBean = new CryptoFactoryBean();
cryptoFactoryBean.setKeyStoreType("PKCS12");
cryptoFactoryBean.setKeyStorePassword("123456");
cryptoFactoryBean.setDefaultX509Alias("1");
ClassPathResource classPathResource = new ClassPathResource("\\jks\\exdemo.p12"); //
// System.out.println(classPathResource.getURL());
cryptoFactoryBean.setKeyStoreLocation(classPathResource);
return cryptoFactoryBean;
}
#Bean
public Wss4jSecurityInterceptor wss4jSecurityInterceptor() throws Exception {
Wss4jSecurityInterceptor wss4jSecurityInterceptor = new Wss4jSecurityInterceptor();
wss4jSecurityInterceptor.setSecurementActions("UsernameToken Timestamp Signature");
// Sign the request
wss4jSecurityInterceptor.setSecurementSignatureUser("alias"); // alias vale used in above screenshot
wss4jSecurityInterceptor.setSecurementUsername("pqr");
wss4jSecurityInterceptor.setSecurementTimeToLive(60);
wss4jSecurityInterceptor.setSecurementPassword("lmn*");
wss4jSecurityInterceptor.setSecurementPasswordType(WSConstants.PW_TEXT);
wss4jSecurityInterceptor.setSecurementUsernameTokenNonce(true);
wss4jSecurityInterceptor.setSecurementUsernameTokenCreated(true);
wss4jSecurityInterceptor.setSecurementSignatureCrypto(cryptoFactoryBean().getObject());
// Encrypt the request
// wss4jSecurityInterceptor.setSecurementEncryptionUser("server-public");
wss4jSecurityInterceptor.setSecurementSignatureKeyIdentifier("DirectReference");
wss4jSecurityInterceptor.setSecurementSignatureAlgorithm(WSConstants.RSA_SHA1);
wss4jSecurityInterceptor.setSecurementSignatureDigestAlgorithm(WSConstants.SHA1);
wss4jSecurityInterceptor.setSecurementMustUnderstand(true);
// wss4jSecurityInterceptor.setSecurementEncryptionUser(securementEncryptionUser);
wss4jSecurityInterceptor.setRemoveSecurityHeader(true);
wss4jSecurityInterceptor.setSecurementEncryptionCrypto(cryptoFactoryBean().getObject());
return wss4jSecurityInterceptor;
}
}
After setting the whole configuration and running the application it is throwing error, which is as follows.
2020-04-20 15:45:21.826 ERROR 1172 --- [ main] o.a.wss4j.dom.message.WSSecSignature : No message with ID "noPrivateKey" found in resource bundle "org/apache/xml/security/resource/xmlsecurity"
org.apache.wss4j.common.ext.WSSecurityException: No message with ID "noPrivateKey" found in resource bundle "org/apache/xml/security/resource/xmlsecurity"
at org.apache.wss4j.common.crypto.Merlin.getPrivateKey(Merlin.java:722) ~[wss4j-ws-security-common-2.2.3.jar:2.2.3]
at org.apache.wss4j.dom.message.WSSecSignature.computeSignature(WSSecSignature.java:558) ~[wss4j-ws-security-dom-2.2.3.jar:2.2.3]
at org.apache.wss4j.dom.action.SignatureAction.execute(SignatureAction.java:166) [wss4j-ws-security-dom-2.2.3.jar:2.2.3]
at org.apache.wss4j.dom.handler.WSHandler.doSenderAction(WSHandler.java:238) [wss4j-ws-security-dom-2.2.3.jar:2.2.3]
at org.springframework.ws.soap.security.wss4j2.Wss4jHandler.doSenderAction(Wss4jHandler.java:63) [spring-ws-security-3.0.8.RELEASE.jar:na]
at org.springframework.ws.soap.security.wss4j2.Wss4jSecurityInterceptor.secureMessage(Wss4jSecurityInterceptor.java:574) [spring-ws-security-3.0.8.RELEASE.jar:na]
at org.springframework.ws.soap.security.AbstractWsSecurityInterceptor.handleRequest(AbstractWsSecurityInterceptor.java:210) [spring-ws-security-3.0.8.RELEASE.jar:na]
at org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:597) [spring-ws-core-3.0.8.RELEASE.jar:na]
at org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive(WebServiceTemplate.java:555) [spring-ws-core-3.0.8.RELEASE.jar:na]
at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:390) [spring-ws-core-3.0.8.RELEASE.jar:na]
at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:383) [spring-ws-core-3.0.8.RELEASE.jar:na]
at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:373) [spring-ws-core-3.0.8.RELEASE.jar:na]
at co.yabx.bureau.client.ExecuteStrategy.executeStrategy(ExecuteStrategy.java:18) [classes/:na]
at co.yabx.bureau.BureauSoapServiceApplication.main(BureauSoapServiceApplication.java:34) [classes/:na]
Caused by: java.security.UnrecoverableKeyException: Get Key failed: Given final block not properly padded. Such issues can arise if a bad key is used during decryption.
at sun.security.pkcs12.PKCS12KeyStore.engineGetKey(Unknown Source) ~[na:1.8.0_171]
at java.security.KeyStore.getKey(Unknown Source) ~[na:1.8.0_171]
at org.apache.wss4j.common.crypto.Merlin.getPrivateKey(Merlin.java:710) ~[wss4j-ws-security-common-2.2.3.jar:2.2.3]
... 13 common frames omitted
Caused by: javax.crypto.BadPaddingException: Given final block not properly padded. Such issues can arise if a bad key is used during decryption.
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:991) ~[sunjce_provider.jar:1.8.0_171]
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:847) ~[sunjce_provider.jar:1.8.0_171]
at com.sun.crypto.provider.PKCS12PBECipherCore.implDoFinal(PKCS12PBECipherCore.java:399) ~[sunjce_provider.jar:1.8.0_171]
at com.sun.crypto.provider.PKCS12PBECipherCore$PBEWithSHA1AndDESede.engineDoFinal(PKCS12PBECipherCore.java:431) ~[sunjce_provider.jar:1.8.0_171]
at javax.crypto.Cipher.doFinal(Cipher.java:2164) ~[na:1.8.0_171]
... 16 common frames omitted
2020-04-20 15:45:21.827 ERROR 1172 --- [ main] o.s.w.s.s.w.Wss4jSecurityInterceptor : Could not secure response: Error during Signature: ; nested exception is org.apache.wss4j.common.ext.WSSecurityException: Error during Signature:
Original Exception was org.apache.wss4j.common.ext.WSSecurityException: No message with ID "noPrivateKey" found in resource bundle "org/apache/xml/security/resource/xmlsecurity"
Original Exception was org.apache.wss4j.common.ext.WSSecurityException: No message with ID "noPrivateKey" found in resource bundle "org/apache/xml/security/resource/xmlsecurity"
Original Exception was java.security.UnrecoverableKeyException: Get Key failed: Given final block not properly padded. Such issues can arise if a bad key is used during decryption.
org.springframework.ws.soap.security.wss4j2.Wss4jSecuritySecurementException: Error during Signature: ; nested exception is org.apache.wss4j.common.ext.WSSecurityException: Error during Signature:
Original Exception was org.apache.wss4j.common.ext.WSSecurityException: No message with ID "noPrivateKey" found in resource bundle "org/apache/xml/security/resource/xmlsecurity"
Original Exception was org.apache.wss4j.common.ext.WSSecurityException: No message with ID "noPrivateKey" found in resource bundle "org/apache/xml/security/resource/xmlsecurity"
Original Exception was java.security.UnrecoverableKeyException: Get Key failed: Given final block not properly padded. Such issues can arise if a bad key is used during decryption.
at org.springframework.ws.soap.security.wss4j2.Wss4jSecurityInterceptor.secureMessage(Wss4jSecurityInterceptor.java:577) ~[spring-ws-security-3.0.8.RELEASE.jar:na]
at org.springframework.ws.soap.security.AbstractWsSecurityInterceptor.handleRequest(AbstractWsSecurityInterceptor.java:210) ~[spring-ws-security-3.0.8.RELEASE.jar:na]
at org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:597) [spring-ws-core-3.0.8.RELEASE.jar:na]
at org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive(WebServiceTemplate.java:555) [spring-ws-core-3.0.8.RELEASE.jar:na]
at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:390) [spring-ws-core-3.0.8.RELEASE.jar:na]
at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:383) [spring-ws-core-3.0.8.RELEASE.jar:na]
at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:373) [spring-ws-core-3.0.8.RELEASE.jar:na]
at co.yabx.bureau.client.ExecuteStrategy.executeStrategy(ExecuteStrategy.java:18) [classes/:na]
at co.yabx.bureau.BureauSoapServiceApplication.main(BureauSoapServiceApplication.java:34) [classes/:na]
Caused by: org.apache.wss4j.common.ext.WSSecurityException: Error during Signature:
at org.apache.wss4j.dom.action.SignatureAction.execute(SignatureAction.java:174) ~[wss4j-ws-security-dom-2.2.3.jar:2.2.3]
at org.apache.wss4j.dom.handler.WSHandler.doSenderAction(WSHandler.java:238) ~[wss4j-ws-security-dom-2.2.3.jar:2.2.3]
at org.springframework.ws.soap.security.wss4j2.Wss4jHandler.doSenderAction(Wss4jHandler.java:63) ~[spring-ws-security-3.0.8.RELEASE.jar:na]
at org.springframework.ws.soap.security.wss4j2.Wss4jSecurityInterceptor.secureMessage(Wss4jSecurityInterceptor.java:574) ~[spring-ws-security-3.0.8.RELEASE.jar:na]
... 8 common frames omitted
Caused by: org.apache.wss4j.common.ext.WSSecurityException: No message with ID "noPrivateKey" found in resource bundle "org/apache/xml/security/resource/xmlsecurity"
at org.apache.wss4j.dom.message.WSSecSignature.computeSignature(WSSecSignature.java:615) ~[wss4j-ws-security-dom-2.2.3.jar:2.2.3]
at org.apache.wss4j.dom.action.SignatureAction.execute(SignatureAction.java:166) ~[wss4j-ws-security-dom-2.2.3.jar:2.2.3]
... 11 common frames omitted
Caused by: org.apache.wss4j.common.ext.WSSecurityException: No message with ID "noPrivateKey" found in resource bundle "org/apache/xml/security/resource/xmlsecurity"
at org.apache.wss4j.common.crypto.Merlin.getPrivateKey(Merlin.java:722) ~[wss4j-ws-security-common-2.2.3.jar:2.2.3]
at org.apache.wss4j.dom.message.WSSecSignature.computeSignature(WSSecSignature.java:558) ~[wss4j-ws-security-dom-2.2.3.jar:2.2.3]
... 12 common frames omitted
Caused by: java.security.UnrecoverableKeyException: Get Key failed: Given final block not properly padded. Such issues can arise if a bad key is used during decryption.
at sun.security.pkcs12.PKCS12KeyStore.engineGetKey(Unknown Source) ~[na:1.8.0_171]
at java.security.KeyStore.getKey(Unknown Source) ~[na:1.8.0_171]
at org.apache.wss4j.common.crypto.Merlin.getPrivateKey(Merlin.java:710) ~[wss4j-ws-security-common-2.2.3.jar:2.2.3]
... 13 common frames omitted
Caused by: javax.crypto.BadPaddingException: Given final block not properly padded. Such issues can arise if a bad key is used during decryption.
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:991) ~[sunjce_provider.jar:1.8.0_171]
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:847) ~[sunjce_provider.jar:1.8.0_171]
at com.sun.crypto.provider.PKCS12PBECipherCore.implDoFinal(PKCS12PBECipherCore.java:399) ~[sunjce_provider.jar:1.8.0_171]
at com.sun.crypto.provider.PKCS12PBECipherCore$PBEWithSHA1AndDESede.engineDoFinal(PKCS12PBECipherCore.java:431) ~[sunjce_provider.jar:1.8.0_171]
at javax.crypto.Cipher.doFinal(Cipher.java:2164) ~[na:1.8.0_171]
... 16 common frames omitted
I also tried creating CrytpoFactoryBean using properties but still getting the same issue. Below is the property configuration I tried
Properties properties = new Properties();
properties.setProperty("org.apache.ws.security.crypto.provider", "org.apache.wss4j.common.crypto.Merlin");
properties.setProperty("org.apache.wss4j.crypto.merlin.keystore.alias", "alias");
properties.setProperty("org.apache.ws.security.crypto.merlin.keystore.type", "PKCS12");
properties.setProperty("org.apache.ws.security.crypto.merlin.keystore.password", "123456");
properties.setProperty("org.apache.ws.security.crypto.merlin.keystore.file",
"\\jks\\exdemo.p12");
cryptoFactoryBean.setConfiguration(properties);
try {
cryptoFactoryBean.afterPropertiesSet();
} catch (Exception e) { // TODO Auto-generated catch block
e.printStackTrace();
}
I don't understand what mistakes am I doing. Anyhelp will be appreciated.
In the above code, I was adding security configurations for Username, password, and Signature together, instead, I have to keep them in separate arrays as follows.
#Bean
public ExecuteStrategy executeStrategy(Jaxb2Marshaller jaxb2Marshaller) throws Exception {
ExecuteStrategy soapClient = new ExecuteStrategy();
soapClient.setDefaultUri("https://demo-servicesesb.datacredito.com.co/wss/DecisorWS/services/dummyService/MotorService");
soapClient.setMarshaller(jaxb2Marshaller);
soapClient.setUnmarshaller(jaxb2Marshaller);
ClientInterceptor[] interceptors = wss4jSecurityInterceptor();
soapClient.setInterceptors(interceptors);
return soapClient;
}
and
#Bean
public Wss4jSecurityInterceptor[] wss4jSecurityInterceptor() throws Exception {
// org.apache.xml.security.Init.init();
Wss4jSecurityInterceptor wss4jSecurityInterceptor = new Wss4jSecurityInterceptor();
wss4jSecurityInterceptor.setSecurementActions("UsernameToken");
// Sign in the request
wss4jSecurityInterceptor.setSecurementUsername("dummyUser");
wss4jSecurityInterceptor.setSecurementPassword("dummyPassword");
// wss4jSecurityInterceptor.setSecurementPassword("123456");
wss4jSecurityInterceptor.setSecurementPasswordType(WSConstants.PW_TEXT);
wss4jSecurityInterceptor.setSecurementUsernameTokenNonce(true);
wss4jSecurityInterceptor.setSecurementUsernameTokenCreated(true);
wss4jSecurityInterceptor.afterPropertiesSet();
Wss4jSecurityInterceptor wss4jSecurityInterceptor1 = new Wss4jSecurityInterceptor();
wss4jSecurityInterceptor1.setSecurementActions("Signature");
wss4jSecurityInterceptor1.setSecurementSignatureUser("1");
wss4jSecurityInterceptor1.setSecurementPassword("123456");
wss4jSecurityInterceptor1.setSecurementSignatureKeyIdentifier("DirectReference");
wss4jSecurityInterceptor1.setSecurementSignatureAlgorithm(WSConstants.RSA_SHA1);
wss4jSecurityInterceptor1.setSecurementSignatureDigestAlgorithm(WSConstants.SHA1);
wss4jSecurityInterceptor1.setSecurementTimeToLive(60);
wss4jSecurityInterceptor1.setTimestampPrecisionInMilliseconds(true);
wss4jSecurityInterceptor1.setSecurementSignatureCrypto(cryptoFactoryBean().getObject());
wss4jSecurityInterceptor1.afterPropertiesSet();
Wss4jSecurityInterceptor[] wss4jSecurityInterceptorArray = new Wss4jSecurityInterceptor[2];
wss4jSecurityInterceptorArray[0] = wss4jSecurityInterceptor;
wss4jSecurityInterceptorArray[1] = wss4jSecurityInterceptor1;
return wss4jSecurityInterceptorArray;
}
and
#Bean
public CryptoFactoryBean cryptoFactoryBean() throws IOException {
CryptoFactoryBean cryptoFactoryBean = new CryptoFactoryBean();
Properties properties = new Properties();
properties.setProperty("org.apache.ws.security.crypto.provider", "org.apache.wss4j.common.crypto.Merlin");
properties.setProperty("org.apache.wss4j.crypto.merlin.keystore.alias", "1");
properties.setProperty("org.apache.ws.security.crypto.merlin.keystore.type", "PKCS12");
properties.setProperty("org.apache.ws.security.crypto.merlin.keystore.password", "123456");
properties.setProperty("org.apache.ws.security.crypto.merlin.keystore.file",
"C:\\abc.p12");
cryptoFactoryBean.setConfiguration(properties);
try {
cryptoFactoryBean.afterPropertiesSet();
} catch (Exception e) {
e.printStackTrace();
}
return cryptoFactoryBean;
}
Keeping the wss4jSecurityInterceptor as an array for username/password as separate and Signature as separate array, worked for me.

Java BeanDefinitionStoreException on Spring Boot 2

I'm trying to rewrite an application using Spring Boot 2 (specifically 2.1.5.RELEASE). Previous version used 1.5.7.RELEASE. We are switching database platforms, thus the rewrite. The startup class in both new and old are nearly identical, both attempting to create a bean from another library. It works in 1.5.7, but in 2.1.5, it fails with the following message:
org.springframework.beans.factory.BeanDefinitionStoreException: Failed to process
import candidates for configuration class [com.company.consumer.ConsumerRecoveryConfiguration];
nested exception is java.lang.IllegalStateException: Failed to introspect
annotated methods on class com.company.consumer.RecordRecovery
Here's what the startup class looks like in old and new:
Old:
#SpringBootApplication
#ComponentScan(basePackages = {
"com.company.core",
"com.company.something",
"com.company.platform",
"com.company.config"},
excludeFilters = #ComponentScan.Filter(type =
FilterType.REGEX, pattern = "com.company.common.diag.*"))
#Import({SomeClass.class, ConsumerRecoveryConfiguration.class,
ConsumerRetryConfiguration.class})
#PropertySource("classpath:build.properties")
public class SomeApplication {
public static void main(String[] args) {
SpringApplication.run(SomeApplication.class, args);
}
#Bean(name = "someDbTimingLogger")
public TimingLogger getSomeDbTimingLogger() {
return new TimingLogger(LoggerFactory.getLogger("timing.someDb"));
}
#Bean(name = "timingLogger")
public TimingLogger getTimingLogger() {
return new TimingLogger(LoggerFactory.getLogger("timing.consumer"));
}
#Bean(name = "kafkaTimingLogger")
public TimingLogger getKafkaTimingLogger() {
return new TimingLogger(LoggerFactory.getLogger("timing.kafka"));
}
#Bean(name = "parser")
public Parser<GenericMessageModel> getSomeModelParser() {
return new Parser<>(GenericMessageModel.class);
}
}
New:
#SpringBootApplication
#ComponentScan(basePackages = {
"com.company.core",
"com.company.something",
"com.company.platform",
"com.company.config"},
excludeFilters = #ComponentScan.Filter(
type = FilterType.REGEX,
pattern = "com.company.common.diag.*"
))
#Import({ ConsumerRecoveryConfiguration.class,
ConsumerRetryConfiguration.class })
#PropertySource("classpath:build.properties")
public class SomeApplication {
public static void main(String[] args) {
SpringApplication.run(SomeApplication.class, args);
}
#Bean(name = "timingLogger")
public TimingLogger getTimingLogger() { return new TimingLogger(LoggerFactory.getLogger("timing.consumer")); }
#Bean(name = "kafkaTimingLogger")
public TimingLogger getKafkaTimingLogger() { return new TimingLogger(LoggerFactory.getLogger("timing.kafka")); }
#Bean(name = "parser")
public Parser<GenericMessageModel> getSomeModelParser() { return new Parser<>(GenericMessageModel.class, null); }
}
The Kotlin class mentioned in the nested exception is as follows (minus its numerous private methods):
#Component
class RecordRecovery(val producer: KafkaProducer<String, String>, val kafkaProducerSettings: KafkaProducerSettings,
val recoverySettings: RecoverySettings, val objectMapper: ObjectMapper) {
val random = ThreadLocalRandom.current()!!
companion object {
val LOGGER = LoggerFactory.getLogger(RecordRecovery::class.java)
}
fun recoverRecords(records: ConsumerRecords<String, String>, exception: Exception) {
recoverRecords(records.map { it.value() ?: StringUtils.EMPTY }, exception)
}
fun recoverRecords(records: List<Any>, exception: Exception) {
error(metaDataFor(records.count()), LOGGER, "Recovering {} records", records.count())
val filteredRecords = records.map { createRecoveryRecord(it) }
.filter{ it != null }
.map { recordToJson(it) }
.filter { removeNulls(it) }
.mapIndexed { index, it -> toEmergencyDataWrapper(it!!, exception, index) }
.mapNotNull {toJSONStringOrNull(it)}
.map {toProducerRecord(it)}
.map { republish(it) }
.toList()
info(metaDataFor(filteredRecords.count()), LOGGER, "After filtering, recovering {} records", filteredRecords.count())
filteredRecords.map { await(it) }
}
}
And here's the ConsumerRecoveryConfiguration class (also Kotlin) in question:
#Configuration
#Import(KafkaProducerConfig::class, RecoverySettings::class, RecordRecovery::class)
class ConsumerRecoveryConfiguration
The class has no body whatsoever. I'm assuming that importing the other classes causes Spring to basically use those as the body.
I'm still somewhat green when it comes to Spring, so I'm struggling to see why it stopped working when I changed to SB 2. Any suggestions about where I should look or what might help me figure this out?
EDIT:
Here is the full stacktrace as requested:
org.springframework.beans.factory.BeanDefinitionStoreException: Failed to process import candidates for configuration class [com.company.consumer.ConsumerRecoveryConfiguration]; nested exception is java.lang.IllegalStateException: Failed to introspect annotated methods on class com.company.consumer.RecordRecovery
at org.springframework.context.annotation.ConfigurationClassParser.processImports(ConfigurationClassParser.java:596)
at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:302)
at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:242)
at org.springframework.context.annotation.ConfigurationClassParser.processImports(ConfigurationClassParser.java:586)
at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:302)
at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:242)
at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:199)
at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:167)
at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:315)
at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:232)
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:275)
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:95)
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:705)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:531)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:142)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:775)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:316)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1260)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1248)
at com.company.SomeApplication.main(SomeApplication.java:35)
Caused by: java.lang.IllegalStateException: Failed to introspect annotated methods on class com.company.consumer.RecordRecovery
at org.springframework.core.type.StandardAnnotationMetadata.getAnnotatedMethods(StandardAnnotationMetadata.java:169)
at org.springframework.context.annotation.ConfigurationClassParser.retrieveBeanMethodMetadata(ConfigurationClassParser.java:392)
at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:317)
at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:242)
at org.springframework.context.annotation.ConfigurationClassParser.processImports(ConfigurationClassParser.java:586)
... 20 common frames omitted
Caused by: java.lang.NoClassDefFoundError: org/json/JSONObject
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2701)
at java.lang.Class.getDeclaredMethods(Class.java:1975)
at org.springframework.core.type.StandardAnnotationMetadata.getAnnotatedMethods(StandardAnnotationMetadata.java:158)
... 24 common frames omitted
Caused by: java.lang.ClassNotFoundException: org.json.JSONObject
at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 28 common frames omitted

mocking enum using powerMock

I am trying to mock enum using powerMock but got Field 'fTestClass' was not found in class error when i ran test. I found that the issue is with Junit 4.12 and powermock-module-junit4 1.5.6. so I changed to 1.6.1 now I am getting below error ...
java.lang.ExceptionInInitializerError
at sun.reflect.GeneratedSerializationConstructorAccessor9.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
at org.objenesis.instantiator.sun.SunReflectionFactoryInstantiator.newInstance(SunReflectionFactoryInstantiator.java:45)
at org.objenesis.ObjenesisBase.newInstance(ObjenesisBase.java:73)
at org.mockito.internal.creation.jmock.ClassImposterizer.createProxy(ClassImposterizer.java:142)
at org.mockito.internal.creation.jmock.ClassImposterizer.imposterise(ClassImposterizer.java:61)
at org.powermock.api.mockito.internal.mockcreation.MockCreator.createMethodInvocationControl(MockCreator.java:109)
at org.powermock.api.mockito.internal.mockcreation.MockCreator.mock(MockCreator.java:57)
at org.powermock.api.mockito.PowerMockito.mockStatic(PowerMockito.java:70)
at OrderEventProcessorTest.setUp(OrderEventProcessorTest.java:47)
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:497)
at org.junit.internal.runners.MethodRoadie.runBefores(MethodRoadie.java:133)
at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:96)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:294)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTestInSuper(PowerMockJUnit47RunnerDelegateImpl.java:127)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTest(PowerMockJUnit47RunnerDelegateImpl.java:82)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:282)
at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:87)
at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:50)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:207)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:146)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$1.run(PowerMockJUnit44RunnerDelegateImpl.java:120)
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:34)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:44)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:122)
at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:106)
at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:53)
at org.powermock.modules.junit4.PowerMockRunner.run(PowerMockRunner.java:59)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:234)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:74)
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:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Caused by: java.lang.NullPointerException
Basically I am trying to mock enum to check the functionality of insert, update, delete operations to cassandra db. the enum gives setups the cassadra db connection. I want to mock it so I don't need to connect to the DB to test my crud functionality. Please let me know if still is there any versioning issues with Junit 4.12 and powermock 1.6.1 . I am using mockito-core 1.10.19 and maven-surefire-plugin 2.19.1
EDITED
ENUM for DB connection
public enum CassProvider {
INSTANCE;
private Map<String,ThreadLocal<PreparedStatement>> psMap;
private String[] hostnames;
private String username;
private String password;
private String keyspace;
private Cluster cluster;
private Session session;
private CassProvider() {
init();
psMap = createPreparedStatements();
}
private void init() {
//get host, port, user , pasword from properties file
cluster = Cluster.builder().addContactPoints(hostnames).withPort(port).withCredentials(username, password).build();
session = cluster.connect(keyspace);
}
private static Map<String,ThreadLocal<PreparedStatement>> createPreparedStatements() {
//code goes for mapping preparedStatements
return psMap;
}
public PreparedStatement getPreparedStatement(String id) {
//logic for preparedStatement
return preparedStatement;
}
public Session getSession() {
return session;
}
}
Code I would like to test for different conditions it executes different prepared statements
if (eventMappingType != null && processEvent) {
.......
BatchStatement batchStatement = new BatchStatement();
PreparedStatement psFieldInsert = CassProvider.INSTANCE.getPreparedStatement("INSERT_ORDERS_FV");
if (eventMappingType.getSimpleFields() != null) {
for (FieldType fieldType : eventMappingType.getSimpleFields().getField()) {
Object value = MVEL.executeExpression(fieldType.getSerializedExpr(), context);
batchStatement.add(psFieldInsert.bind(keyFields.get("orderNumber"),dateStringToDate(eventDateTime), fieldType.getValue(), value != null ? value.toString() : value));
}
}
if (eventType.compareToIgnoreCase("OrderPlaced") == 0) {
//Update the lookup table for given name 2 orders.
if (name != null && name.compareToIgnoreCase("")!=0) {
batchStatement.add(CassProvider.INSTANCE.getPreparedStatement("INSERT_ORDERS_BY_NAME").bind(name, dateStringToDate(eventDateTime), orderNumber));
}
//Update the lookup table for accIds 2 orders; not sure if we need this for now
if (accIds != null && accIds.compareToIgnoreCase("")!=0) {
batchStatement.add(CassProvider.INSTANCE.getPreparedStatement("INSERT_ORDERS_BY_ACCIDS").bind(accIds, dateStringToDate(eventDateTime), orderNumber));
}
if (SAPOrderNumber != null) {
batchStatement.add(CassProvider.INSTANCE.getPreparedStatement("INSERT_SAP_ORDER").bind(SAPOrderNumber, orderNumber));
}
}
CassProvider.INSTANCE.getSession().execute(batchStatement);
}
Not sure how your Cluster.builder() method works but I suggest you make that you configurable, i.e. to open it up for your test class to inject a mocked builder that in the end returns a mocked Cluster that in turn returns a mocked Session...

Can't commit JPA transaction - RollbackException: Transaction marked as rollbackOnly

first I want to say that I have seen all the topics here on stackoverflow for my case but wasn't able to solve my problem anyway.
I need to run scheduled task every night to check weather the task was finished or not - I'm doing like this:
#Service
#Transactional
public class CronBackGroundProcess {
#Autowired
private CronJobService cronJobService;
#Scheduled(cron = "15 01 01 ? * *")
public void StartNightJob() {
CronJobLog log = new CronJobLog();
int count = 0;
try {
log.setStartTime(new Date());
log.setStatus("Entered StartNightJob Function");
cronJobService.saveCronJobLog(log);
List<Task> Tasks = cronJobService.getActive_AND_InArreasTasks();
log.setStatus("Grabbed List of tasks to Check");
cronJobService.saveCronJobLog(log);
for (Task Task : Tasks) {
cronJobService.StartNightJobProcess(Task, true);
count++;
}
} catch (Exception e) {
CronJobLog log2 = new CronJobLog();
log2.setStatus("Error Occurred " + new Date().toString() + e.getMessage());
cronJobService.saveCronJobLog(log2);
}
log.setLoansChecked(count);
log.setStatus("Finished");
log.setEndDate(new Date());
cronJobService.saveCronJobLog(log);
}
}
CronJobService itself is #Transactional and autowires several #Transactional services
#Service
#Transactional
public class CronJobService {
#Autowired
private ProductService productService;
#Autowired
private RepaymentService repaymentService;
#Autowired
private CronJobLogDAO cronJobLogDAO;
#Autowired
private TransferService transferService;
public String StartNightJobProcess(Account account, boolean makeTransfers) {
do something....
}
}
}
the process goes without errors and when all transactions must be committed I receive such error:
org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Transaction marked as rollbackOnly
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:524) ~[spring-orm-4.0.0.RELEASE.jar:4.0.0.RELEASE]
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:757) ~[spring-tx-4.0.0.RELEASE.jar:4.0.0.RELEASE]
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:726) ~[spring-tx-4.0.0.RELEASE.jar:4.0.0.RELEASE]
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:478) ~[spring-tx-4.0.0.RELEASE.jar:4.0.0.RELEASE]
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:272) ~[spring-tx-4.0.0.RELEASE.jar:4.0.0.RELEASE]
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95) ~[spring-tx-4.0.0.RELEASE.jar:4.0.0.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.0.0.RELEASE.jar:4.0.0.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:646) ~[spring-aop-4.0.0.RELEASE.jar:4.0.0.RELEASE]
at ge.shemo.services.core.CronBackGroundProcess$$EnhancerByCGLIB$$30cdcf31.StartNightJob(<generated>) ~[spring-core-4.0.0.RELEASE.jar:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0_79]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[na:1.7.0_79]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.7.0_79]
at java.lang.reflect.Method.invoke(Method.java:606) ~[na:1.7.0_79]
at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:65) ~[spring-context-4.0.0.RELEASE.jar:4.0.0.RELEASE]
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) ~[spring-context-4.0.0.RELEASE.jar:4.0.0.RELEASE]
at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:81) [spring-context-4.0.0.RELEASE.jar:4.0.0.RELEASE]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) [na:1.7.0_79]
at java.util.concurrent.FutureTask.run(FutureTask.java:262) [na:1.7.0_79]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:178) [na:1.7.0_79]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:292) [na:1.7.0_79]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [na:1.7.0_79]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [na:1.7.0_79]
at java.lang.Thread.run(Thread.java:745) [na:1.7.0_79]
Caused by: javax.persistence.RollbackException: Transaction marked as rollbackOnly
at org.hibernate.jpa.internal.TransactionImpl.commit(TransactionImpl.java:58) ~[hibernate-entitymanager-5.0.1.Final.jar:5.0.1.Final]
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:515) ~[spring-orm-4.0.0.RELEASE.jar:4.0.0.RELEASE]
... 22 common frames omitted
I can't figure out why.
Also If I launch same function from #Controller it works fine
#Controller
#RequestMapping("/test")
public class test {
#Autowired
private ClientService clientService;
#Autowired
private CronBackGroundProcess cronBackGroundProcess;
#RequestMapping(value = "/test")
#ResponseBody
public void test() throws Exception {
try {
cronBackGroundProcess.StartNightJob();
} catch (Exception e) {
String s = "sd";
}
}
}
So my question is why this function works from controller - commits everything as expected and not works from scheduled task(goes through all process without errors)?
If you can then, put a debug break-point in org.springframework.transaction.interceptor.TransactionAspectSupport.completeTra‌​nsactionAfterThrowing(TransactionInfo txInfo, Throwable ex) and then see what the actual exception is.
You not need mark CronBackGroundProcess as #Transactional because in StartNightJob() method you not have access to db all access to DB as I guess you execute in CronJobService.
So remove #Transactional from CronBackGroundProcess and it must help.

Categories

Resources