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.
Related
Attached my screenshot which is entry level rest class, where used #Component. Why used #Component ?
I gone through below blog
http://www.benchresources.net/jersey-2-x-web-service-integrating-with-spring-framework-using-annotation/
#Component, #Resource, #Service used because you are still using spring framework application for dependency injection, specifically to link to found classes by component scan, and you want it to be able to autowire spring components as you service or dao classes
I Have a spring boot application with following config.
#Configuration
#EnableWebMvc
#ComponentScan({ "com.xxx.mypackages" })
public class MyWebAppConfiguration extends WebMvcConfigurerAdapter {
}
In my project I have some web services and spring controllers. I want swagger to be enabled only in my web service classes. Currently, it generates documentation for both rest and controller classes. How can I customize that?
I'm using following dependency in gradle.
compile "com.mangofactory:swagger-springmvc:1.0.2"
If you look at the 1.0.2 documentation you'll find that SwaggerSpringMvcPlugin has a includePatterns method. This method takes a regular expression of the paths to include. For e.g. if you had an path prefix for the rest endpoints like this /rest/some-resource.... you could include a pattern, something like the snippet shown below
#Bean
public SwaggerSpringMvcPlugin customImplementation(){
return new SwaggerSpringMvcPlugin(this.springSwaggerConfig)
//... more config goes here
//regex to identify your rest services path
.includePatterns(".*rest.*");
}
Also it would be useful to know that we're going to be releasing 2.0 shortly with support for swagger spec 2.0. That might be something to consider as well.
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 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).