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.
Related
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.
I have interface A.java and 3 classes which are implementing A.java interface named B.java, C.java and D.java. Now i am try to inject the bean like this.
interface A{}
#Component
#Scope("request")
class B implements A{
//......
}
#Component
#Scope("request")
class C implements A{
//.....
}
#Component
#Scope("request")
class D implements A{
}
class Implementation{
#Autowired
public A obj;
#Autowired
private BeanFactory beanFactory;
String[] beans = {"B","C","D"}; //actually these are coming from database in my case
for(String beanName : beans){
obj = (A)beanFactory.getBean(beanName);
....//calling some method of particular bean class
}
}
It is showing Error message something: "Unique bean not found: contains multiple beans["B","C","D"]".
If I am configuring these beans in XML file, it is working fine but I don't want to use xml config
How to solve this problem Using spring Annonantion??
It seems to me that the problem is with the Autowired annotation, because it'll do the injection by type, and the type of your variable is A, so It will be difficult to decide which bean to actually inject, B, C or D.
Try to use Resource annotation which decide to inject by name. Or instead just add Qualifier annotation.
Look here for further explanation:
Difference between #Qualifier and #Resource
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;
Im trying to use CDI extensions to discover JAX-RS resources at runtime and automatically publish them under different base URIs in a Java SE environment. Applications should not need to extend javax.ws.rs.core.Application themselves if possible.
I have read RestEasy documentation and javadoc but failed to find any obvious way to modify the #ApplicationPath at runtime.
One idea that im exploring is to try generate javax.ws.rs.core.Application and set the #ApplicationPath base URI programmatically, maybe by using an AnnotatedType CDI extension, and publish that as a * org.jboss.resteasy.spi.ResteasyDeployment`.
Are there other/better ways to do this?
EDIT:
Trying CDI extension event ProcessAnnotatedType to change #javax.ws.rs.Path of JAX-RS resources.
<X> void process(#Observes ProcessAnnotatedType<X> pat) {
if (!pat.getAnnotatedType().isAnnotationPresent(javax.ws.rs.Path.class)) {
return;
}
final AnnotatedType<X> org = pat.getAnnotatedType();
AnnotatedType<X> wrapped = new AnnotatedType<X>() {
#Override
public <T extends Annotation> T getAnnotation(final Class<T> annotation) {
if (javax.ws.rs.Path.class.equals(annotation)) {
class PathLiteral extends AnnotationLiteral<javax.ws.rs.Path> implements javax.ws.rs.Path {
#Override
public String value() {
return "change_me/" + (javax.ws.rs.Path) org.getAnnotation(annotation);
}
}
return (T) new PathLiteral();
} else {
return org.getAnnotation(annotation);
}
}
pat.setAnnotatedType(wrapped);
}
... then after bootstrap, constructing the bean using javax.enterprise.inject.spi.BeanManager was expecting the following code to print "change_me/...."
Set<Bean<?>> beans = beanManager.getBeans(jaxrsClass);
for (Bean<?> bean : beans) {
CreationalContext cc = bm.createCreationalContext(bean);
Object jaxrs = bean.create(cc);
Path p = jaxrs.getClass().getAnnotation(Path.class);
System.out.println(p.value());
}
... but this does not work. javax.ws.rs.Path is unchanged for JAX-RS resource 'jaxrsClass'.
What is wrong?
I doubt this can be done in a reliable way. It probably all comes down to which happens first: the CDI bootstrap or JAX-RS, of course in the future or in other application servers it could all be done in parallel.
It's certainly a cool idea though. What have they said on the RestEasy forums?
We are already using such an approach.
We are using the feature to use Subresource locators and take the power of guice.
At the startup we are scanning the classpath for all resources annotated with #Path. After that we are extracting the path and binding the resources with the help of Names/#Named. So the resources can later be injected with the help of the name.
bind(..).annotatedWith(Names.named("path")).to(..)
The next step is that you need a resource with a subresource locator.
#Path("{name}")
public Object find(#PathParam("name") name){
return injector.getInstance(..);
}
You could use this approach to bind them at runtime and also to change the original annotated path.
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.