How to mock a Java component within Mule Flow using MUnit - java

I am trying to Unit test one of my sub-flows using MUnit, I need to mock out a custom Java component but I am unable to do so.
My sub-flow reads as below
<sub-flow name="ProcessCSVFlow" tracking:enable-default-events="true">
<transformer ref="enrichWithHeaderAndEndOfFileTransformer" doc:name="headerAndEOFEnricher" />
<set-variable variableName="outputfilename" value="#['Mercury'+server.dateTime.year+server.dateTime.month+server.dateTime.dayOfMonth+server.dateTime.hours +server.dateTime.minutes+server.dateTime.seconds+'.csv']" doc:name="outputfilename"/>
<sftp:outbound-endpoint exchange-pattern="one-way" connector-ref="DestinationSFTP" host="${destination.host}" port="22" responseTimeout="10000" doc:name="DestinationSFTP"
outputPattern="#[outputfilename]" path="${destination.path}" user="${destination.username}" password="${destination.password}"/>
<!-- <component class="nz.co.mightyriver.creditreport.component.ArchiveOutputComponent" doc:name="Archive"/> -->
<gzip-compress-transformer/>
<sftp:outbound-endpoint exchange-pattern="one-way" connector-ref="InputSFTP" host="${source.host}" port="22" responseTimeout="10000" doc:name="SourceArchiveSFTP"
outputPattern="#[outputfilename].gzip" path="Archive" user="${source.username}" password="${source.password}"/>
<component doc:name="Delete Read File">
<singleton-object class="nz.co.mightyriver.creditreport.component.DeleteProcessedFileComponent">
<property key="host" value="${source.host}"/>
<property key="username" value="${source.username}"/>
<property key="password" value="${source.password}"/>
<property key="workingDirectory" value="${source.path}"/>
</singleton-object>
</component>
<parse-template location="successmessagetemplate.txt" doc:name="Success Template"/>
<smtp:outbound-endpoint host="${smtp.host}" port="${smtp.port}" user="${smtp.from.address}" password="${smtp.from.password}"
to="${smtp.to.address}" from="${smtp.from.address}" subject="${mail.success.subject}" responseTimeout="10000"
doc:name="SuccessEmail" connector-ref="Gmail"/>
<logger message="Process completed successfully" level="INFO" doc:name="Logger"/>
</sub-flow>
This is my failing unit test
#Test
public void givenAValidPayload_whenFlowIsInvoked_itShouldSendPayloadToDestinationSFTPOnlyOnce() throws Exception {
destinationSFTP.thenReturnSameEvent();
sourceArchiveSFTP.thenReturnSameEvent();
deleteProcessedFileComponent.thenReturnSameEvent();
successEmail.thenReturnSameEvent();
MuleEvent testEvent = PropertyEnricher.enrich(testEvent(IOUtils.toInputStream("hello,dummy,payload"))).get();
runFlow(PROCESS_CSV_FLOW, testEvent);
verifyCallOfMessageProcessor("outbound-endpoint")
.ofNamespace("sftp")
.withAttributes(attribute("name").ofNamespace("doc").withValue("DestinationSFTP"))
.times(1);
}
My attempt at mocking out the component
deleteProcessedFileComponent = whenMessageProcessor("component")
.withAttributes(attribute("name").ofNamespace("doc").withValue("Delete Read File"));
I have tried a few variations and none have worked, I am guessing a component is not a MessageProcessor
The exception I get is as follows
org.mule.api.lifecycle.InitialisationException: Component has not been initialized properly, no flow constuct.
at org.mule.component.AbstractComponent.initialise(AbstractComponent.java:218)
at org.mule.processor.chain.AbstractMessageProcessorChain.initialise(AbstractMessageProcessorChain.java:80)
at org.mule.processor.chain.AbstractMessageProcessorChain$$FastClassByCGLIB$$38c17d88.invoke(<generated>)
at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:191)
at org.mule.munit.common.mp.WrapperMunitMessageProcessorInterceptor.invokeSuper(WrapperMunitMessageProcessorInterceptor.java:71)
at org.mule.munit.common.mp.WrapperMunitMessageProcessorInterceptor.invokeSuper(WrapperMunitMessageProcessorInterceptor.java:63)
at org.mule.munit.common.mp.WrapperMunitMessageProcessorInterceptor.intercept(WrapperMunitMessageProcessorInterceptor.java:49)
at org.mule.processor.chain.SubflowInterceptingChainLifecycleWrapper$$EnhancerByMUNIT$$c8ca2508.initialise(<generated>)
at org.mule.munit.runner.functional.FunctionalMunitSuite.initialiseSubFlow(FunctionalMunitSuite.java:269)
at org.mule.munit.runner.functional.FunctionalMunitSuite.runFlow(FunctionalMunitSuite.java:259)
at nz.co.mightyriver.ProcessCsvTest.givenAValidPayload_whenFlowIsInvoked_itShouldSendPayloadToDestinationSFTPOnlyOnce(ProcessCsvTest.java:62)
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.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:69)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:48)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.ParentRunner.run(ParentRunner.java:292)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

So there is no problem with your mock it actually work perfectly.
The problem is with Mule and a little bit with MUnit.
Short answer, there is no fix for that right now.
There is a workaround though!
Create a new xml (as to keep it separate from your production code)
Add flow (not a sub-flow) to that new xml.
In the flow you just added do a flow-ref to your sub-flow.
From you test, instead of doing runFlow(PROCESS_CSV_FLOW), do runFlow("the_flow_you_created").
The longer answer is:
The sub-flows are not real flows, they don't even share a parent class. Thus they behave a little bit different. MUnit does some stuff to make that fact transparent to the user.
As it turns out we are not making enough, I'll create a jira in the MUnit project to tackle that issue. But hopefully you should be able to keep testing.

Related

Java EclipseLink Persistence JPQL Operator: TruncateDate

I have seen several answers and documentation on how to use operators, but cannot get this to work. I want to know where I can find use case on TruncateDate OPERATOR. I have looked at the following and they are not helpful:
http://www.eclipse.org/eclipselink/api/2.5/org/eclipse/persistence/expressions/Expression.html#truncateDate(java.lang.String)
https://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Querying/JPQL#Functions
What I need is just a simple query that works with the TruncateDate operator. Here is my query:
#NamedQueries({
#NamedQuery(name="SprMessage.findPendingMessageIds",
query="SELECT s.messageId "
+ "FROM SprMessage s "
+ "WHERE s.inOrOut = 'INBOUND'"
+ "AND s.messageStatus = 'RECEIVED'"
+ "OR (s.messageStatus = 'RETRY' AND s.lastUpdateDate < OPERATOR('TruncateDate', :todayIn)) "
+ "ORDER BY s.createdDate ASC")
})
If I replace OPERATOR('TruncateDate', :todayIn) with :todayIn it works. Is this even possible with a parameter? My issue is I do not want to check seconds and minutes, etc. Just down to the day.
Thank you in advance for any help on the matter.
Additional information on my JPA version:
compile (group: 'org.eclipse.persistence', name: 'eclipselink', version: '2.5.1')
compile (group: 'org.eclipse.persistence', name: 'javax.persistence', version: '2.1.0', ext: 'jar')
I could do this in code with JODA time but I would really like to see this work in JPA for the sake of IT.
Due to a comment about database system, this is being run against an Oracle 11g database, as well as a Derby database for the JUnits which are failing.
Here is the error I am getting running:
Local Exception Stack:
Exception [EclipseLink-6047] (Eclipse Persistence Services - 2.5.1.v20130918-f2b9fc5): org.eclipse.persistence.exceptions.QueryException
Exception Description: Invalid operator [platform operator - TruncateDate] in expression.
Query: ReportQuery(name="SprMessage.findPendingMessageIds" referenceClass=SprMessage jpql="SELECT s.messageId FROM SprMessage s WHERE s.inOrOut = 'INBOUND'AND s.messageStatus = 'RECEIVED'OR (s.messageStatus = 'RETRY' AND s.lastUpdateDate < OPERATOR('TruncateDate', :todayIn, 'dd')) ORDER BY s.createdDate ASC")
at org.eclipse.persistence.exceptions.QueryException.invalidOperator(QueryException.java:664)
at org.eclipse.persistence.internal.expressions.FunctionExpression.initializePlatformOperator(FunctionExpression.java:330)
at org.eclipse.persistence.internal.expressions.FunctionExpression.getPlatformOperator(FunctionExpression.java:307)
at org.eclipse.persistence.internal.expressions.FunctionExpression.printSQL(FunctionExpression.java:544)
at org.eclipse.persistence.expressions.ExpressionOperator.printDuo(ExpressionOperator.java:2239)
at org.eclipse.persistence.internal.expressions.CompoundExpression.printSQL(CompoundExpression.java:286)
at org.eclipse.persistence.internal.expressions.RelationExpression.printSQL(RelationExpression.java:872)
at org.eclipse.persistence.expressions.ExpressionOperator.printDuo(ExpressionOperator.java:2239)
at org.eclipse.persistence.internal.expressions.CompoundExpression.printSQL(CompoundExpression.java:286)
at org.eclipse.persistence.expressions.ExpressionOperator.printDuo(ExpressionOperator.java:2239)
at org.eclipse.persistence.internal.expressions.CompoundExpression.printSQL(CompoundExpression.java:286)
at org.eclipse.persistence.internal.expressions.ExpressionSQLPrinter.translateExpression(ExpressionSQLPrinter.java:306)
at org.eclipse.persistence.internal.expressions.ExpressionSQLPrinter.printExpression(ExpressionSQLPrinter.java:129)
at org.eclipse.persistence.internal.expressions.SQLSelectStatement.printSQL(SQLSelectStatement.java:1683)
at org.eclipse.persistence.platform.database.DerbyPlatform.printSQLSelectStatement(DerbyPlatform.java:373)
at org.eclipse.persistence.internal.expressions.SQLSelectStatement.buildCall(SQLSelectStatement.java:782)
at org.eclipse.persistence.internal.expressions.SQLSelectStatement.buildCall(SQLSelectStatement.java:792)
at org.eclipse.persistence.descriptors.ClassDescriptor.buildCallFromStatement(ClassDescriptor.java:813)
at org.eclipse.persistence.internal.queries.StatementQueryMechanism.setCallFromStatement(StatementQueryMechanism.java:390)
at org.eclipse.persistence.internal.queries.ExpressionQueryMechanism.prepareReportQuerySelectAllRows(ExpressionQueryMechanism.java:1696)
at org.eclipse.persistence.queries.ReportQuery.prepareSelectAllRows(ReportQuery.java:1203)
at org.eclipse.persistence.queries.ReadAllQuery.prepare(ReadAllQuery.java:744)
at org.eclipse.persistence.queries.ReportQuery.prepare(ReportQuery.java:1071)
at org.eclipse.persistence.queries.DatabaseQuery.checkPrepare(DatabaseQuery.java:661)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.checkPrepare(ObjectLevelReadQuery.java:901)
at org.eclipse.persistence.queries.DatabaseQuery.checkPrepare(DatabaseQuery.java:613)
at org.eclipse.persistence.internal.jpa.QueryImpl.getDatabaseQueryInternal(QueryImpl.java:341)
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.createNamedQuery(EntityManagerImpl.java:1124)
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.createNamedQuery(EntityManagerImpl.java:1144)
at com.paychex.corp.app2app.iatosfdc.WarTransactionsHandler.getPendingMessageIds(WarTransactionsHandler.java:102)
at com.paychex.corp.app2app.iatosfdc.WarTransactionsHandlerTest.testGetPendingMessageBatchGetsMessagesById(WarTransactionsHandlerTest.java:102)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:30)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

org.dbunit.dataset.NoSuchTableException: localized_values

I am trying to using spring test dbunit.
https://springtestdbunit.github.io/spring-test-dbunit/
As I am using spring 4.1.x I decided to use version 1.2.1 for spring-test-dbunit and 2.5.2 for core dbunit.
Originally I used plain dbunit and it worked fine. Then I decided to try spring-test-dbunit and I got several problems.
Here is my test class
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(value = {
"classpath:path/to/test/context/sql-context.xml"})
#TransactionConfiguration(defaultRollback = true)
#Transactional
#TestExecutionListeners({ DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class,
TransactionalTestExecutionListener.class, DbUnitTestExecutionListener.class })
#DbUnitConfiguration(databaseConnection = "databaseConnection")
#DatabaseSetup("classpath:path/to/dataset/questionRepositoryTestDS.xml")
public class QuestionRepositoryDbUnitTest {
....
#Autowired
private QuestionRepository repository;
#Test
public void mustReturnQuestion() throws Exception {
....
assertEquals("Result is not the same as expected!", expected,
repository.findQuestion(QUESTION_ID_1, PRODUCT_CONFIGURATION_ID_1, LANGUAGE));
}
My dataset file looks like this
<?xml version="1.0" encoding="UTF-8"?>
<dataset>
<question question_id='q_mail' display_type='EMAIL' display_group='2' organization_uid='123' display_order='1'/>
<question question_id='q_copies' display_type='NUMBER' display_group='1' organization_uid='123' display_order='1'/>
<localized_question question_id='q_mail' language='EN' organization_uid='*' display_label='What is your email?'/>
<localized_question question_id='q_mail' language='EN' organization_uid='123' display_label='Enter the mailbox'/>
<localized_question question_id='q_copies' language='EN' organization_uid='*' display_label='How many copies you are planning to create?'/>
<localized_values question_select_value_id='a_mail1' language='EN' organization_uid='*' display_label='common#email.com'/>
<localized_values question_select_value_id='a_mail1' language='EN' organization_uid='123' display_label='custom#email.com'/>
<localized_values question_select_value_id='a_mail2' language='EN' organization_uid='*' display_label='null#email.com'/>
</dataset>
Database connection bean looks like this
<bean id="databaseConnection"
class="com.github.springtestdbunit.bean.DatabaseDataSourceConnectionFactoryBean">
<property name="schema" value="mySchema"/>
<property name="dataSource" ref="customDataSource"/>
</bean>
where dataSource bean is
<bean id="customDataSource"
class="com.custom.db.embedded.EmbeddedH2DatabaseFactory">
<property name="resourcesFromPaths">
<list value-type="java.lang.String">
<value>#{systemProperties['test-changelog']}</value>
</list>
</property>
<property name="url" value="jdbc:h2:mem:product.pricing;MVCC=TRUE"/>
<property name="createCommonTablesOnStartup" value="false"/>
</bean>
But when I try to run test I get this error
org.dbunit.dataset.NoSuchTableException: localized_values
at org.dbunit.database.DatabaseDataSet.getTableMetaData(DatabaseDataSet.java:305)
at org.dbunit.operation.DeleteAllOperation.execute(DeleteAllOperation.java:109)
at org.dbunit.operation.CompositeOperation.execute(CompositeOperation.java:79)
at com.github.springtestdbunit.DbUnitRunner.setupOrTeardown(DbUnitRunner.java:194)
at com.github.springtestdbunit.DbUnitRunner.beforeTestMethod(DbUnitRunner.java:66)
at com.github.springtestdbunit.DbUnitTestExecutionListener.beforeTestMethod(DbUnitTestExecutionListener.java:186)
at org.springframework.test.context.TestContextManager.beforeTestMethod(TestContextManager.java:249)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:70)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:224)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:83)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:163)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.runTestClass(JUnitTestClassExecuter.java:86)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.execute(JUnitTestClassExecuter.java:49)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassProcessor.processTestClass(JUnitTestClassProcessor.java:64)
at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:50)
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.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.messaging.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32)
at org.gradle.messaging.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
at com.sun.proxy.$Proxy2.processTestClass(Unknown Source)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:106)
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.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.messaging.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:360)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:54)
at org.gradle.internal.concurrent.StoppableExecutorImpl$1.run(StoppableExecutorImpl.java:40)
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)
What is the problem?
Also when I used plain dbunit I had to set autoCommit in order to make it work
databaseConnection = new DatabaseConnection(h2databaseResource.getConnection(), DATABASE_SCHEMA);
databaseConnection.getConnection().setAutoCommit(true);
(though I thought that autoCommit supposed to be true by default)
I know that this is a late answer but I think your issue is that you haven't created your schema correctly. I see that you are using a custom data source factory and I would recommend you switch over to using a more standardized DB initialization, like putting this in your test XML configuration:
<jdbc:initialize-database data-source="dataSource">
<jdbc:script location="classpath:com/foo/sql/db-schema.sql"/>
</jdbc:initialize-database>
Or declaring a test #Configuration class:
#Configuration
public class TestDbConfig {
#Value("classpath:com/foo/sql/db-schema.sql")
private Resource schemaScript;
#Bean
public DataSourceInitializer dataSourceInitializer(final DataSource dataSource) {
final DataSourceInitializer initializer = new DataSourceInitializer();
initializer.setDataSource(dataSource);
initializer.setDatabasePopulator(databasePopulator());
return initializer;
}
private DatabasePopulator databasePopulator() {
final ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
populator.addScript(schemaScript);
return populator;
}
}

Test Method fails with Log Error

I've written a test Method. In this project I use Morphia for MongoDB. But when I start the Method I get the follow Error:
java.lang.NoSuchMethodError: org.apache.log4j.Logger.log(Ljava/lang/String;Lorg/apache/log4j/Level;Ljava/lang/Object;Ljava/lang/Throwable;)V
at org.slf4j.impl.Log4jLoggerAdapter.info(Log4jLoggerAdapter.java:166)
at com.mongodb.diagnostics.logging.SLF4JLogger.info(SLF4JLogger.java:71)
at com.mongodb.connection.SingleServerCluster.<init>(SingleServerCluster.java:45)
at com.mongodb.connection.DefaultClusterFactory.create(DefaultClusterFactory.java:85)
at com.mongodb.Mongo.createCluster(Mongo.java:670)
at com.mongodb.Mongo.createCluster(Mongo.java:656)
at com.mongodb.Mongo.<init>(Mongo.java:278)
at com.mongodb.Mongo.<init>(Mongo.java:274)
at com.mongodb.MongoClient.<init>(MongoClient.java:174)
at com.mongodb.MongoClient.<init>(MongoClient.java:151)
at com.mongodb.MongoClient.<init>(MongoClient.java:141)
at de.meinTellerchen.utils.mongoDB.connection.MongoDBCon.<init>(MongoDBCon.java:65)
at de.meinTellerchen.ingredient.service.IngredientRestService.dataBaseConnection(IngredientRestService.java:34)
at de.meinTellerchen.ingredient.service.IngredientRestService.<init>(IngredientRestService.java:22)
at de.meinTellerchen.ingredient.service.IngredientRestServiceTest.test001_WriteIngredient(IngredientRestServiceTest.java:21)
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.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
The Method in this Test creates an Object and saves it in a MongoDB with Morphia.
#Test
public void test001_WriteIngredient() {
Ingredient ingredient = generateIngredient();
IngredientRestService ingredientRestService = new IngredientRestService();
assertNotNull(ingredient);
Response response = ingredientRestService.writeIngredient(ingredient);
assertNotNull(response);
}
I don't know why it doesn't work. I don't use Logger.
The issue is with the version of log4j and slf4j.
Add below mentioned jars in your classpath :
log4j
slf4j-simple
jcl-over-slf4j
slf4j-api
slf4j-log4j12 with appropriate versions
or use maven to handle your dependencies.
Example of Compatible versions of jars:
1) log4j-1.2.15.jar
2) slf4j-api-1.7.7.jar
3) commons-logging-1.0.4.jar
4) logback-classic-1.0.0.jar
5) logback-core-1.0.0.jar
The dependent jar of slf4j is missing in your classpath.
Please open the mongodriver jar available in your system and see the meta-inf/MANIFEST.MF file and add the required jars mentioned in Import-Package:section.
Example:
Mongodb java driver 3.2.1 requires following dependent jars.
Import-Package: javax.xml.bind,javax.crypto,javax.crypto.spec,javax.ma
nagement,javax.net,javax.net.ssl,javax.security.sasl,javax.security.a
uth.callback,org.ietf.jgss,io.netty.bootstrap;resolution:=optional;ve
rsion="[4.0,5)",io.netty.buffer;resolution:=optional;version="[4.0,5)
",io.netty.channel;resolution:=optional;version="[4.0,5)",io.netty.ch
annel.nio;resolution:=optional;version="[4.0,5)",io.netty.channel.soc
ket;resolution:=optional;version="[4.0,5)",io.netty.channel.socket.ni
o;resolution:=optional;version="[4.0,5)",io.netty.handler.ssl;resolut
ion:=optional;version="[4.0,5)",io.netty.handler.timeout;resolution:=
optional;version="[4.0,5)",io.netty.util.concurrent;resolution:=optio
nal;version="[4.0,5)",org.slf4j;resolution:=optional;version="[1.7,2)
"

Spring MVC Java-based configuration can't see class-path properties file

I'm trying to migrate my web-app from XML-based configuration to Java-based one. I have properties files under "\src\main\resources\" directory. In XML configuration I had such bean:
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:test.properties</value>
</list>
</property>
</bean>
And it worked just fine.
Now I switched to Java config so I have:
#Configuration
#ComponentScan(basePackages = {"blah.blah.blah.*"})
#Import({MVCConfig.class, PersistenceConfig.class, SecurityConfig.class})
#PropertySource("classpath:test.properties")
public class TestConfig {
}
But unfortunately I'm getting exception:
java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContext(CacheAwareContextLoaderDelegate.java:99)
at org.springframework.test.context.DefaultTestContext.getApplicationContext(DefaultTestContext.java:101)
at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:155)
at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:100)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:319)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:212)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:289)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:291)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:232)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:89)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:175)
at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:264)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:153)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:124)
at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:200)
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:153)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:103)
Caused by: org.springframework.beans.factory.BeanInitializationException: Could not load properties; nested exception is java.io.FileNotFoundException: class path resource [classpath:WEB-INF/test.properties] cannot be opened because it does not exist
at org.springframework.beans.factory.config.PropertyResourceConfigurer.postProcessBeanFactory(PropertyResourceConfigurer.java:89)
...
I've tried to use #PropertySource("classpath*:test.properties"), then exception changes to:
Caused by:
org.springframework.beans.factory.BeanDefinitionStoreException: Failed
to load bean class: blah.blah.blah.TestConfig; nested
exception is java.io.FileNotFoundException: class path resource
[classpath*:test.properties] cannot be opened because it does not
exist ...
Leading slash also doesn't help...
My test class starts as follows:
#RunWith(SpringJUnit4ClassRunner.class)
#WebAppConfiguration
#ContextConfiguration(classes = TestConfig.class, loader = AnnotationConfigContextLoader.class)
public class IntegrationTests {
What am I doing wrong?
My bad: I also had #Bean of type org.springframework.beans.factory.config.PropertyPlaceholderConfigurer and it conflicted somehow with #PropertySource annotation. Removing this been fixed things up.

SAXParseException: Element type "CountryNamecode" must be followed by either attribute specifications, ">" or "/>"

OK, this seems like a common error message, but I've looked at this from a few angles, and I'm stumped.
My XML (complete file is huge, so limiting to area that seems related unless somebody can tell me how/why I need more here):
<?xml version="1.0" encoding="utf-8"?>
<MyXML date="201112102200" type="daily">
<CountryList>
<CountryName code="AARCT" name="Antarctica" IsTerritory="True"/>
<CountryName code="ABKHAZ" name="Abkhazia" IsTerritory="True"/>
<!-- ... -->
<CountryName code="VCAN" name="Vatican City" IsTerritory="False" ProfileURL="vatican city.doc"/>
<CountryName code="VEN" name="Venezuela" IsTerritory="False" ProfileURL="venezuela.doc"/>
<CountryName code="VI" name="US Virgin Islands" IsTerritory="True"/>
<CountryName code="VIETN" name="Vietnam" IsTerritory="False" ProfileURL="vietnam.doc"/>
<CountryName code="WALLIS" name="Wallis and Futuna Islands" IsTerritory="True"/>
<CountryName code="WSOMOA" name="Samoa" IsTerritory="False" ProfileURL="samoa.doc"/>
<CountryName code="YEMAR" name="Yemen" IsTerritory="False" ProfileURL="yemen.doc"/>
<CountryName code="YUG" name="Serbia" IsTerritory="False" ProfileURL="serbia.doc"/>
<CountryName code="ZAIRE" name="Democratic Republic of the Congo" IsTerritory="False" ProfileURL="democratic republic of the congo.doc"/>
<CountryName code="ZAMBIA" name="Zambia" IsTerritory="False" ProfileURL="zambia.doc"/>
<CountryName code="ZIMBAB" name="Zimbabwe" IsTerritory="False" ProfileURL="zimbabwe.doc"/>
</CountryList>
<!-- ... -->
</MyXML>
So the error is:
org.xml.sax.SAXParseException: Element type "CountryNamecode" must be followed by either attribute specifications, ">" or "/>".
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1231)
at com.foo.bar.Baz.<init>(Baz.java:38)
at com.foo.bar.BazTest.testRecordCounts(BazTest.java:69)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
The logging I have indicated it's failing after country code "VI", and that there's something wrong with the "VIETN" entry.
So, there doesn't appear to be a malformed element called "CountryNamecode", I've checked for dodgy characters, but it's all pretty vanilla character-wise. The whole file validates when I've checked it, using STS, Oxygen, and xmllint.
Any help on this would be greatly appreciated.
Cheers folks!
EDIT:
XMLReader xmlReader = XMLReaderFactory.createXMLReader();
xmlReader.setContentHandler(this);
xmlReader.setErrorHandler(this);
xmlReader.parse(new InputSource(new StringReader(retriever.getContent())));
The retriever object is returning the xml string, and other than that, I'm parsing an InputSource, passing it the StringReader. Unless there's something obvious I'm missing
I'd be prepared to bet the issue is in the underlying data stream code.
To support my theory, open the original data file, move the cursor to the space between CountryName and code and find a way of determining the exact offset of that space character in the file. It is likely to be an exact multiple of 1024 and probably 4096 or 8192.
Then look at the InputSource or Reader code you are using to feed the SAX parser. It will probably look something like:
sax = factory.newSAXParser();
try {
// Here I am using an InputSource wrapping a StringReader.
sax.parse(new InputSource(new StringReader(xml)), this);
} catch (SAXException ex) {
log.warning("XMLParser failed on: "+xml, ex);
}
I suspect whatever you are using instead of the new InputSource(new StringReader(xml)) I use above is what is corrupting the data.

Categories