Can anyone please guide me on how to use Arquillian with WildFly 10. I have recently migrated my application from JBoss 7 to WildFly 10. Arquillian used to work with JBoss 7, but the same configuration is not working on WildFly 10.
I am able to integrate now, however my EJBs with JNDI names as "java:global/xyz/xyzEMFactor" is failing with following error:
Caused by: java.lang.Exception: {"WFLYCTL0180: Services with missing/unavailable dependencies" => ["jboss.naming.context.java.module.test.test.env.\"com.xyz.abc.poc.knowledge_base.ontology.DBContextBean\".emFactory is missing [jboss.naming.context.java.global.xyz_dal.xyzpEMFactory]"]} at org.jboss.as.controller.client.helpers.standalone.impl.ServerDeploymentPlanResultFuture.getActionResult(ServerDeploymentPlanResultFuture.java:134)
Following is my class:
#AccessTimeout(5 * 60 * 60 * 1000)
#StatefulTimeout(-1)
#TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public class DBContextBean<T> {
#Inject
#EJB(lookup = "java:global/xyz_dal/xyzEMFactory")
private xyzEMFactory emFactory;
}
It was because, The testable war file, i was creating a jar as,
#Deployment(name = "xyz_dal", order = 3)
public static Archive<?> createDeployment() {
JavaArchive jar = ShrinkWrap.create(JavaArchive .class, "xyz_dal.jar")
.addClasses(xyzEMFactory.class, DBContextBean.class, xyzDao.class)
.addPackages(true, "com.xyz.abc.poc.entities")
.addAsResource("test-persistence.xml", "META-INF/persistence.xml")
.addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml").setManifest(new Asset() {
#Override
public InputStream openStream() {
// dependency management
return ManifestBuilder.newInstance()
.addManifestHeader("Dependencies", "xyz,javax.api,deployment.abc_common.jar")
.openStream();
}
});
return jar;
}
It worked when i changed it to
#Deployment(name = "xyz_dal", order = 3)
public static Archive<?> createDeployment() {
WebArchive jar = ShrinkWrap.create(WebArchive.class, "xyz_dal.war")
.addClasses(xyzpEMFactory.class, DBContextBean.class, xyzDao.class)
.addPackages(true, "com.xyz.abc.poc.entities")
.addAsResource("test-persistence.xml", "META-INF/persistence.xml")
.addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml").setManifest(new Asset() {
#Override
public InputStream openStream() {
// dependency management
return ManifestBuilder.newInstance()
.addManifestHeader("Dependencies", "xyz,javax.api,deployment.abc_common.jar")
.openStream();
}
});
return jar;
}
It was because when i was creating a testable jar,the container wraps the jar in a test.war, and hence the context "java:global/xyz/xyzEMFactory" was not available.
I don't know how this could work in JBoss7 but: either #EJB or #Inject, I presume #Inject, is superfluous. In my experience wildfly is sometimes more rigorous than jboss7 when looking at unclear constructs.
#Inject
#EJB(lookup = "java:global/xyz_dal/xyzEMFactory")
xyzEMFactory emFactory;
CDI can't inject ejbs. What we do sometimes is:
#Produces
#EJB(lookup = "java:global/xyz/xyzEMFactory")
xyzEMFactory emFactory;
Then you can use at other places
#Inject
xyzEMFactory emFactory;
because the ejb-injected bean can be used as Producer-Field.
Related
I have a seam 2.2.2 aplication which I'm migrating to jboss eap 6 (AS7).
As the tests were in the old jboss embedded container, so I started to use arquillian but I could not discover hot to create a deployment package.
This is one of my attempts:
#Deployment
#OverProtocol("Servlet 3.0")
public static Archive<?> createDeployment() throws IOException {
// Build the ear with Maven by hand before run the test!
final EnterpriseArchive ear = ShrinkWrap.createFromZipFile(
EnterpriseArchive.class, new File("../Sin-ear/target/Sin.ear"));
final JavaArchive testjar = ShrinkWrap.createFromZipFile(
JavaArchive.class, new File("./target/test.jar"));
//final JavaArchive testjar = ShrinkWrap.create(JavaArchive.class, "test.jar") //other attempt
// .addPackages(true, "com.miles.knowledge.test");
ear.addAsModule(testjar);
return ear;
}
And it fails when I run the test class as JUnit test (I can see the aplication deployment with no errors):
java.lang.ClassNotFoundException: com.miles.knowledge.test.GreeterTest from [Module "deployment.Sin.ear.Sin.war:main" from Service Module Loader]
at org.jboss.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:213)
...
It seems that I have to package the test class into a war package, but I'm kind of lost, I need some help.
This kind of deployment should work (note adding the test class to the war)...
#RunWith(Arquillian.class)
public class JsfTest extends org.jboss.seam.mock.JUnitSeamTest{
#Deployment(name="UserLoginTest")
#OverProtocol("Servlet 3.0")
public static Archive<?> createDeployment(){
EnterpriseArchive er = Deployments.webAppDeployment();
WebArchive web = er.getAsType(WebArchive.class, "WebApp-web.war");
er.addAsModule(Testable.archiveToTest(web));
web.addClasses(JsfTest.class)
.addAsResource(EmptyAsset.INSTANCE, "seam.properties")
.delete("/WEB-INF/web.xml");
web.addAsWebInfResource("mock-web.xml", "web.xml");
return er;
}
}
public class Deployments {
public static EnterpriseArchive webAppDeployment() {
return ShrinkWrap.create(ZipImporter.class, "WebApp.ear")
.importFrom(new File("../WebApp-ear/target/WebApp.ear"))
.as(EnterpriseArchive.class);
}
}
Setup: arquillian, jboss as 7.1.1.final as a managed Container
I am currently migrating an EJB application from EJB 2.x to 3.x and JBoss 3.x to JBoss AS 7.1.
During this process i would like to get most classes under test and stumbled over arquillian.
While arquillian seems to offer some nice features on inter-bean-functionality i cannot figure out whether or not the testing of remote client features using jndi lookups works or not.
I used the Arquillian Getting started guides on my beans which worked, but since these are using #Inject and in my application jndi lookups are used everywhere i (at least think that i) need to swerve from that path.
Here is the TestCase i created based on Arquillian Getting Started. I explicitly left in all attempts using jndi properties of which i thought they might help.
The Test
should_create_greeting()
works if the Greeter bean using a separate Producer.
#RunWith(Arquillian.class)
public class GreeterTest {
public static final String ARCHIVE_NAME = "test";
Logger logger = Logger.getLogger(GreeterTest.class.getName());
#Deployment
public static Archive<?> createDeployment() {
JavaArchive jar = ShrinkWrap.create(JavaArchive.class, ARCHIVE_NAME + ".jar").addPackage(Greeter.class.getPackage())
.addAsManifestResource("test-persistence.xml", "persistence.xml").addAsManifestResource("OracleGUIDS-ds.xml")
.addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
return jar;
}
/**
* #Inject works using a producer with {#code #Produces}
*/
// #Inject
// Greeter greeter;
#ArquillianResource
Context context;
GreeterRemote greeter;
#Before
public void before() throws Exception {
Map<String, String> env = new HashMap<>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.as.naming.InitialContextFactory");
env.put("jboss.naming.client.ejb.context", "true");
// env.put("jboss.naming.client.connect.options.org.xnio.Options.SASL_POLICY_NOPLAINTEXT",
// "false");
// env.put("jboss.naming.client.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS",
// "false");
// env.put("jboss.naming.client.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED",
// "false");
for (Map.Entry<String, String> entry : env.entrySet()) {
context.addToEnvironment(entry.getKey(), entry.getValue());
}
greeter = (GreeterRemote) context.lookup(ARCHIVE_NAME + "/" + Greeter.class.getSimpleName() + "!"
+ GreeterRemote.class.getName());
}
#Test
public void should_create_greeting() {
Assert.assertEquals("Hello, Earthling!", greeter.createGreeting("Earthling"));
greeter.greet(System.out, "Earthling");
}
}
Is it possible to get this test running with jndi lookup? Am i missing something?
If you want to test the Remote features of a EJB you probably want to run on the client side and not in container.
You can configure the Deployment to be only client side by using #Deployment(testable=false). The #Test methods will then run as if you were a remote client.
Beyond that you can just lookup the bean via the injected Context if you want.
I had the same issue, so in a workaround i just added on the method to be tested the remoteejb as a parameter.
On my ejb:
public List localBean.obtain(RemoteEJB remoteEjb){
return remoteEjb.obtain();
}
Then on the arquillian test :
#Inject
private LocalBean localBean;
#Inject
private RemoteEJB remoteEjb;
#Test
public void test(){
List<Vo>voList = localBean.obtain(remoteEjb);
}
The best part is the remote ejb its injected and on the caller method original
#EJB(lookup="java:global/ear/ejb/RemoteEjb")
private RemoteEJB remoteEjb;
I've searched now for days to find some solution for my, in my opinion not too hard but obviously unsolvable problem.
I have an EAR project containing Some EJB, a web client (works fine) and now I added an Application Client Module.
As everything is in the same project, I thought a simple #EJB injection in the main class of the application client would do. I also tried a JNDI lookup.
I use eclipse and glassfish as a server and tried to run the application 1. in eclipse (there my injected bean is just null) and 2. downloaded the client-stub from the glassfish administration and tried to start it with sh appclient -client (or -jar) OmazanClient.jar (and also the other two jars hidden in the client-stub folder). There I get mostly a "ClassNotFoundExeption:Main" like
java.lang.ClassNotFoundException: Main
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at org.glassfish.appclient.client.acc.ACCClassLoader.findClass(ACCClassLoader.java:212)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:247)
at org.glassfish.appclient.client.acc.FacadeLaunchable.getMainClass(FacadeLaunchable.java:262)
at org.glassfish.appclient.client.acc.AppClientContainer.setClient(AppClientContainer.java:324)
at org.glassfish.appclient.client.acc.AppClientContainerBuilder.createContainer(AppClientContainerBuilder.java:185)
at org.glassfish.appclient.client.acc.AppClientContainerBuilder.newContainer(AppClientContainerBuilder.java:172)
at org.glassfish.appclient.client.AppClientFacade.createContainerForAppClientArchiveOrDir(AppClientFacade.java:492)
at org.glassfish.appclient.client.AppClientFacade.createContainer(AppClientFacade.java:454)
at org.glassfish.appclient.client.AppClientFacade.prepareACC(AppClientFacade.java:269)
at org.glassfish.appclient.client.acc.agent.AppClientContainerAgent.premain(AppClientContainerAgent.java:82)
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 sun.instrument.InstrumentationImpl.loadClassAndStartAgent(InstrumentationImpl.java:323)
at sun.instrument.InstrumentationImpl.loadClassAndCallPremain(InstrumentationImpl.java:338)
So for the injection, my code looks like:
public class Main {
#EJB (mappedName="ejb/customerBean")
public static CustomerInterface customerBean;
#EJB (mappedName="ejb/productBean")
public static ProductInterface productBean;
public static void main(String[] args) {
try{
Main m = new Main();
m.runDialog();
}
catch (Exception e){
e.printStackTrace();
}
}
/* (non-Java-doc)
* #see java.lang.Object#Object()
*/
public Main() {
super();
}
private void runDialog() throws Exception{
System.out.println("Test");
List<ProductDTO> productList = productBean.getAllProducts();
...
My remote interface looks like this:
#Remote
public interface ProductInterface {
public int addProduct(String productName);
public void deleteProduct(int prodid);
public void updateProduct(int prodid, String newName);
List<ProductDTO> getAllProducts();
...
My implementation is this:
/**
* Session Bean implementation productInterface
* */
#Stateless(mappedName="ejb/productBean")
#LocalBean
#WebService
public class ProductBean implements ProductInterface {
#EJB ProductEAO eao;
#EJB Conversion conv;
/**
* Default constructor.
*/
public ProductBean() {
// TODO Auto-generated constructor stub
}
#Override
public int addProduct(String prodName) {
return eao.addProduct(prodName);
}
#Override
public List<ProductDTO> getAllProducts() {
List<ProductDTO> result = new ArrayList<ProductDTO>();
List<Product> allProducts = eao.allProducts();
for (Product pr : allProducts) {
ProductDTO ci = conv.fromProduct(pr);
result.add(ci);
}
return result;
}
... and so on (all methods required by the interface are implemented, just try to keep it shorter here)
and the MANIFEST.MF is just
Manifest-Version: 1.0
Main-Class: Main
I've tried a lot like JNDI lookup, giving the bean names (see example) etc. But either the interface is not found (lookup) or the bean simply null.
How ever I am also not quite sure how to run the application client. I thought glassfishs appclient is the right starting point? It shall be a console-interaction so no swing components or anything similar.
Now I'd be thankful for any suggestions what I might have missed.
Cheers :)
Found a solution. Somehow, JNDI works now. Another problem was that my db query returned an Object and not primitive value or string - this caused a buffer error.
However, I am still confused on how to export an run an application client correctly. Maybe someone has an idea?!
There is a good example here: Create and Run a JEE6 Client Application with Netbeans 6.8 and Glassfish V3 - Part 2: Enhancing and Deploying the Application. It is a few years old, but it does give a pretty good overview.
I use Spring 3 in my project.Then I face a problem when I inject spring bean from JAR file. In JAR file, there is class like;
package test;
#Service("CommonService")
public class CommonService {
}
And i already used it like this;
package com.java.test.app;
#Service(value = "OtherService")
public class OtherService {
#Resource(name = "CommonService")
private CommonService service;
}
In my spring-beans.xml;
<context:component-scan base-package="com.java.test.app, test">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
</context:component-scan>
But #Resource annotation doesn't work.Can I inject spring bean from JAR file?
If at runtime your CommonService class is on the classpath and is within the base package you specify with component-scan, then you should be good to go. Try using #Autowired instead of #Resource.
I have the following setup:
JBoss 4.2.3
under that I have:
--> Project A (Which is not SEAM 2.1.2GA based)
EJBs:
* beanA (JNDI = beanA/remote)
* beanB (JNDI = beanB/remote)
--> Project B (SEAM based)
EJBs / Components:
* ComponentX
* ComponentY
On component X I have the current piece of code:
#Scope(ScopeType.CONVERSATION)
#Name("ComponentX")
public class ComponentX implements java.io.Serializable {
...
#EJB
beanAInterface beanA;
....
public foo(){
beanA.bar(); // <--------- beanA is null, even with mapped name and etc., only works
// if I direct lookup with Context().lookup("beanA/remote")
}
Any ideas on how to solve this?
Your ComponentX class is not an EJB, so you cannot use the #EJB annotation to inject them. You have a few options. Convert your ComponentX to EJB adding #Stateless or #Statefull and an interface #Local or #Remote, in this way the AS will notice ComponentX is an EJB and will know what to do with the desired injection. The other option is let the ComponentX as simply a component and use InitialContext#lookup for obtaining the reference to "beanA/remote" by hand.