I can write a ejb like this...
#Stateless
public class AnotherBean {
#PersistenceContext(unitName = "VoidJPA-ejbPU")
private EntityManager em;
public void newTest() {
System.out.println("Testing");
}
}
And call it using this from a servlet
#EJB
private AnotherBean nsb;
...
...
nsb.newTest();
But whenever i put a variable into newTest() i cannot access it
public void test(String i)
The servlet and EJB are both deployed but still
the server gives the error
WARNING: StandardWrapperValve[HelloEjb]: PWC1406: Servlet.service() for servlet
HelloEjb threw exception
java.lang.NoSuchMethodError: enew.AnotherBean.newTest(Ljava/lang/String;)V
at jpa.HelloEjb.processRequest(HelloEjb.java:44)
at jpa.HelloEjb.doGet(HelloEjb.java:85)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:734)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:847)
.....
........
......
Any Help
Thanks
Pradyut
India
The Servlet clearly doesn't see the version of the Bean with the String parameter at runtime (you might have several versions on the classpath).
This could be a packaging issue, a deployment issue. You need to tell us more about the way you package and deploy your application.
Clean and rebuild your application then deploy again. Also check the dependencies. It seems the EJB contract is not visible to the servlet.
Ya i got it...
In netbeans i had to do the following...
Clean and Build the Ejb Project
Deploy the Ejb Project
Deploy the WebApplication(war) project (and make sure the ejb jar is in libraries which netbeans automatically does and needs no worry).
Related
I am trying to run a Junit test case for a method which uses webapplication context internally. However my problem is that I can not create or mock WebApplicationContext in Junit. When application is build and run then the actual code executes fine and webapplication context is created but in Junit it can not create the same.
My test case has below tags
#WebAppConfiguration
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration("classpath:applicationcontext.xml")
The method which I am trying to test has below code
WebApplicationContext context =
ContextLoader.getCurrentWebApplicationContext();
context.getBean("checkStatus", checkStatus.class);
At this point I get null pointer exception as it can not get webapplication context from ContextLooader, Can I mock this some how so that it does not give null pointer or some how can I get the actual webapplication context so that I can use it.
Should I add some code for WebApplicationContext loading in my application context xml file. In my web.xml file there is an entry regarding ContextLoaderListener should I read configuration from web.xml also in my Junit Test case?
Please provide some suggestion.
there's a lot missing from you question, including details of your environment, version numbers, and especially the exact problem you're trying to solve.
we run junit and spring boot flawlessly using the instructions in https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html#boot-features-testing-spring-boot-applications-testing-with-running-server .
but since we have no information about your use case, i can't tell whether that would work for you or not.
I am going through JavaEE7-samples repo in github. I found that the author has mentioned the following in this code snippet:
// Cannot be injected using #Inject
#EJB Cart bean;
The author explicitly mentions that #Inject will not work. But I am wondering what is the reason behind it?
I have read the following posts on difference between #EJB and #Inject. but that did not help me here.
http://www.adam-bien.com/roller/abien/entry/inject_vs_ejb
What is the difference between #Inject and #EJB
Should I use #EJB or #Inject
Both will work if the bean has Local interface. However for #Inject to work you have to enable CDI (create beans.xml file in your WEB-INF folder).
If the bean has Remote interface you would need to have producer class to declare the resource with the following code:
public class RemoteProducer {
#Produces #EJB
HelloRemote helloBean;
}
For more details see section 3.5 in the JSR-299 CDI specification.
So for simplicity of usage I'd suggest to stick with #EJB for EJBs.
I'm studying EJB now, and I create a simple EJB example in JBOSS and run successfully, here are my steps:
Create an EJB project in myeclipse
Create an interface named FirstEjb
Create FirstEjbBean implemented the FirstEjb interface, and mark the EJB annotations
#Remote
#Stateless
public class FirstEjbBean implements FirstEjb {
#Override
public String saySomething(String name) {
return "Hello, " + name;
}
}
Create a Java project name "EjbClient" in MyEclipse, export the FirstEjb interface as a *.jar and the new Java project reference to it
Add all the jars in directory "client" of JBOSS to EjbClient project
Create a jndi.properties in the Ejb:
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=localhost
7 .Create class FirstEjbClient.java
public class FirstEjbClient {
public static void main(String[] args) throws NamingException {
InitialContext context = new InitialContext();
FirstEjb ejb = (FirstEjb) context.lookup("FirstEjbBean/remote");
String something = ejb.saySomething("Jimmy.Chen");
System.out.println(something);
}
}
And then I can access the EJB successfully.
The question is, I don't know how to do this same in websphere.
There are some questions:
Do I need to config anything in websphere after deploy the EJB project? Like JNDI??
What jars should I import into the Client project? And those jars are in what directory of websphere?
Do I still need the jndi.properties? And how to write it if needed?
I have search on the internet a lot, but all I found is config the data source in websphere.
Sorry for my poor English, hope there is someone can understand it and provide some help.
Thanks in advance!
Jimmy.Chen
Hello,
try this:
Properties props= new Properties();
props.setProperty(Context.INITIAL_CONTEXT_FACTORY,"com.ibm.websphere.naming.WsnInitialContextFactory");
props.setProperty(Context.PROVIDER_URL,"corbaloc:iiop:localhost:2809");
Context ctx = new InitialContext(props);
Object homeObject = ctx.lookup("some.package.MyEJBRemote");
MyEJBRemote myEJB = (MyEJBRemote) javax.rmi.PortableRemoteObject.narrow(homeObject, some.package.MyEJBRemote);
However I'm not sure about the jars necessary to import, since you can add WebSphere Application Server X runtime library to the buildpath in Eclipse
WAS runtimes for Eclipse are on http://www.ibmdw.net/wasdev/
When you create an EJB project in Eclipse, an EJB deployment descriptor is created. You have to add all your JNDI resources in it, in the references tab.
And you have to add websphere runtime JARs same as you have added any other JARs.
I'm configuring an ejb module on websphere 7 and I need to set my classloader to PARENT_LAST to make sure I don't get any classloader issues with wrong version of classes.
The odd thing is, my ejb #Resource annotation does not inject my resources anymore (which are defined in ejb-jar.xml) when I change my classloader to PARENT_LAST. All my fields annotated with #Resource are null.
I suspect your application contains a JAR that contains the javax.annotation.Resource class. The PARENT_LAST setting is causing the class loader to prefer your Resource class over the one in the JDK, which means the WebSphere Application Server injection engine never sees your Resource annotation. You should remove that JAR from your application.
If you want to verify, try adding the following logic to your application before the NPE occurs:
System.out.println(Resource.class.getProtectionDomain().getCodeSource().getLocation());
...or enable the -verbose:class (Verbose JVM class loading) option in your server JVM.
I have #LocalBeans and JAX-RS resources in different packages in a single ear.
And I also have a ServletFilter filtering before those resources.
I found that #EJB works for the ServletFilter but not for those resources.
#Stateless
#LocalBean
class MyBean { // in ejb jar
}
#WebFilter(urlPatterns = {"/*"})
class MyFilter implements Filter { // in the same war
#EJB MyBean myBean; // not null
}
#ApplicationPath("/")
class MyApplication extends Application { // in the same war
}
#Path("/my")
class MyResource { // in the same war
#EJB MyBean myBean; // null
}
No logs special, just an NPE in MyResource's method.
Can anybody help me?
UPDATE -----------------------------------------------
Making those resource classes as #Stateless do works.
But I just curious that those ejb-jar and web-war are assembled into a single ear.
And then the web-war is a web component, isn't it?
UPDATE2 ------------------------------------------------------
Oh, I'm sorry. There is also MyApplication that makes MyResource as a JAX-RS resource.
When I deploy the ear GF detect it as an 'Enterprise Application'.
UPDATE3 ---------------------------------------------------------------
Here comes my application.xml
<?xml version="1.0" encoding="UTF-8"?>
<application xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_6.xsd" version="6">
<display-name>sngp-v0-ear</display-name>
<module> <!-- EJBs are here -->
<ejb>sngp-v0-beans-1.0-alpha-1-SNAPSHOT.jar</ejb>
</module>
<module>
<web> <!-- JAX-RS are here -->
<web-uri>sngp-v0-mobile-resources-1.0-alpha-1-SNAPSHOT.war</web-uri>
<context-root>/sngp-v0-mobile-resources</context-root>
</web>
</module>
<library-directory>lib</library-directory>
</application>
MyResource class isn't either a web component or an enterprise bean, but you are trying to inject an EJB into it. EJB injection is guaranteed to work only when the client is either a web component or another enterprise bean.
Try making MyResource #Stateless.
Have a look at this Java EE 6 tutorial regarding EJB injection. If you are using NetBeans, I have also found useful using the built-in wizard for creating RESTFul web services. Check out this link in case.