-
1. Re: WebRemote inconsistencies
shane.bryzak Aug 2, 2006 10:56 PM (in response to zeddmaxim)I've never come across this issue before. If you browse to the stubs directly do they only work intermittently?
-
2. Re: WebRemote inconsistencies
zeddmaxim Aug 2, 2006 11:37 PM (in response to zeddmaxim)Here are the two stubs, the first set is when it does not work, the second, when it does. All I do inbetween is rebuild the ear and redeploy it via MyEclipse IDE. I am using JBoss 4.0.4GA (installed via the JEMS installer) and Seam 1.0.1 GA if that helps any.
Seam.Remoting.type.modelbuilder = function() { this.__callback = new Object(); } Seam.Remoting.type.modelbuilder.__name = "modelbuilder"; Seam.Component.register(Seam.Remoting.type.modelbuilder);
Seam.Remoting.type.modelbuilder = function() { this.__callback = new Object(); Seam.Remoting.type.modelbuilder.prototype.findGL = function(p0, callback) { return Seam.Remoting.execute(this, "findGL", [p0], callback); } Seam.Remoting.type.modelbuilder.prototype.getDefaultPOD = function(p0, callback) { return Seam.Remoting.execute(this, "getDefaultPOD", [p0], callback); } Seam.Remoting.type.modelbuilder.prototype.getPriceFactors = function(p0, callback) { return Seam.Remoting.execute(this, "getPriceFactors", [p0], callback); } Seam.Remoting.type.modelbuilder.prototype.validateModelDescription = function(p0, p1, p2, callback) { return Seam.Remoting.execute(this, "validateModelDescription", [p0, p1, p2], callback); } } Seam.Remoting.type.modelbuilder.__name = "modelbuilder"; Seam.Component.register(Seam.Remoting.type.modelbuilder);
-
3. Re: WebRemote inconsistencies
shane.bryzak Aug 3, 2006 12:24 AM (in response to zeddmaxim)Is it possible for you to debug this? I can't reproduce it so any insight into its cause would be very helpful. You would need to set your breakpoint in InterfaceGenerator.appendComponentSource(). There's a while-loop that iterates through the methods of your component to add them to the javascript source:
componentSrc.append("Seam.Remoting.type."); componentSrc.append(component.getName()); componentSrc.append(" = function() {\n"); componentSrc.append(" this.__callback = new Object();\n"); for (Method m : type.getDeclaredMethods()) // <- set breakpoint here
You would need to step through this code and see if its finding your component methods or not. -
4. Re: WebRemote inconsistencies
zeddmaxim Aug 3, 2006 9:05 AM (in response to zeddmaxim)I think I have found the problem. It is mostly my fault, but I think a change or two in InterfaceGenerator.appendComponentSource() would ease a lot of people's headaches in the future.
My WebRemote methods are in a SFSB, with both a remote and local interface. However, the remote and local interfaces are not the same (more methods are exposed via the local than remote, including my WebRemote methods). The culprit in this situation lies with the following snippet from that method:if ((component.getType().equals(ComponentType.STATEFUL_SESSION_BEAN) || component.getType().equals(ComponentType.STATELESS_SESSION_BEAN)) && component.getBusinessInterfaces().size() > 0) { type = component.getBusinessInterfaces().iterator().next(); }
Since the method getBusinessInterfaces() returns a Set, which is not ordered, and I have 2 interfaces on my SFSB, I have (roughly) a 50/50 chance of getting my local interface returned first, which contains my WebRemote method stubs. If my remote interface is returned first, no stubs.
The solution for me is easy at this point. Expose my WebRemote methods in the remote interface as well, and it then does not matter which it grabs first.
However, in the long run, would it not make more sense to iterate all of the stateless/ful session bean's interfaces looking for WebRemote methods?
Incidentally, I admit it is not a common use case to have your local and remote interfaces be different, but the case still seems valid. -
5. Re: WebRemote inconsistencies
zeddmaxim Aug 3, 2006 9:23 AM (in response to zeddmaxim)Ok, so my understanding is still incomplete. Adding to the remote interface adds the stubs, but does not solve the problem. Does seam remoting only work with local interfaces? When the Call class actually invokes the method through reflection, I am getting the following stack trace:
java.lang.IllegalArgumentException: object is not an instance of declaring class at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:585) at org.jboss.seam.remoting.Call.execute(Call.java:121) at org.jboss.seam.remoting.ExecutionHandler.handle(ExecutionHandler.java:92) at org.jboss.seam.remoting.SeamRemotingServlet.doPost(SeamRemotingServlet.java:56) at javax.servlet.http.HttpServlet.service(HttpServlet.java:717) 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:96) 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.SecurityAssociationValve.invoke(SecurityAssociationValve.java:175) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:432) at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:74) 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:869) at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:664) 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:595)
Also, I noticed this in Call.execute itself:if (component.getBusinessInterfaces().size() > 0) { // Get the local interface for the component - this is the type that we're // going to assume we're invoking against. type = component.getBusinessInterfaces().iterator().next(); }
If you're only going after local interfaces, would it make more sense to iterate until you find one with a @Local annotation? Again, my understanding may be incomplete, and these suggestions may be totally bogus.
My solution for now will be to remove the remote interface. We had only been using it for testing up to this point. However, if the time ever comes that they want to expose this bean as a web service, or they want the class to implement another interface, this will again become a problem for me. -
6. Re: WebRemote inconsistencies
shane.bryzak Aug 3, 2006 6:25 PM (in response to zeddmaxim)Yes you're right, it should only use the Local interface. I'll modify InterfaceGenerator and the Call class today to ensure that they get only the interface annotated as @Local.
-
7. Re: WebRemote inconsistencies
shane.bryzak Aug 3, 2006 8:16 PM (in response to zeddmaxim)All fixed. The local interface is now used in both places.