Win a copy of Kotlin in Action this week in the Kotlin forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Problem calling a method in a servlet witch returns remote ejb  RSS feed

 
pierre castin
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi, I have a problem combining servlets ands ejbs, I expose my problem :

What I have :

1 . I have a User table into a SGBD with two attributes login and pass.
2 . I have a UserBean linked to User table with a remote interface
3 . I have a stateless UserSessionBean with a remote interface
4 . I have a UserServlet linked to a jsp page which allows me to add users
5 . I use Jboss

What is working ?

1 - I have a method newUser implemented in my UserSessionBean :

public class UserSessionBean implements SessionBean {
private SessionContext sessionContext;
private UserRemoteHome userRemoteHome;

public void ejbCreate() throws CreateException {
// Initialize UserRemoteHome
}

// Method to add a new user
public UserRemote newUser(String login, String password) {
UserRemote newUser = null;
try {
newUser = userRemoteHome.create(login, password);
} catch (RemoteException ex) {
System.err.println("Error: " + ex);
} catch (CreateException ex) {
System.err.println("Error: " + ex);
}
return newUser;
}
}



2 - When I test this method with a simple client it works perfectly :

public class TestEJB {

public static void main(String[] args) {
Context initialCtx;

try {
// Create JNDI context
// ....

// Context initialization
// ....

// Narrow UserSessionHome
// ....

// Create UserSession

UserSession session = sessionHome.create();

// Test create

UserRemote newUser = session.newUser("pierre", "hemici");

if (newUser != null) {
System.out.println(newUser.printMe());
}

} catch (Exception e) {
System.err.println("Error: " + e);
e.printStackTrace();
}
}
}



Result : I got the newUser printed on STDOUT and I check in the User table (in the SGBD) if the new user has been created.

What I want ?

I want to call the newUser method from the UserServlet and use the RemoteUser returned by the method.

What I do ?

The jsp :

1 - I have a jsp page where a get information about the new user to create
2 - I put the login parameter and the password parameter into the request
3 - I call the UserServlet when the button "add" is pressed on the jsp page.

The Servlet :

1 - I have a method doInsert which call the newUser method :

public class UserServlet extends HttpServlet {
private static final String CONTENT_TYPE = "text/html";

// EJB Context
InitialContext ejbCtx;

// Session bean
UserSession userSession;

public void init() throws ServletException {
try {
// Open JNDI context (the same as TestClient context)
//....

// Get UserSession Home
//....

// Create UserSession

userSession = userSessionHome.create();

} catch (NamingException ex) {
System.out.println("Error: " + ex);
} catch (RemoteException ex) {
System.out.println("Error: " + ex);
} catch (CreateException ex) {
System.out.println("Error: " + ex);
}
}

protected void service(HttpServletRequest req, HttpServletResponse resp) throws
ServletException, IOException {
// ...
}

/**
* Does insertion of the new user in the database.
*/
public void doInsert(HttpServletRequest req, HttpServletResponse resp) throws
ServletException, IOException {
try {

// Get parameters to create the newUser

String login = req.getParameter("login");
String password = req.getParameter("password");

// Create the newUser

System.out.println("Calling newUser before");

UserRemote user = userSession.newUser(login, password);

System.out.println("Calling newUser after");

} catch (Exception e) {
}
}

// Clean up resources
public void destroy() {
}
}



Result :

When I run my jsp page and click on the "add" button, I got the message "Calling newUser before" printed in STDOUT and the error message :

ERROR [[userservlet]] Servlet.service() for servlet userservlet threw exception
javax.servlet.ServletException: loader constraints violated when linking javax/ejb/Handle class

at noumea.user.UserServlet.service(UserServlet.java:112)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:810)

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)

at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)

at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:81)

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)

at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)

at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)

at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)

at org.jboss.web.tomcat.security.CustomPrincipalValve.invoke(CustomPrincipalValve.java:39)

at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:153)

at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:59)

at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)

at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)

at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)

at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)

at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:856)

at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:744)

at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)

at org.apache.tomcat.util.net.MasterSlaveWorkerThread.run(MasterSlaveWorkerThread.java:112)

at java.lang.Thread.run(Thread.java:534)

Constat :

I checked into my SGBD and the new user has been created.
The error appears only when the method return Remote ejbs, if I return simples objects (Strings, int..) it works.

What can I do to resolve this problem ?

Thank you.
 
Valentin Tanase
Ranch Hand
Posts: 704
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Pierre,


I checked into my SGBD and the new user has been created.
The error appears only when the method return Remote ejbs, if I return simples objects (Strings, int..) it works.

What can I do to resolve this problem ?

Do exactly what you�ve said: make the newUser method to return either void or something else that is meaningful to the clients. The fact that your SLSB returns a remote interface of one of your entity ejb, is a poor designing decision. In fact you�re kind of using the session fa�ade pattern, which supposes to hide the entity ejb layer from your clients (the servlet in this case). Besides the session fa�ade should access your entity beans layer through the local interfaces.
The question that puzzles me is why do you need to return the UserRemote in the first place anyway? So far the session bean is the one that creates the new user, which is fine and it shouldn't do more. If you think that your clients should call any of the UserBean�s methods than you should allow the UserSessionBean to do this. Again the clients should not be aware about the fact that your app uses entity ejbs for persistence.
Regards.
 
pierre castin
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I include only the newUser example to my question, I accord you that it is not
apparent why it must return a UserRemote.

Let me show you another example based on the same class :

If I want the a list of all users to be see in a jsp page, I call the method getUserList which return a list of UserRemote. Then I iterate over the list to get the users parameters to print.

As the other example, when I do
"List users = (ArrayList) userSession.getUserList();" with the simple client it works, but in the servlet I got the same error.

But, if I call directly the findAll method,
"List users = (ArrayList) userRemoteHome.findAll();" it works...

I don't want to have ejb treatments in my servlet, I want that all treatments to be in my UserSession bean.

But with this method, I don't need UserSession bean anymore.

I precise that my design is this :

jsp -> servlet -> session bean -> entity bean -> sgbd

Did you understand better why I methods in my session bean which returns remote ejbs ?

I you have another solution, for example to have the list of all users in the servlet by a session bean method, without calling direclty the findAll method into the servlet, It will be nice to explain it because I don't see any solution.

Thank you.
 
Valentin Tanase
Ranch Hand
Posts: 704
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Pierre,


I you have another solution, for example to have the list of all users in the servlet by a session bean method, without calling direclty the findAll method into the servlet, It will be nice to explain it because I don't see any solution.

That�s what I�m saying: add a method like getAllUsers in your session bean and let the UserSessionBean return a collection of users. Hence it would be the session bean that looks up the entity bean and calls the findAll method (ideally using the local interfaces). The next question you need to answer is about the type of data you need to return back to the clients. Obviously the remote interfaces are not the best idea. You might consider revisiting the DTO and DTO factory design patterns in order to decide which type of data fits your project needs.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!