appassembler-maven-plugin JSW - How to set wrapper-java-mainclass - java-service-wrapper

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 ;)

Related

Picocontainer is not sharing data with step file,My tests are getting skipped

My problem is related to picocontainer,i am not able to figure out what I am doing wrong when executing the test runner I am unable to find any scenarios or steps.However when I execute my old file the tests runs correctly which doesnot have picocontainer reference.
My project contains following file
1) 1 Step definition
2) Feature File
2) Runner File
4) Test Context (Sharing state file,here I have mentioned webdriver and page object elements)
POM FIle
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.141.5</version>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-java</artifactId>
<version>4.8.0</version>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-junit</artifactId>
<version>4.8.0</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/io.cucumber/cucumber-jvm-deps -->
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-jvm-deps</artifactId>
<version>1.0.6</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-picocontainer</artifactId>
<version>4.8.0</version>
</dependency>
Feature File
Feature: Automated End2End Tests
Description: The Purpose of this feature is to test End 2 End integration.
Scenario:Customer place an order by purchasing an item from search
Given user is on Home page
When he search for "dress"
And choose to buy the item for first time
And moves to checkout from mini cart
And enter personal details on checkout page and place the order
Step Definition
package stepDefinitions;
import cucumber.TestContext;
import io.cucumber.java.en.Given;
import io.cucumber.java.en.When;
import pageObjects.HomePage;
public class HomePageSteps {
TestContext testContext;
HomePage homePage;
public HomePageSteps(TestContext context) {
this.testContext = context;
homePage = testContext.getPageObjectManager().getHomePage();
}
#Given("^user is on Home Page$")
public void user_is_on_Home_Page(){
homePage.navigateTo_HomePage();
}
#When("^he search for \"([^\"]*)\"$")
public void he_search_for(String product) {
homePage.perform_Search(product);
}
}
Runner File
package runners;
import org.junit.runner.RunWith;
import io.cucumber.junit.Cucumber;
import io.cucumber.junit.CucumberOptions;
//import cucumber.api.java.ObjectFactory;T
#RunWith(Cucumber.class)
#CucumberOptions(
// junit = "--step-notifications",
features = "src/test/resources/functionalTests",
glue= {"stepDefinitions"})
public class TestRunner {
}
Test Context
package cucumber;
import managers.PageObjectManager;
import managers.WebDriverManager;
public class TestContext {
private WebDriverManager webDriverManager;
private PageObjectManager pageObjectManager;
public TestContext(){
webDriverManager = new WebDriverManager();
pageObjectManager = new PageObjectManager(webDriverManager.getDriver());
}
public WebDriverManager getWebDriverManager() {
return webDriverManager;
}
public PageObjectManager getPageObjectManager() {
return pageObjectManager;
}
}

Can't take screenshot for Allure + BDD (Jbehave) (Thucydides)

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>

Aspectj and spring security aspects - order of advice execution

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").

Unable to get JIBX IBindingFactory based on binding file

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

ConfigurationSettings.AppSettings is empty, throws null exception

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();

Resources