I have to create project with interface(IGraphRemote), sessionbean(Graph) and client class(AppClient)
I tried to prepare simple project with one method register(int hwork, String album) - hwork its my homework's number, album its my album's number, but it doesn't work and returns an error: java.lang.NullPointerException , so connection wasn't established. How can i fix that ?
My files:
IGraphRemote
public interface IGraphRemote {
public boolean register(int hwork, String album);
}
Graph
#Remote
public class Graph implements IGraphRemote{
public boolean register(int hwork, String album) {
return (hwork == 6
&& album.equals("119962"));
}
}
And AppClient
public class AppClient {
#EJB
private static IGraphRemote gremote;
public static void main(String[] args) {
AppClient ap = new AppClient();
System.out.println(ap.gremote.register(6, "119962"));
}
}
here are my project
Error:
Exception in thread "main" java.lang.NullPointerException
at AppClient.main(AppClient.java:22)
Java Result: 1
It's obvious from your code and also in the stack trace that you try to run a standard j2se application with a main method from within a web application, so how do you expect dependcy injection to happen unless there is some other code create the ejb instance and inject it in the ejb reference. EJB is a J2EE component and it can't be created in standard java application, you need an ejb container with a naming service to manage the EJB lifecycle. You can create a standard j2se client by connecting to the naming service and lookup for the bean, but your EJB MUST be deployed in an ejb container in the first place such as TomEE, Glassfish, websphere,..etc
First of all, your EJB bean can not be static, waht is desrcibed here:
Injecting a static EJB, nonsense?
Second, if you want to inject your EJB bean, your app has to run in EJB container, like Glassfish or JBoss. If you run your app like simple Java SE applicaiton, your IGraphRemote gremote will always be null unless you initialize it by yourself.
Related
I'm creating a java class library and EJB module as a user authentication application which can be used by stand alone clients by calling the remote interface EJB and its implementation class (session bean). I'm Using Netbeans 8 and Glassfish 4.0. After succesfully building the app I get the following stack when trying to run it:
SEVERE: Exception during lifecycle processing
java.lang.Exception: java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: java.lang.RuntimeException: java.lang.NoClassDefFoundError: Lcom/manaar/security/services/remote/UserServiceRemote;
at com.sun.enterprise.web.WebApplication.start(WebApplication.java:168)
at org.glassfish.internal.data.EngineRef.start(EngineRef.java:122)
at org.glassfish.internal.data.ModuleInfo.start(ModuleInfo.java:291)
at org.glassfish.internal.data.ApplicationInfo.start(ApplicationInfo.java:352)
...
SEVERE: Exception while loading the app : java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: java.lang.RuntimeException: java.lang.NoClassDefFoundError: Lcom/manaar/security/services/remote/UserServiceRemote;
The steps I'm following are:
1) Create the Java class library and populate it with the remote interface and entity class
2) Create the EJB module and populate this with the implementation class (session bean) and dao methods
3) Add both projects above to the library of the client JSF web application
4) Call the remote interface as an EJB in the client app and use the methods to show a user profile
The main classes are:
1) Java class library
#Remote
public interface UserServiceRemote {
public List<Users> findAllUsers();
public Users findByName(String userName);
public void createUser(Users newUser);
public void updateUser(Users updatedUsers);
public void deleteUser(Users userToDelete);
public void adminUpdateUser(Users aUpdatedUser);
#Entity
#Table(name = "SHA_USERS")
public class Users {
#Id
private String userName;
private String password;
2) EJB Module
#Stateless
public class UserServiceImpl implements UserServiceRemote {
#EJB
private UsersDao dao;
#Override
public Users findByName(String userName) {
return dao.findByName(userName);
}
3) Java class library and EJB module are both added as Projects in the client application
4) The managed bean in the client app:
#ManagedBean
#SessionScoped
public class SecClientFull {
#EJB
private UserServiceRemote useServ;
private Users loggedUser;
private String userName;
public String showProfile() {
loggedUser = useServ.findByName(userName);
return "/Users/AppUserProfile";
}
public String getUserName() {
userName = FacesContext.getCurrentInstance().getExternalContext().getRemoteUser();
return userName;
}
...
}
Looking in this forum and elsewhere online I've seen several posts talking about bug in GF3. I'm using the newest version so I'm hoping this is not a bug and I have simply configured this wrong.
Also I'm not clear if I still need to add any configurations for the EJBs in the glassfish-web.xml (or sun-web.xml) configuration file. I've assumed that the Java EE annotations are sufficient.
Finally I should say I coded this manually. I'm not sure if using the Netbeans wizards to create the libraries and session beans is a better way to make sure the configurations are correct.
Would really appreciate any advice or feedback and pls let me know if I need to provide further information. Thanks in advance!
The solution to the above is twofold:
1) Make sure that both Java class library and EJB module are created with separate 'lib' directories if they are to used by stand alone applications (which they are in my case). It's easy to overlook that point if you're creating EJBs for use in the same app (as many tutorials are)
2) The entity class (Users) must implement the java.io.Serialization interface and so should the managed bean on the client side
When first re-creating the Java class library and EJB module I got a ClassCastException that Users cannot be cast to Serialization. As the Java EE tutorial says the implementation of Serialization is for security reasons when EJB modules are used by stand alone applications and transferred accross networks.
So I added the interface to the entity class and the managed bean on the client side. The exception was eliminated and the app now runs perfectly. Thanks again!
Did you create default no args constructor for your class. Because I don't see it in your code.
I have 2 EJB module projects and I want from one of the projects to call a stateless no-interface bean from another project. I want to inject the bean to be called using the EJB annotation. The problem is the injection doesn't work(I use NetBeans 7.4 if that is relevant).
The stateless no-interface EJB being called:
package standalonepackage;
import javax.ejb.Stateless;
import javax.ejb.LocalBean;
#Stateless
#LocalBean
public class StandaloneBean {
private static final String message="Greetings!";
public String returnMessage(){
return message;
}
}
The interface of the bean that calls the bean above(this ejb resides in another ejb module project)
#Local
public interface ExampleBeanLocal {
public String getMessage();
}
The implementation of the interface:
#Stateless
public class ExampleBean implements ExampleBeanLocal {
#EJB
private StandaloneBean standaloneBean;
#Override
public String getMessage() {
return String.format("Me - and the second message %s", standaloneBean.returnMessage());
}
}
I also have a main class that just calls the ExampleBean getMessage method(MainClass is located in the second ejb module project):
public class MainClass {
private static ExampleBeanLocal instance = new ExampleBean();
public static void main(String[] args) {
System.out.println(instance.getMessage());
}
}
What am I missing?
First of all if you want to access your business logic as EJB then first you will need to deploy the EJB in an application server. During the deployment process the application server will create something called the JNDI name which is like a gatepass to access your business logic.
Secondly, there are two ways you can invoke an EJB.
1. Creating ContextLookup using JNDI name
2. Using Context Dependency Injection CDI (only within the same Container)
You cannot invoke an EJB using CDI from a POJO ( since it is not contained in any container and the EJB your accessing is in a different JVM ). If you want to access an EJB from a POJO you'll need to use #Remote and use the ContextLookup way of accessing an EJB, you can find more information here
http://wiki.netbeans.org/CreatingEJB3UsingNetbeansAndGlassfish
You need application server with EJB container to run this. Have a look at JBoss, Apache TomEE or something else.
you can use this way to run your jar GLASFISH_HOME/bin/appclient -client app.jar
before compiling your maven project mvn assembly:assembly
and add your main class in your pom.xml
When I try to access EJB from another module inside one Application I got NullPointerException.
I'll explain an example to be more exact.
EAR Structure following:
EAR
|
— core.jar (EJB-module with core EJB) — application core
|
— app.jar (another EJB-module with EJBs) — business logic here
|
— web.war (servlets)
At code.jar there is EJB:
#LocalBean
#Singleton
#Startup
public class AppInfo(){
private int counter;
public void incCounter(){
counter++;
}
public int getCounterValue(){
return counter;
}
}
At module app.jar we have Stateless EJB which tries to read counter.
#Stateless
public class SomeBean{
#EJB private AppInfo appinfo;
public void run(){
int counter = appInfo.getCounterValue(); // here method throws with NPE
System.out.println("Counter value is: "+counter);
}
}
At module web.war there is servlet that increment counter value for every request:
public class MyServlet extends HttpServlet{
#EJB private AppInfo appInfo;
protected void doPost(params){
appInfo.incCounter();
...
other code
}
}
While debugging, I detected that:
At servlet injection work well: when entering doPost() appInfo is Proxy object for AppInfo EJB.
At SomeBean there is NPE: at run() entry point value of appInfo = null.
How I do correctly inject EJB from core.jar to another EJB from App?
P.S. I deploy EAR to JBoss 6.1 EAP
P.S.S. I also tried using #Remote: not working (appInfo is still equals null)
I think Local should work - this is in the same Application.
Try the fully qualified package name:
#EJB(beanName="my.package.AppInfo")
It seems to be that this is a JBoss deployment ordering issue. When the container creates a new instance of SomeBean and tries to inject the AppInfo bean, this one hasn't been created/deployed yet.
Try to rename your jars file, indicating the correct dependency order. (eg. a_core.jar and b_app.jar).
Other possibility could be to inject the singleton bean on a setter method.
To access EJB from another module, you need to do with following ways:
Use Remote access instead of Local access. or
Use JNDI.
For details, read this tutorial.
Using GlassFish 3.1.2, I try to call a Session Bean from a Netbeans platform module, and I get a null pointer exception. My problem is that I have no trace explaining how / where the NPE is generated.
The code in my Module is simply:
import ejb.MySessionRemote;
import javax.ejb.EJB;
public class TestServer {
#EJB
private static MySessionRemote mySession;
public boolean execute() {
System.out.println("result = " + mySession.getString()); //NPE here: mySession is null
return true;
}
}
The Session bean "My Session", the remote interface and the application deployed on the server side are just the ones from this tutorial: https://netbeans.org/kb/docs/javaee/entappclient.html
Any help greatly appreciated.
Note: I've checked this tutorial, without solving my issue.
If mySession is null, it was probably not injected. You can inject into managed beans (EJBs for example), because these instances are managed (created/removed) by a container, and the container does the injection for you.
You can possibly inject into a POJO, if you use CDI.
If TestServer is part of a stand-alone application for example, try to lookup the EJB using JNDI. This is what your tutorial does as well. It involves setting up the properties to get an InitialContext, and the lookup of the EJB using JNDI.
I am writing a little java library that is intended to be used in a web-application as well as by a java console-application.
In order to profit from CDI and other javaEE 6 features and not having to maintain two versions (java EE and java SE) of the library I'd like to use openejb (embedded) for the console-application.
So I've built a maven project in eclipse and added the openejb artifact.
Somehow I just don't get how to make the console program use the openejb-container, that is resolve my injections and other javaEE features.
Lets say I have two very simple classes:
#Stateless
Class A {
#Inject
public B member;
public A() {};
}
and
#Stateless
Class B {
public B() {};
public String getString () {
return "Hello";
}
}
So, how would I get a plain old java class with a main() method make instantiate a member of A using the embedded openejb? - in a way like:
public class TestOpenEJB {
public static void main(String[] args) {
Class A a = new A(); /*wrong of couse*/
System.out.println( a.member.getString() );
}
}
A working solution for this simple example would be helpful.
Finally, my aim here is to provide a java SE api for a library that uses an embedded javaEE container internally.
Thanks a lot!
Additional to my comments, I think your problem can be answered in this way:
Go on and model your library's behaviour with EJBs (as shown in your code example). This is a good approach, since the container cares about things like pooling, parallel access, transactions and such.
Then your web application (assuming it's in the same container) can just use those EJBs directly.
And for accessing it via a console application, you can either run it within an application client container (which is preferable than trying to embed a container in your application), or (which I would recommend) expose your business logic in an additional way (e.g. via REST) and use that in a standalone client application.
PS: For integration testing your business logic with DI mechanisms, use Arquillian.