I have my custom maven plugin, which has to run tests programmatically on a test phase for example. So I have something like that
#Mojo(name = "aggregate", requiresDependencyResolution = ResolutionScope.RUNTIME)
public class AcceptanceTestMojo extends AbstractMojo {
#Override
public void execute() throws MojoExecutionException, MojoFailureException {
TestExecutor testExecutor = new TestExecutor();
testExecutor.setTestClasses(new Class[]{TestClass.class});
testExecutor.run();
}
}
So the problem comes because the TestClass.class is from another maven module and actually the resources which I want to get are loaded in that module classpath. In that TestClass I have the following method:
public Object[][] retrieveFile() throws IOException {
String[] issuesKeys = IOUtils.toString(
Thread.currentThread().getContextClassLoader().getResourceAsStream("fileName"))
.split("\\n");
....
....
}
If I build the module where the TestClass belongs to everything is working fine, because Thread.currentThread().getContextClassLoader() is loading the correct ClassLoader, but if run it with my plugin as I run the test programatically Thread.currentThread().getContextClassLoader() is loading the classpath of my plugin, so the file I want to retrive is not there and a RuntimeException is thrown.
So my question is how to get the correct ClassLoader so that to be able to get the file or is there a way to load files in classpath manually with java?
I found one solution- I modified the currentThread ClassLoader- I got all required classes from the classpath of the maven project I am executing the plugin on. This is possible with injecting the MavenProject bean:
#Component
private MavenProject project;
Related
Hi I am working on a Maven project having dependency on a external jar which has a class ConfigLoader having following loader() method.
public class ConfigLoader {
public void initialize() {
loader();
}
private static void loader() {
URL configURL = ConfigLoader.getClass().getResource("runtimeConfiguration.xml");
//some other method calls to which configURL is an argument.
}
//other methods of ConfigLoader class
}
and the directory structure is like this -
src
|...main
|.......java
|.......resources
|................dev
|................prod
both dev and prod have a file named runtimeConfiguration.xml
and the code which uses this class is
public class Application {
private Application application;
public static void main(String []args){
application = new Application();
application.invokeConfigLoader();
//additional code
}
private void invokeConfigLoader() {
configLoader.initialize();
}
}
The error I get is
could not find: runtimeConfiguration.xml
and the exception is thrown at the getResource() line in the class from jar.
I have tried adding the dev folder to classpath but still the same error. I want to run this code from linux terminal, and the command I am giving from trunk directory (where all my exernal jars and resource folder sits after maven build) is -
java -cp /resources/dev/*:configuration-loader.jar
I am using intelliJ 2017.2 and also tried to add the resources/dev folder as module dependency, but I keep on getting the same error. The resources folder is added as a library via project structure settings. I tried to search a lot but have not found any question with this issue. Kindly help me out as I am new to this environment based development.
Thanks!
ConfigLoader.getClass().getResource("runtimeConfiguration.xml"); will try to get runtimeConfiguration.xml from the same package a the ConfigLoader is defined and not from the root of classpath. Try appending / to runtimeConfiguration.xml.
This should work ConfigLoader.getClass().getResource("/runtimeConfiguration.xml"); or ConfigLoader.getClass().getResource("/dev/runtimeConfiguration.xml"); depending how you are adding resources to your classpath.
See javadoc for more.
We have a multimodule Maven project and intend on performing tests on this. Because our tests are very homogenous, instead of writing the same test over and over, we wrote a parameterised test, which fetches all the files which stand to test and runs its tests against them. Now we want this as a maven plugin so you could just do something like mvn xquerytestrunner:test
I created a separate project, created a Java File in there and annotated it with
#Mojo( name = "xquerytester")
public class XQueryTestRunner extends AbstractMojo {
#Parameter( property = "xquerytester.querytotest", defaultValue = "" )
private static String queryToTest;
public void execute() throws MojoExecutionException, MojoFailureException {
JUnitCore junit = new JUnitCore();
Result result = junit.run(ParameterizedGenericXQueryTest.class);
}
}
Now my question. Will this run? And does it make sense?
My other option was to just have the test in the src/test/java folder of the main module and run it with mvn -Dtest=TestCircle test but the problem is that we use a plugin by Oracle ( oracle-soa-plugin ) that messes up everything around the project but we have to use it.
Our main pom.xml has <packaging>pom</packaging> which is why running the above test goal doesnt work. it just doesnt build or test anything. If i change it to jar the plugin throws errors during build. and I cannot skip build phase because the plugin just does its stuff anyways.
My goal is just to have a one liner for the console that runs my parameterized tests. It just seems Oracle didnt read the howtos on how to write a maven plugin and now i have to work with it.
Update 1:
We now went with a maven plugin. This can be run independent of the oracle soa plugin and also on a mvn project that has a "pom" packagint type.
The Mojo Class:
#Mojo( name = "xsl")
public class XslTestRunner {
#Parameter( property = "xsl.name", defaultValue = "" )
private static String name;
public void execute() throws MojoExecutionException, MojoFailureException {
JUnitCore junit = new JUnitCore();
Result result = junit.run(ParameterizedGenericXslTest.class);
PrintHelper.printResults(result, TransformationTestType.XQUERY);
}
}
The Maven Plugin Pom:
In general I followed these instructions: Your First Plugin
I'm writing a Maven plugin whose job is to delegate to a core module who needs to read files from the project classpath (i.e. the project declaring the plugin as a plugin dependency).
However, from what I understand, Maven plugin comes with its own classpath, thus leading all my Class#getResourceAsStream in my core module calls to returning null.
Is there a way to include the project classpath elements in the plugin one?
OK, the issue was due to a leading slash. Once removed, the following code retrieves the MavenProject instance (you need to add maven-artifact and maven-project to your POM):
public static ClassLoader getClassLoader(MavenProject project) throws DependencyResolutionRequiredException, MalformedURLException {
List<String> classPathElements = compileClassPathElements(project);
List<URL> classpathElementUrls = new ArrayList<>(classPathElements.size());
for (String classPathElement : classPathElements) {
classpathElementUrls.add(new File(classPathElement).toURI().toURL());
}
return new URLClassLoader(
classpathElementUrls.toArray(new URL[classpathElementUrls.size()]),
Thread.currentThread().getContextClassLoader()
);
}
private static List<String> compileClassPathElements(MavenProject project) throws DependencyResolutionRequiredException {
return newArrayList(project.getCompileClasspathElements());
}
I have created a jUnit test class within Eclipse for Mac OS. I was successfully able to create the class and run the code generated by Eclipse, but when I try to add another class I need into the file I get NoClassDefFound.
It seems to be complaining about XmlPullParser, which is used in one of the methods I added:
#Test(expected= Exception.class) public void testParseNull() throws XmlPullParserException, IOException
{
EntryParser parser = new EntryParser();
parser.parse(null);
}
I saw this post but I don't think it is related.
Here is my build path:
I am trying to get gwt-test-utils to work. I set up the project in the following way:
src/main/java : all the java source code
src/test/java : the test source code
src/test/resources : resource files for the tests
I am building my project with gradle and eclipse. Gradle uses these directories correctly by default and I added all three of them as source directories to Eclipse.
I have successfully built and run the project and was able to execute some plain old JUnit tests as well as a GWTTestCase, so I think I set up the project and its dependencies correctly.
Now I wanted to use gwt-test-utils for some more advanced integration tests. To do so I did the following:
Add the gwt-test-utils and gwt-test-utils-csv to my dependencies
gwtTestUtilsVersion = '0.45'
testCompile group:'com.googlecode.gwt-test-utils', name:'gwt-test-utils', version:gwtTestUtilsVersion
testCompile group:'com.googlecode.gwt-test-utils', name:'gwt-test-utils-csv', version:gwtTestUtilsVersion
Add a gwt-test-utils.properties file to the directory src/test/resources/META-INF with the following content:
path/to/my/module = gwt-module
Added a class that extends GwtCsvTest to a package in the src/test/java directory. It is modeled after the second example in HowToWriteCsvScenario from the gwt-test-utils project wiki, replacing occurrence of their example classes with mine. It looks like this
#CsvDirectory(value = "gwtTests")
public class LoginLogoutTest extends GwtCsvTest
{
#Mock
private MainServiceAsync mainService;
private AppController appController = new AppController();
#CsvMethod
public void initApp()
{
appController.onModuleLoad();
}
#Before
public void setup()
{
GwtFinder.registerNodeFinder("myApp", new NodeObjectFinder()
{
#Override
public Object find(Node node)
{
return csvRunner.getNodeValue(appController, node);
}
});
GwtFinder.registerNodeFinder("loginView", new NodeObjectFinder()
{
#Override
public Object find(Node node)
{
return csvRunner.getNodeValue(appController.getRootPresenter().getCurrentlyActiveSubPresenters().iterator().next().getView(), node);
}
});
addGwtCreateHandler(createRemoteServiceCreateHandler());
}
}
added a csv-file for configuring the test to src/test/resources/gwtTests with the following content
start
initApp
assertExist;/loginView/emailTextBox
I tried executing it via the Eclipse's Run As > JUnit Test and indirectly via gradle build (which executes all the test cases, not just this one). Both lead to the same error:
ERROR GwtTreeLogger Unable to find type 'myPackage.client.AppController'
ERROR GwtTreeLogger Hint: Check that the type name 'myPackage.client.AppController' is really what you meant
ERROR GwtTreeLogger Hint: Check that your classpath includes all required source roots
The AppController class is the entry-point configured in the module I configured in gwt-test-utils.properties, which makes me think that configuration works correctly and the rest of the setup (dependencies and all) work as well.
In an earlier version I used the same file as a subclass of GWTTestCase and created an AppController instance in the same way. That worked, so I'm pretty sure the class path is setup correctly to include it as well. I also tried changing it back to the previous version just now and it still works.
I have no clue why the class is not found. Is there anything gwt-test-utils does differently which means I need to specifically set the class path for it? Otherwise it should just work, since both gradle and eclipse know about all the relevant source folders and dependencies.