I use Eclipse with Maven (m2eclipse plugin) and JIBX to (un)marshall XML.
It works if I use the factory like this:
IBindingFactory bindingFactory = BindingDirectory.getFactory(mappedClass);
However I want to create a factory based on the binding file, because this is done by the automatically generated service stub. So I run the following test in TestNG:
#Test
public void testBindingFactory() {
try
{
IBindingFactory factory = BindingDirectory.getFactory("binding", "");
} catch (JiBXException e)
{
e.printStackTrace();
fail(e.getMessage());
}
}
and it fails with the following error message:
Unable to access binding 'binding'
Make sure classes generated by the binding compiler are available at runtime
java.lang.ClassNotFoundException: .JiBX_bindingFactory
The name (filename is binding.xml) is correct, the empty "" means no package, which is also correct, but could be a problem I guess?
The factory is generated under target/classes/JiBX_bindingFactory.class in my project folder, so it should be found! (Remember everything works if I specify a concrete toplevel binded class)
Any help would be appreciated!
The build section in my pom.xml file:
<build>
<plugins>
<plugin>
<groupId>org.jibx</groupId>
<artifactId>jibx-maven-plugin</artifactId>
<version>1.2.5</version>
<configuration>
<schemaBindingDirectory>src/main/config</schemaBindingDirectory>
<includeSchemaBindings>
<includeSchemaBinding>binding.xml</includeSchemaBinding>
</includeSchemaBindings>
<verbose>true</verbose>
</configuration>
<executions>
<execution>
<goals>
<!-- Do we require other goals? http://jibx.sourceforge.net/maven-jibx-plugin/ -->
<goal>bind</goal>
<!-- goal>test-bind</goal-->
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Found the solution, its a bug in the implemention of getFactory(java.lang.String bname, java.lang.String pack, java.lang.ClassLoader loader)!
Consider the first lines of code:
public static IBindingFactory [More ...] getFactory(String bname, String pack,
ClassLoader loader) throws JiBXException {
String cname = (pack == null ? "" : pack + '.') +
GENERATE_PREFIX + convertName(bname) + BINDINGFACTORY_SUFFIX;
...
Remember that the auto-generated service stub called the getFactory method like this: factory = org.jibx.runtime.BindingDirectory.getFactory("binding", "",
ISService_1_0_deStub.class.getClassLoader());
So the empty quotes are replaced with ".", which leads to the Exception: java.lang.ClassNotFoundException: .JiBX_bindingFactory as said (note the dot before the class name!).
The solution is to call the method like this: factory = org.jibx.runtime.BindingDirectory.getFactory("binding", (String)null,
ISService_1_0_deStub.class.getClassLoader());
Note the cast to String, otherwise the call is ambiguous!
Sidenote: The method getFactory(String, String) calls the method getFactory(String, String, ClassLoader) in BindingDirectory
Related
Hello everyone.
There is a ready project using BDD (Jbehave) (Thucydides)
There was a need to connect the Allure report to the project.
For this purpose, AllureReporter was taken from here
allure-jbehave-reporter
The reports are working, everything is fine.
But there is one big problem, the tests are started with the help of RemoteWebDriver on the Selenium Hub.
We need screenshots to understand what the problem is, and what happens there.
At the moment, screenshots are not taken by Allure.
That is, no screenshots are taken from the screen and are not attached.
Tried:
#Attachment(value = "Page screenshot", type = "image/png")
public byte[] saveScreenshot(byte[] screenShot) {
return screenShot;
}
and
public static byte[] takeScreenshot() {
WebDriver driver = ThucydidesWebDriverSupport.getDriver();
if (WebDriverFactory.isAlive(driver) && (driver instanceof TakesScreenshot)) {
return ((TakesScreenshot) driver).getScreenshotAs(OutputType.BYTES);
}
return null;
}
and
Allure.addAttachment()
That all not working for me.
This way works, takes screen shots from the screen and adds their specified folder, BUT! they are not attached to the report.
#Attachment(value = "Page screenshot", type = "image/png")
public byte[] saveScreenAsImage() throws IOException {
WebDriver driver = ThucydidesWebDriverSupport.getDriver();
File file = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(file, new File("target/allure-results/" + file.getName()));
return Files.toByteArray(file);
}
Any ideas how this can be solved?
Thanks in advance.
Here is POM
<dependency>
<groupId>io.qameta.allure</groupId>
<artifactId>allure-java-commons</artifactId>
<version>2.6.0</version>
</dependency>
<dependency>
<groupId>io.qameta.allure</groupId>
<artifactId>allure-generator</artifactId>
<version>2.5.0</version>
</dependency>
<plugin>
<groupId>io.qameta.allure</groupId>
<artifactId>allure-maven</artifactId>
<version>2.9</version>
<configuration>
<reportVersion>2.6.0</reportVersion>
<allureDownloadUrl>https://dl.bintray.com/qameta/generic/io/qameta/allure/allure/2.6.0/allure-2.6.0.zip</allureDownloadUrl>
</configuration>
<executions>
<execution>
<id>allure-report</id>
<phase>post-integration-test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
I have a Maven plugin that I am attempting to test using a subclass of the AbstractMojoTestCase. The plugin Mojo defines an outputFolder parameter with a defaultValue. This parameter is not generally expected to be provided by the user in the POM.
#Parameter(defaultValue = "${project.build.directory}/someOutputFolder")
private File outputFolder;
And if I use the plugin in a real scenario then the outputFolder gets defaulted as expected.
But if I test the Mojo using the AbstractMojoTestCase then while parameters defined in the test POM are populated, parameters with a defaultValue that are not defined in the POM are not populated.
public class MyPluginTestCase extends AbstractMojoTestCase {
public void testAssembly() throws Exception {
final File pom = getTestFile( "src/test/resources/test-pom.xml");
assertNotNull(pom);
assertTrue(pom.exists());
final MyMojo myMojo = (BaselineAssemblyMojo) lookupMojo("assemble", pom);
assertNotNull(myMojo);
myMojo.execute(); // Dies due to NullPointerException on outputFolder.
}
}
Further: if I define the outputFolder parameter in the POM like so:
<outputFolder>${project.build.directory}/someOutputFolder</outputFolder>
then ${project.build.directory} is NOT resolved within the AbstractMojoTestCase.
So what do I need to do to get the defaultvalue populated when testing?
Or is this a fault in the AbstractMojoTestCase?
This is Maven-3.2.3, maven-plugin-plugin-3.2, JDK 8
You need to use lookupConfiguredMojo.
Here's what I ended up using:
public class MyPluginTest
{
#Rule
public MojoRule mojoRule = new MojoRule();
#Test
public void noSource() throws Exception
{
// Just give the location, where the pom.xml is located
MyPlugin plugin = (MyPlugin) mojoRule.lookupConfiguredMojo(getResourcesFile("basic-test"), "myGoal");
plugin.execute();
assertThat(plugin.getSomeInformation()).isEmpty();
}
public File getResourcesFile(String filename)
{
return new File("src/test/resources", filename);
}
}
Of course you need to replace myGoal with your plugin's goal. You also need to figure out how to assert that your plugin executed successfully.
For a more complete example, check out the tests I wrote for fmt-maven-plugin
I'm using spring-security 3.2.4.RELEASE , spring-security-aspects 3.2.4.RELEASE, AspectJ maven plugin version 1.6, Java 7.
I using AspectJ's weaving and not SpringAOP, therefore my aspectj maven plugin looks like this:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
<configuration>
<Xlint>ignore</Xlint>
<showWeaveInfo>true</showWeaveInfo>
<source>${java.version}</source>
<target>${java.version}</target>
<complianceLevel>${org.aspectj-version}</complianceLevel>
<aspectLibraries>
<aspectLibrary>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-aspects</artifactId>
</aspectLibrary>
</aspectLibraries>
</plugin>
I have another aspect that looks like this:
package com.mycompany.fw.app.config;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.DeclarePrecedence;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.security.core.parameters.DefaultSecurityParameterNameDiscoverer;
import com.mycompany.fw.security.Integration;
#Aspect
#DeclarePrecedence("IntegrationAspects*,*")
public class IntegrationAspects {
ParameterNameDiscoverer parameterNameDiscoverer = new DefaultSecurityParameterNameDiscoverer();
#Pointcut("(execution(* com.mycompany..*(..))) && #annotation(integrate) ")
public void integratePointCut(Integration integrate) {
}
/**
* TODO: cache
*
* #param jp
* #param integrate
* #throws Throwable
*/
#Around("integratePointCut(integrate)")
public Object integrate(final ProceedingJoinPoint pjp, Integration integrate) throws Throwable {
Object res = pjp.proceed();
return res;
}
}
What I need is to put the above (integration aspect) to be the first before any other aspect (including Spring's security aspect)
As you can see I tried it with #DeclarePrecedence (I also tried it with declare precedence : IntegrationAspects*,* as well in an .aj file), unfortunately, without success.
Can someone instruct me how to define the aspects invocation order?
The problem is that you do not use the plain aspect name IntegrationAspects in #DeclarePrecedence, but a joker character *. In this case you need to use a fully qualified class name or jokers creating same.
Does not work:
#DeclarePrecedence("IntegrationAspects*, *")
Works:
#DeclarePrecedence("IntegrationAspects, *")
#DeclarePrecedence("com.mycompany.fw.security.Integration.IntegrationAspects, *")
#DeclarePrecedence("com.mycompany.fw.security.Integration.IntegrationAspects*, *")
#DeclarePrecedence("*..IntegrationAspects*, *")
And so forth. By the way, using upper-case package names and plurals in class names looks really ugly.
I am an AspectJ expert, not a Spring user, so I cannot tell you if declaring precedence will also affect Spring-provided aspects. It might also depend on whether they are implemented using native AspectJ or Spring-AOP (proxy-based "AOP lite").
i try to use the appassembler-maven-plugin to ease the use of the Java-Service-Wrapper
My Setup is as follows:
implemented a class MyServiceWrapper which extends WrapperListner from JSW to have full access to the start/stop/controlEvent-methods
added the appassembler-maven-plugin to my pom.xml and configured JSW
MyServiceWrapper:
package aaa.bbb.ccc;
import org.tanukisoftware.wrapper.WrapperListener;
import org.tanukisoftware.wrapper.WrapperManager;
public class MyServiceWrapper implements WrapperListener {
#Override
public void controlEvent(int arg0) {
}
#Override
public Integer start(String[] arg0) {
return null;
}
#Override
public int stop(int exitCode) {
return exitCode;
}
public static void main(String[] args) {
WrapperManager.start(new MyServiceWrapper(), args);
}
}
appassembler-maven-plugin in my pom.xml:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>appassembler-maven-plugin</artifactId>
<version>1.3.1</version>
<executions>
<execution>
<id>generate-jsw-scripts</id>
<phase>package</phase>
<goals>
<goal>generate-daemons</goal>
</goals>
<configuration>
<!--declare the JSW config -->
<daemons>
<daemon>
<id>MyServiceWrapper</id>
<mainClass>aaa.bbb.ccc.MyServiceWrapper</mainClass>
<platforms>
<platform>jsw</platform>
</platforms>
</daemon>
</daemons>
<target>${project.build.directory}/appassembler</target>
</configuration>
</execution>
</executions>
</plugin>
This generates the wrapper.conf and a lot of other files! But there is one line which is wrong and i don't know how to generate it correctly.
The wrong line is:
wrapper.java.mainclass=org.tanukisoftware.wrapper.WrapperSimpleApp
and it should be:
wrapper.java.mainclass=aaa.bbb.ccc.MyServiceWrapper
If i manually set this line to the correct mentioned line it works!
So: is there any way to generate this line correctly?
PS:
Is it possible to set the log-level of the JSW from inside the pom.xml?
appassembler is by default using integration method #1, where the (i.e. your) 'main class' is actually the first parameter to the WrapperSimpleApp class. That's why your mainclass is getting mapped to wrapper.app.parameter.1, and not wrapper.java.mainclass...
In most cases you don't need to generate your own implementation of WrapperListener interface and sticking to integration method#1 will be working most of the time....
If you really want to use integration method#3, i.e. provide your own WrapperListener implementation, you have to add the following into your pom.xml:
<property>
<name>wrapper.java.mainclass</name>
<value>my.WrapperListenerImpl</value>
</property>
<property>
<name>wrapper.logfile.loglevel</name>
<value>DEBUG</value>
</property>
Full example can be found >here<
This will add or overwrite existing configuration properties... you can use that also for the loglevel ;)
I have a class like this:
public class RxNormFolderMgr
{
// properties
public string RxNormFolder { get { return ConfigurationSettings.AppSettings["rootFolder"].ToString(); } }
}
When I try to use it like this:
public class TestRxNormFolderManager : ColumnFixture
{
public string RxNormFolder()
{
RxNormFolderMgr folderMgr = new RxNormFolderMgr();
return folderMgr.RxNormFolder;
}
}
I get an error: "System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.NullReferenceException: Object reference not set to an instance of an object." The AllKeys property for AppSettings is an array of zero length where I am expecting length of 1.
My app.config file in the project looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="rootFolder" value ="C:\RxNorm" />
<!-- Root folder must not end with slash. -->
</appSettings>
</configuration>
I know ConfigurationSettings.AppSettings is supposed to be obsolete and I should use ConfigurationManager.AppSettings, but I can't even get that to compile. I do have a reference in the project to System.configuration (c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\System.configuration.dll on my machine) and using statement at top of my code.
I am using Fitnesse to test the code, and that's when I get the error. It's my understanding that I should also place a copy of the app.config file in the Bin>Debug folder of the test fixtures project which I have done. So, I don't know why I'm getting this error still.
Please, help.
Also: try using the ConfigurationManager class instead of "ConfigurationSettings":
Use a check for NOT NULL first:
public class RxNormFolderMgr
{
// properties
public string RxNormFolder
{
get
{
if(ConfigurationManager.AppSettings["rootFolder"] != null)
{
return ConfigurationManager.AppSettings["rootFolder"].ToString();
}
return string.Empty;
}
}
}
Is this inside a class library assembly? Those never use their own app.config - but instead the use the host app's app.config (the app that uses the class library).
Marc
When you are testing with FitNesse, the actual executable running is "FitServer.exe" so AppSettings is looking for a "FitServer.exe.config" in the directory with FitServer.exe lives. So a quick and dirty solution is to copy your app.config there and rename it.
A better solution is to specify the app config as described here:
http://www.syterra.com/FitnesseDotNet/ApplicationConfigurationFile.html
or if you're using fitSharp (which is an enhancement of FitNesse.NET):
http://www.syterra.com/Fit/AppConfigFiles.html
Do not put it in appsettings. Use <connectionStrings>
example:
<appSettings/>
<connectionStrings>
<add name="NORTHWNDConnectionString" connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\NORTHWND.MDF;Integrated Security=True;User Instance=True" providerName="System.Data.SqlClient"/>
</connectionStrings>
string cnstr = ConfigurationManager.ConnectionStrings["NORTHWNDConnectionString"].ToString();