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();
}
Related
I'm trying to do something that is quite impossible with Java, but maybe there's a solution.
The code below tries to pass a transactional object via RMI
public class FileRepositoryImpl extends UnicastRemoteObject
implements FileRepository {
#Override
public byte[] get(String appId, String filePath) throws RemoteException, NotBoundException {
Registry registry = LocateRegistry.getRegistry();
XodusRepository repository = (XodusRepository) registry.lookup(XodusRepository.class.getName());
final byte[][] bytes = {null};
repository.transact(appId, true, new Command<byte[]>() {
#Override public byte[] execute(jetbrains.exodus.entitystore.StoreTransaction txn) {
Entity entity = txn.findWithBlob(Constants.ENTITYSTORE_FILE, filePath).getLast();
if (entity != null) {
InputStream blobStream = entity.getBlob(filePath);
bytes[0] = Try.of(() -> ByteStreams.toByteArray(blobStream)).getOrNull();
}
return bytes[0];
}
});
return bytes[0];
}
}
However this code throws:
java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:
java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
java.lang.ClassNotFoundException: com.mycompany.backend.repository.FileRepositoryImpl$1 (no security manager: RMI class loader disabled)
at java.rmi/sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:391)
at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:200)
at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:197)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.rmi/sun.rmi.transport.Transport.serviceCall(Transport.java:196)
at java.rmi/sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:562)
at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:796)
at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:677)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:676)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:834)
at java.rmi/sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:283)
at java.rmi/sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:260)
at java.rmi/sun.rmi.server.UnicastRef.invoke(UnicastRef.java:161)
at java.rmi/java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:209)
at java.rmi/java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:161)
at com.sun.proxy.$Proxy57.transact(Unknown Source)
at com.mycompany.backend.repository.FileRepositoryImpl.get(FileRepositoryImpl.java:48)
at com.mycompany.backend.hosting.MyCompanyFileRepresentation.write(MyCompanyFileRepresentation.java:91)
On the other side, the other Java process it have:
#Override public <T> T transact(String appId, boolean isReadOnly, Command<T> command)
throws NotBoundException, RemoteException {
AtomicReference<T> result = null;
manager.transactPersistentEntityStore(xodusRoot, appId, isReadOnly, txn -> {
result.set(command.execute(txn));
});
return Try.of(() -> result.get()).getOrNull();
}
Is there a way to use transactional objects over RMI?
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
I'm having problems with using Guice's assisted inject within my spigot plugin, and can't seem to narrow down the problem. This is the error I'm getting:
> [12:00:38 INFO]: [DestinyMC] Enabling DestinyMC v1.0
> 2019-01-14 12:00:41,492 Log4j2-TF-1-AsyncLogger[AsyncContext#5c647e05]-1 ERROR An exception occurred processing Appender File com.google.common.util.concurrent.UncheckedExecutionException: java.lang.IllegalStateException: zip file closed
at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2217)
at com.google.common.cache.LocalCache.get(LocalCache.java:4154)
at com.google.common.cache.LocalCache.getOrLoad(LocalCache.java:4158)
at com.google.common.cache.LocalCache$LocalLoadingCache.get(LocalCache.java:5147)
at com.google.common.cache.LocalCache$LocalLoadingCache.getUnchecked(LocalCache.java:5153)
at com.google.inject.internal.util.StackTraceElements.forMember(StackTraceElements.java:71)
at com.google.inject.internal.Messages.formatSource(Messages.java:241)
at com.google.inject.internal.Messages.formatSource(Messages.java:220)
at com.google.inject.internal.Messages.formatMessages(Messages.java:90)
at com.google.inject.CreationException.getMessage(CreationException.java:50)
at org.apache.logging.log4j.core.impl.ThrowableProxy.<init>(ThrowableProxy.java:134)
at org.apache.logging.log4j.core.impl.ThrowableProxy.<init>(ThrowableProxy.java:122)
at org.apache.logging.log4j.core.async.RingBufferLogEvent.getThrownProxy(RingBufferLogEvent.java:330)
at org.apache.logging.log4j.core.pattern.ExtendedThrowablePatternConverter.format(ExtendedThrowablePatternConverter.java:61)
at org.apache.logging.log4j.core.pattern.PatternFormatter.format(PatternFormatter.java:38)
at org.apache.logging.log4j.core.layout.PatternLayout$PatternSelectorSerializer.toSerializable(PatternLayout.java:455)
at org.apache.logging.log4j.core.layout.PatternLayout.toText(PatternLayout.java:232)
at org.apache.logging.log4j.core.layout.PatternLayout.encode(PatternLayout.java:217)
at org.apache.logging.log4j.core.layout.PatternLayout.encode(PatternLayout.java:57)
at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.directEncodeEvent(AbstractOutputStreamAppender.java:177)
at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.tryAppend(AbstractOutputStreamAppender.java:170)
at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.append(AbstractOutputStreamAppender.java:161)
at org.apache.logging.log4j.core.appender.RollingRandomAccessFileAppender.append(RollingRandomAccessFileAppender.java:218)
at org.apache.logging.log4j.core.config.AppenderControl.tryCallAppender(AppenderControl.java:156)
at org.apache.logging.log4j.core.config.AppenderControl.callAppender0(AppenderControl.java:129)
at org.apache.logging.log4j.core.config.AppenderControl.callAppenderPreventRecursion(AppenderControl.java:120)
at org.apache.logging.log4j.core.config.AppenderControl.callAppender(AppenderControl.java:84)
at org.apache.logging.log4j.core.config.LoggerConfig.callAppenders(LoggerConfig.java:448)
at org.apache.logging.log4j.core.config.LoggerConfig.processLogEvent(LoggerConfig.java:433)
at org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:417)
at org.apache.logging.log4j.core.config.AwaitCompletionReliabilityStrategy.log(AwaitCompletionReliabilityStrategy.java:79)
at org.apache.logging.log4j.core.async.AsyncLogger.actualAsyncLog(AsyncLogger.java:337)
at org.apache.logging.log4j.core.async.RingBufferLogEvent.execute(RingBufferLogEvent.java:161)
at org.apache.logging.log4j.core.async.RingBufferLogEventHandler.onEvent(RingBufferLogEventHandler.java:45)
at org.apache.logging.log4j.core.async.RingBufferLogEventHandler.onEvent(RingBufferLogEventHandler.java:29)
at com.lmax.disruptor.BatchEventProcessor.processEvents(BatchEventProcessor.java:168)
at com.lmax.disruptor.BatchEventProcessor.run(BatchEventProcessor.java:125)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.IllegalStateException: zip file closed
at java.util.zip.ZipFile.ensureOpen(Unknown Source)
at java.util.zip.ZipFile.getEntry(Unknown Source)
at java.util.jar.JarFile.getEntry(Unknown Source)
at java.util.jar.JarFile.getJarEntry(Unknown Source)
at org.bukkit.plugin.java.PluginClassLoader.findClass(PluginClassLoader.java:120)
at org.bukkit.plugin.java.PluginClassLoader.findClass(PluginClassLoader.java:104)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at com.google.inject.internal.util.StackTraceElements$1.load(StackTraceElements.java:49)
at com.google.inject.internal.util.StackTraceElements$1.load(StackTraceElements.java:45)
at com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3716)
at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2424)
at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2298)
at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2211)
... 39 more
This is my Binder Class:
public class MainBinder extends AbstractModule {
#Override
protected void configure() {
bind(DestinyMC.class).toInstance(this.plugin);
install(new FactoryModuleBuilder().build(InventoryFromFileFactory.class));
}
The error goes away when I comment out the install line. That line uses this factory class
public interface InventoryFromFileFactory {
InventoryFromFile create(String targetRootKey, String targetFile);
}
which declare the parameters that need to be manually provided at object creation for this class:
public class InventoryFromFile {
#Inject
public InventoryFromFile
(
#Assisted String targetRootKey,
#Assisted String targetFile,
ConfigAccessorFactory configAccessorFactory
)
{
ConfigurationSection targetCS = configAccessorFactory.create(targetFile).getCustomConfig().getConfigurationSection(targetRootKey);
...
}
}
The ConfigAccessFactory is another factory class for assisted inject
public interface ConfigAccessorFactory {
ConfigAccessor create(String filename);
}
which is used here:
public class ConfigAccessor {
private Plugin plugin;
private final String customFileName;
#Inject
public ConfigAccessor
(
#Assisted String fileName,
DestinyMC plugin
)
{
this.customFileName = fileName;
this.plugin = plugin;
}
...
}
Finally, the DestinyMC dependency is the main class for the spigot plugin:
public class DestinyMC extends JavaPlugin {
//Inject dependencies
#Inject private ConfigAccessorFactory configAccessorFactory;
//Code only run once when the plugin is enabled
public void onEnable() {
MainBinder mainBinder = new MainBinder(this);
Injector injector = Guice.createInjector(mainBinder);
injector.injectMembers(this);
//Saves config files to disk if they don't exist
saveDefaultConfig();
Arrays.asList(
"inventory-gui.yml",
"player-tree-template.yml",
"player-tree-data.yml"
).forEach((file) -> {
configAccessorFactory.create(file).saveDefaultConfig();
});
...
}
I'm not too sure what I'm doing wrong, but I'm fairly new to Guice so I'm most likely misunderstanding something. Also, if there's simply a better way to do this, let me know. Thanks for the help.
I am trying to write a junit using mockito api for a final class and using #PostConstruct annotaion. Below is the sample code which I have written so far.
public final class ConfigCache {
private static final MultiKeyMap configCache = new MultiKeyMap();
#Autowired
private ConfigDao dao;
#PostConstruct
public void init() {
Map<String, Collection<Configuration>> map = null;
try {
if (configurationCache != null || configurationCache.isEmpty()) {
map = dao.loadConfigurations();
map.forEach((k, v) -> {
v.forEach((c) -> {
configCache.put(k, c.getAttributeName(), c.getAttributeValue());
});
});
}
} catch (DaoException e) {
throw new RuntimeException(e);
}
}
public Object getValue(String k1, String k2) {
return configurationCache.get(k1, k2);
}
#PreDestroy
public void clearCache() {
if (configCache != null) {
configCache.clear();
}
}
}
Junit which I have so far is
#RunWith(SpringRunner.class)
#SpringBootTest(classes = {ConfigCache.class})
public class ConfigCacheTest {
#InjectMocks
private ConfigCache configCache;
#MockBean
private ConfigDao dao;
private Map<String,Collection<Configuration>> map;
#Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}
#After
public void tearDown() {
}
#Test
public void testInit() throws DaoException {
map = new HashMap<String,Collection<Configuration>>();
List<Configuration> configurations = new ArrayList<Configuration>();
Configuration configuration = new Configuration();
configuration.setAttributeName("a");
configuration.setAttributeValue("20");
configurations.add(configuration);
configuration = new Configuration();
configuration.setAttributeName("b");
configuration.setAttributeValue("10");
configurations.add(configuration);
map.put("abc", configurations);
when(dao.loadConfigurations()).thenReturn(map);
assertEquals("ConfigurationCacheBuilder.init()",configurationCacheBuilder.getConfigurationcache().size(),1);
}
}
When I run this, I get an error
java.lang.ExceptionInInitializerError
at org.mockito.internal.exceptions.stacktrace.ConditionalStackTraceFilter.<init>(ConditionalStackTraceFilter.java:17)
at org.mockito.exceptions.base.MockitoException.filterStackTrace(MockitoException.java:41)
at org.mockito.exceptions.base.MockitoException.<init>(MockitoException.java:30)
at org.mockito.exceptions.misusing.MockitoConfigurationException.<init>(MockitoConfigurationException.java:18)
at org.mockito.internal.configuration.plugins.PluginLoader.loadImpl(PluginLoader.java:66)
at org.mockito.internal.configuration.plugins.PluginLoader.loadPlugin(PluginLoader.java:24)
at org.mockito.internal.configuration.plugins.PluginRegistry.<init>(PluginRegistry.java:12)
at org.mockito.internal.configuration.plugins.Plugins.<clinit>(Plugins.java:11)
at org.mockito.internal.util.MockUtil.<clinit>(MockUtil.java:24)
at org.springframework.boot.test.mock.mockito.MockReset.<clinit>(MockReset.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 java.lang.Class.getEnumConstantsShared(Class.java:3320)
at java.lang.Class.enumConstantDirectory(Class.java:3341)
at java.lang.Enum.valueOf(Enum.java:232)
at sun.reflect.annotation.AnnotationParser.parseEnumValue(AnnotationParser.java:483)
at sun.reflect.annotation.AnnotationParser.parseMemberValue(AnnotationParser.java:347)
at java.lang.reflect.Method.getDefaultValue(Method.java:606)
at sun.reflect.annotation.AnnotationType.<init>(AnnotationType.java:128)
at sun.reflect.annotation.AnnotationType.getInstance(AnnotationType.java:85)
at sun.reflect.annotation.AnnotationParser.parseAnnotation2(AnnotationParser.java:266)
at sun.reflect.annotation.AnnotationParser.parseAnnotations2(AnnotationParser.java:120)
at sun.reflect.annotation.AnnotationParser.parseAnnotations(AnnotationParser.java:72)
at java.lang.reflect.Field.declaredAnnotations(Field.java:1150)
at java.lang.reflect.Field.declaredAnnotations(Field.java:1148)
at java.lang.reflect.Field.getDeclaredAnnotations(Field.java:1139)
at java.lang.reflect.AccessibleObject.getAnnotations(AccessibleObject.java:207)
at org.junit.runners.model.FrameworkField.getAnnotations(FrameworkField.java:31)
at org.junit.runners.model.TestClass.addToAnnotationLists(TestClass.java:84)
at org.junit.runners.model.TestClass.scanAnnotatedMembers(TestClass.java:71)
at org.junit.runners.model.TestClass.<init>(TestClass.java:57)
at org.junit.runners.ParentRunner.createTestClass(ParentRunner.java:88)
at org.junit.runners.ParentRunner.<init>(ParentRunner.java:83)
at org.junit.runners.BlockJUnit4ClassRunner.<init>(BlockJUnit4ClassRunner.java:65)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.<init>(SpringJUnit4ClassRunner.java:138)
at org.springframework.test.context.junit4.SpringRunner.<init>(SpringRunner.java:49)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.junit.internal.builders.AnnotatedBuilder.buildRunner(AnnotatedBuilder.java:104)
at org.junit.internal.builders.AnnotatedBuilder.runnerForClass(AnnotatedBuilder.java:86)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:26)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:33)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createUnfilteredTest(JUnit4TestLoader.java:84)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createTest(JUnit4TestLoader.java:70)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.loadTests(JUnit4TestLoader.java:43)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:444)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: java.lang.NullPointerException
at org.mockito.internal.configuration.plugins.Plugins.getStackTraceCleanerProvider(Plugins.java:17)
at org.mockito.internal.exceptions.stacktrace.StackTraceFilter.<clinit>(StackTraceFilter.java:21)
... 55 more
I tried with 2 versions of mockito
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>2.0.2-beta</version>
</dependency>
and
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.5.5</version>
can someone let me know what might be going wrong ?
One way you can solve this is by creating a package level setter for dao variable.
void setConfigDao(ConfigDao configDao) {
dao = configDao;
}
And then, avoid to use #InjectMocks in class ConfigCacheTest and initialize your configCache object in setUp() method.
#Before
public void setUp() {
MockitoAnnotations.initMocks(this);
configCache = new ConfigCache();
configCache.setConfigDao(dao);
configCache.init();
}
This way, you can avoid this NPE when #PostConstruct init() method is called before mockito injects dao object.
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.completeTransactionAfterThrowing(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.