mulesoft-labs / mule-gradle-plugin

Plugin for building mule apps with the gradle build system.
Apache License 2.0
24 stars 14 forks source link

Data Mapper plugins in unit tests #46

Closed sohrab- closed 9 years ago

sohrab- commented 9 years ago

Unit test initialisation of flows with Data Mapper fail with the following stacktrace:

...
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#187a06b6': Invocation of init method failed; nested exception is java.lang.RuntimeException: java.lang.NullPointerException
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1513)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:521)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:276)
    ... 110 more
Caused by: java.lang.RuntimeException: java.lang.NullPointerException
    at com.mulesoft.mule.module.datamapper.DataMapperModule.initialise(DataMapperModule.java:83)
    at com.mulesoft.mule.module.datamapper.processors.DataMapperMessageProcessor.initialise(DataMapperMessageProcessor.java:109)
    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.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeCustomInitMethod(AbstractAutowireCapableBeanFactory.java:1639)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1580)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1510)
    ... 113 more
Caused by: java.lang.NullPointerException
    at com.mulesoft.mule.module.datamapper.clover.impl.CloverEngineManager.initPlugins(CloverEngineManager.java:47)
    at com.mulesoft.mule.module.datamapper.clover.impl.CloverEngineManager.<init>(CloverEngineManager.java:34)
    at com.mulesoft.mule.module.datamapper.clover.impl.CloverEngineManagerContainer.getCloverEngineManager(CloverEngineManagerContainer.java:24)
    at com.mulesoft.mule.module.datamapper.DataMapperModule.createGraphExecutorFactory(DataMapperModule.java:89)
    at com.mulesoft.mule.module.datamapper.DataMapperModule.initialise(DataMapperModule.java:76)
    ... 121 more

I think it is trying to scan all the plugins and it is failing. So I printed out what com.mulesoft.mule.module.datamapper.clover.CloverEngineConfig.createDefault().getCloverPluginDirPath() returns:

/C:/Workspace/example-project-v1/build/classes/test/clover-plugins;file:/C:/Users/dev/.gradle/caches/modules-2/files-2.1/com.cloveretl/cloveretl-engine/3.6.0/273b3419e51aabbf8abaefaf230e38c41c5056a/cloveretl-engine-3.6.0.zip!/clover-plugins;file:/C:/Users/dev/.gradle/caches/modules-2/files-2.1/com.mulesoft.muleesb.datamapper/mule-clover-plugins/3.6.0/793c76e22c392069ee451291fa74fc8f4056cbf5/mule-clover-plugins-3.6.0.zip!/clover-plugins

I think it is fine for the clover-plugins directory the Gradle plugin adds but then it tries to do that same for the JAR files and it dies (not implemented to handle archives).

The application runs and unit tests fine in the Studio which makes me think we have an issue with our Gradle test classpath.

getCloverPluginDirPath() returns the below when I run the unit test through Studio:

/C:/Tools/AnypointStudio/plugins/org.mule.tooling.server.3.6.0.ee_5.0.1.201501301628/mule/data-mapper/clover-plugins

There is a fair bit of conjecture here since Data Mapper source code is not on Support Portal but do you know if there is a way to exclude those JARs from Plugin directories through Gradle?

I am running version 1.1.1 of mule-gradle-plugin.

juancavallotti commented 9 years ago

@sohrab- There is a task that is in charge of unzipping clover plugins, that is called 'unpackClover'. https://github.com/mulesoft-labs/mule-gradle-plugin/blob/master/src/main/groovy/com/mulesoft/build/dependency/UnpackCloverTask.groovy that is supposed to unpack these jars in the first location: /C:/Workspace/example-project-v1/build/classes/test/clover-plugins actually this is as well how unit testing with datamapper work for maven.

Can you produce a sample app that reproduces the issue so I can review?

sohrab- commented 9 years ago

@juancavallotti yep, that is one of the directories that is scanned but it also tries to scan some JARs.

I made a very quick Mule app to demonstrate this issue:

https://drive.google.com/open?id=0BwqZuZm_yqVGNVBmbjYxV196NVU&authuser=0

Try running JUnit in Studio and it will pass but then try gradle test and you get the stacktrace above.

juancavallotti commented 9 years ago

@sohrab- ok, this looks to be a regression in datamapper, if you switch the version to 3.5.2, then your unit test will run. Can you please check if the issue is the same with a mavenized version of the same project? If so, a support ticket would need to be open, if not, we might be missing something.

sohrab- commented 9 years ago

@juancavallotti, I dropped it into a Maven project and unit test passes through both Studio and mvn clean test.

https://drive.google.com/open?id=0BwqZuZm_yqVGUE11NWtOdS1RVXM&authuser=0

As mentioned before, I think it is the test classpath that is causing the issue. It is including clover-plugins inside some JARs that are located in Gradle cache. We need to find a way to tell Gradle to not to do that.

juancavallotti commented 9 years ago

@sohrab- Yes, I did the same thing and got also those results. The test task has a classpath property that we should be able to configure manually before the tests are run, let's try and make sure that is actually the issue and we can work on a proper fix.

juancavallotti commented 9 years ago

@sohrab- Ok, I've taken a look at the code in datamapper, the part that is failing was indeed introduced in 3.6.0 and the failure it is produced because of a misconsideration on the code, what is trying to do is to list files over a java.io.File that does not represent a directory. (one of the entries on the classpath). We'll have to fix this on the plugin side.

sohrab- commented 9 years ago

Any ideas on what the fix would entail? Or a work-around I can drop into our code?

I don't have the background on this but I see you add those dependencies explicitly in MuleProjectDependenciesConfigurer so simply excluding them would not be a good idea.

juancavallotti commented 9 years ago

In this case, it might be a good Idea to use a separate configuration for defining the dependencies on clover plugins. So this configuration does not get included in the test classpath in the first place.

sohrab- commented 9 years ago

I think you still need to have clover-engine JAR on the test classpath, even though it is one of the JARs that is causing us issues.

...
Caused by: java.lang.NoClassDefFoundError: org/jetel/plugin/PluginLocation
    at com.mulesoft.mule.module.datamapper.clover.impl.CloverEngineManager.initPlugins(CloverEngineManager.java:48)
    at com.mulesoft.mule.module.datamapper.clover.impl.CloverEngineManager.<init>(CloverEngineManager.java:34)
    at com.mulesoft.mule.module.datamapper.clover.impl.CloverEngineManagerContainer.getCloverEngineManager(CloverEngineManagerContainer.java:24)
    at com.mulesoft.mule.module.datamapper.DataMapperModule.createGraphExecutorFactory(DataMapperModule.java:89)
    at com.mulesoft.mule.module.datamapper.DataMapperModule.initialise(DataMapperModule.java:76)
    ... 47 more
Caused by: java.lang.ClassNotFoundException: org.jetel.plugin.PluginLocation
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
    ... 52 more
juancavallotti commented 9 years ago

@sohrab- I have created a proposed fix on branch issue46, it is working on my end, can you please validate?

sohrab- commented 9 years ago

@juancavallotti - Looks good. Worked with the app from my earlier comment and it now passes unit tests through both gradle test and Studio.

I'll move us to the SNAPSHOT version till 1.2.0 is released. (Speaking of which, when do you think that would be?)

juancavallotti commented 9 years ago

@sohrab- Thanks for letting me know, I would need to add unit tests and merge it into the master branch. I'm planing on updating the studio plugin before releasing. It should not be long.