GWT Deferred binding issue - gwt

I am running into an issue with GWT :
The exception stack looks like :
Caused by: java.lang.RuntimeException: Deferred binding failed for 'com.cme.reg.fltrs.common.service.AnnouncementService' (did you forget to inherit a required module?)
at com.google.gwt.dev.shell.GWTBridgeImpl.create(GWTBridgeImpl.java:53)
at com.google.gwt.core.client.GWT.create(GWT.java:98)
at com.cme.reg.fltrs.client.sharedui.utils.ServiceFactory.getAnnouncementService(ServiceFactory.java:117)
at com.cme.reg.fltrs.client.announcement.AddMaintainAnnouncementModel.saveAnnouncement(AddMaintainAnnouncementModel.java:36)
at com.cme.reg.fltrs.client.announcement.AddMaintainAnnouncementPanel.save(AddMaintainAnnouncementPanel.java:260)
at com.cme.reg.fltrs.client.announcement.AddMaintainAnnouncementPanel$6.onClick(AddMaintainAnnouncementPanel.java:168)
at com.cme.libs.gwt.client.widgets.events.CMEClickListener.onEvent(CMEClickListener.java:10)
at com.cme.libs.gwt.client.widgets.events.CMEListenerCollection.fireEvent(CMEListenerCollection.java:51)
at com.cme.libs.gwt.client.widgets.CMEButton$1.onClick(CMEButton.java:30)
at com.google.gwt.event.dom.client.ClickEvent.dispatch(ClickEvent.java:54)
at com.google.gwt.event.dom.client.ClickEvent.dispatch(ClickEvent.java:1)
at com.google.gwt.event.shared.GwtEvent.dispatch(GwtEvent.java:1)
at com.google.web.bindery.event.shared.SimpleEventBus.doFire(SimpleEventBus.java:193)
at com.google.web.bindery.event.shared.SimpleEventBus.fireEvent(SimpleEventBus.java:88)
at com.google.gwt.event.shared.HandlerManager.fireEvent(HandlerManager.java:127)
Its failing at : announcementService = GWT.create(AnnouncementService.class);
Notes:
I have my service class : AnnouncementService
#RemoteServiceRelativePath( "announcement.srvc" ) has been added to AnnouncementService.
Async service class: AnnouncementServiceAsync
Configurations.xml :
entry key="**/announcement.srvc" value-ref="announcementServiceServlet"
Any help, where I am doing wrong or missing anything ?

Thanks Thomas.
Few The things to be checked:
1.Service must have a matching ServiceAsync class
2. Make sure all types used in Service implement IsSerializable
I was missing these two condition at few places.

If you're getting a deferred binding error with your RPC, then in addition to checking there is a matching Async interface, another thing to check is to make sure that you have the same methods in the following 3 places:
Synchronous interface
Asynchronous interface
Service implementation class
I got a similar "deferred binding" error when I accidentally had an extra method in my Synchronous (regular) interface that was missing in the Async interface and implementation class, but my IDE (IntelliJ IDEA 12) did not flag any files as having errors. When I finally remembered that I had recently removed a method from my service, I went into the Synchronous interface and saw that I had forgotten to remove that method's signature from the synchronous interface. Removing it so that the signatures matched in all three files fixed the Deferred binding error.

Related

Why the default Controller implementation sends crashes with internal error?

I generated controller under rest-api grails app profile. Nothing is changed in controller, just some println calls added.
For call curl -X PUT -d name=petr2 -d phone=338 localhost:8080/TSCell/3 I have {"message":"Internal server error","error":500} response. In debug I can see, that error occured after final respond TSCell, [status: OK, view:"show"] call.
Code for update method:
#Transactional
def update(TSCell tSCell) {
println "in update method"
if (tSCell == null) {
transactionStatus.setRollbackOnly()
render status: NOT_FOUND
return
}
if (tSCell.hasErrors()) {
transactionStatus.setRollbackOnly()
respond tSCell.errors, view:'edit'
return
}
tSCell.save flush:true
respond tSCell, [status: OK, view:"show"]
}
And stack trace
ERROR org.grails.web.errors.GrailsExceptionResolver - IllegalArgumentException occurred when processing request: [PUT] /TSCell/3
Model variable [TSCell] of with value [class zcrm.api.TSCell] type [java.lang.Class] is not of the correct type [zcrm.api.TSCell]. Stacktrace follows:
java.lang.reflect.InvocationTargetException: null
at org.grails.core.DefaultGrailsControllerClass$ReflectionInvoker.invoke(DefaultGrailsControllerClass.java:210)
at org.grails.core.DefaultGrailsControllerClass.invoke(DefaultGrailsControllerClass.java:187)
at org.grails.web.mapping.mvc.UrlMappingsInfoHandlerAdapter.handle(UrlMappingsInfoHandlerAdapter.groovy:90)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
at org.springframework.web.servlet.FrameworkServlet.doPut(FrameworkServlet.java:883)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
at org.springframework.boot.web.filter.ApplicationContextHeaderFilter.doFilterInternal(ApplicationContextHeaderFilter.java:55)
at org.grails.web.servlet.mvc.GrailsWebRequestFilter.doFilterInternal(GrailsWebRequestFilter.java:77)
at org.grails.web.filters.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:67)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
Caused by: grails.views.ViewRenderException: Error rendering view: Model variable [TSCell] of with value [class zcrm.api.TSCell] type [java.lang.Class] is not of the correct type [zcrm.api.TSCell]
at grails.views.AbstractWritableScript.writeTo(AbstractWritableScript.groovy:33)
at grails.views.mvc.GenericGroovyTemplateView.renderMergedOutputModel(GenericGroovyTemplateView.groovy:71)
at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:303)
at grails.views.mvc.renderer.DefaultViewRenderer.render(DefaultViewRenderer.groovy:105)
at grails.artefact.controller.RestResponder$Trait$Helper.internalRespond(RestResponder.groovy:188)
at grails.artefact.controller.RestResponder$Trait$Helper.respond(RestResponder.groovy:98)
at zcrm.api.TSCellController$$EQ0icN2W.$tt__update(TSCellController.groovy:64)
at grails.transaction.GrailsTransactionTemplate$2.doInTransaction(GrailsTransactionTemplate.groovy:96)
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:133)
at grails.transaction.GrailsTransactionTemplate.execute(GrailsTransactionTemplate.groovy:93)
at grails.transaction.GrailsTransactionTemplate$2.doInTransaction(GrailsTransactionTemplate.groovy:96)
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:133)
at grails.transaction.GrailsTransactionTemplate.execute(GrailsTransactionTemplate.groovy:93)
... 14 common frames omitted
Caused by: java.lang.IllegalArgumentException: Model variable [TSCell] of with value [class zcrm.api.TSCell] type [java.lang.Class] is not of the correct type [zcrm.api.TSCell]
at grails.views.WritableScriptTemplate.make(WritableScriptTemplate.groovy:138)
at grails.plugin.json.view.api.internal.DefaultGrailsJsonViewHelper.prepareWritable(DefaultGrailsJsonViewHelper.groovy:736)
at grails.plugin.json.view.api.internal.DefaultGrailsJsonViewHelper$7.writeTo(DefaultGrailsJsonViewHelper.groovy:713)
at grails.plugin.json.view.JsonViewTemplate.json(JsonViewTemplate.groovy:126)
at grails.plugin.json.view.JsonViewTemplate.json(JsonViewTemplate.groovy:149)
at zcrm_api_TSCell_show_gson.run(zcrm_api_TSCell_show_gson:7)
at grails.plugin.json.view.JsonViewTemplate.doWrite(JsonViewTemplate.groovy:35)
at grails.views.AbstractWritableScript.writeTo(AbstractWritableScript.groovy:30)
... 26 common frames omitted
Thanks in advance.
That code shouldn't compile, but Groovy is too 'helpful' sometimes and allowed it through. You named an instance variable the same as its class, TSCell, and this turns out to be an interesting block of code to see how Groovy handles disambiguation between instance and static method calls.
For the first line, since you have TSCell TSCell it's possible for the compiler to know that the one on the left is the class name and the one on the right is an instance variable, since there's no other valid interpretation of those tokens.
In the third line it's not as clear whether the class or instance variable is being checked for null, but I tried this out locally and it's the instance variable.
TSCell.hasErrors() could be interpreted as a static method call on the class or a call on the instance, but since that method isn't static, Groovy invokes it on the instance and it succeeds. The same logic has to be applied to the save call, but again since it's not a static method it's call on the instance and succeeds.
And then on the last line of the method, kaboom, your luck ran out after four successful calls. There are a few overloads of the respond method and you end up calling respond(Object, Map), and that's valid for either TSCell the class, or TSCell the instance of the TSCell class. Groovy picked the one that wasn't what you intended and the one that isn't supported inside the respond method.
Groovy shares Java's variable and class naming conventions, i.e. class names start with an uppercase letter and instance variable names start with a lowercase letter. It's one thing to just tell people that this is a good approach, but an example like this makes it a lot more obvious why it's a bad idea to use uppercase instance variable names (you should be able to look at the variable and not need to see its declaration to know if it's a class or var name) and why it's even worse to use the same name as the class.
This error is probably caused because you named parameter with same name as class name.
I would suggest that you change name of the variable to lowercase (this is groovy and java naming convention).
def update(TSCell tsCell) { //you can also just write tsCell without type
println "in update method"
if (tsCell == null) {
transactionStatus.setRollbackOnly()
render status: NOT_FOUND
return
}
if (tsCell.hasErrors()) {
transactionStatus.setRollbackOnly()
respond tsCell.errors, view:'edit'
return
}
tsCell.save flush:true
respond tsCell, [status: OK, view:"show"]
}
The problem was in the call curl. As documentation says Grails has built in support for Content negotiation using either the HTTP Accept header, an explicit format request parameter or the extension of a mapped URI.
So the adding -H "Accept: application/xml" to the above curl call resolved the issue.

JAXRS tries to call Interface instead of Implementation

I got a JAXRS application. I have an Interface class (SomeResource) (where i put most of my annotations) and an implementation of this interface (SomeService).
I have registered the SomeService.class in the overriden JaxRSApplication method .getClasses();
All my other services/resources are implemented in the same way, but whenever i try to call this one service (SomeService), i get the following exception:
"Error 500: javax.servlet.ServletException: java.lang.IllegalAccessException: Class org.apache.wink.server.internal.handlers.InvokeMethodHandler can not access a member of class package.api.SomeResource with modifiers "public abstract""
As you can see, for some reason, this one Service tries to call the Resource(Interface) instead of the the Service class with the actual implementation.
Anyone got an idea how to resolve this? (Real classnames hidden because of security).
Be sure to declare the implementation class of the service (SomeService.class) with its full qualified classname and not the interface within your rest service configurationen of your application.
The way you have to do that depends on the implementing framework.
Have a look here:
http://cxf.apache.org/docs/jaxrs-services-configuration.html

Sharprepository Autofac InstancePerApiRequest in Webapi environment not working

Does anyone have a working example of sharprepository intergration with autofac using InstancePerApiRequest for DbContext?
I am registering my dbcontext thusly:
builder.RegisterType<AuditTestEntities>().As<DbContext>().InstancePerApiRequest();
If I remove the InstancePerApiRequest, sharprepository is able to get a dbcontext. But with the InstancePerApiRequest, I get the error message pasted below. Basically the crux of the error is, I suspect, the way sharprepository makes the call:
No scope with a Tag matching 'AutofacWebRequest' is visible from the scope in which the instance was requested. This generally indicates that a component registered as per-HTTP request is being requested by a SingleInstance() component (or a similar scenario.) Under the web integration always request dependencies from the DependencyResolver.Current or ILifetimeScopeProvider.RequestLifetime, never from the container itself.
The full error stack:
iisexpress.exe Error: 0 : Operation=DefaultHttpControllerActivator.Create, Exception=System.InvalidOperationException: An error occurred when trying to create a controller of type 'AccountController'. Make sure that the controller has a parameterless public constructor. ---> Autofac.Core.DependencyResolutionException: An exception was thrown while invoking the constructor 'Void .ctor()' on type 'AccountRepository'. ---> Could not resolve type 'System.Data.Entity.DbContext' using the 'AutofacDependencyResolver'. Make sure you have configured your Ioc container for this type. View the InnerException for more details. (See inner exception for details.) ---> SharpRepository.Repository.Ioc.RepositoryDependencyResolverException: Could not resolve type 'System.Data.Entity.DbContext' using the 'AutofacDependencyResolver'. Make sure you have configured your Ioc container for this type. View the InnerException for more details. ---> Autofac.Core.DependencyResolutionException: No scope with a Tag matching 'AutofacWebRequest' is visible from the scope in which the instance was requested. This generally indicates that a component registered as per-HTTP request is being requested by a SingleInstance() component (or a similar scenario.) Under the web integration always request dependencies from the DependencyResolver.Current or ILifetimeScopeProvider.RequestLifetime, never from the container itself.
Okay found the issue. There is a problem with using the SharpRepository AutofacDependencyResolver when using the MVC or Web API integration and trying to use the scope InstancePerApiRequest or InstancePerHttpRequest. Autofac expects those items to be resolved from the System.Web.DependencyResolver.Current instead of from the Autofac IContainer directly as the AutofacDependencyResolver is currently doing.
Here is how you can fix the issue right now until we make an overload for AutofacDependencyResolver that fixes the issue.
You will need to create your own dependency resolver within your project like this one:
public class CustomAutofacDependencyResolver : BaseRepositoryDependencyResolver
{
private readonly IDependencyResolver _resolver;
public CustomAutofacDependencyResolver(IDependencyResolver resolver)
{
_resolver = resolver;
}
protected override T ResolveInstance<T>()
{
return _resolver.GetService<T>();
}
protected override object ResolveInstance(Type type)
{
return _resolver.GetService(type);
}
}
And then register it with SharpRepository so it will use it to resolve the DbContext and then it will work as expected.
RepositoryDependencyResolver.SetDependencyResolver(new CustomAutofacDependencyResolver(DependencyResolver.Current));
** Update**
I was testing with MVC and able to replicate the error and fix it but that doesn't work with Web API. I am used to using StructureMap where it works fine using the GlobalConfiguration.Configuration.DependencyResolver.
It seems the issue is that Autofac needs a IDependencyScope that you can access from the HttpRequestMessage but I'm not seeing a way to get to that outside of the ApiController. This describes the issue and the reason: https://groups.google.com/forum/#!msg/autofac/b3HCmNE_S2M/oMmwFE5uD80J
Unfortunately right now I'm at a bit of a loss on the best way to handle this. But I'll keep thinking about it.
So, I was able to get mine working by changing the lifetime scope to InstancePerLifetimeScope. I don't know whether this has any unforeseen consequences or not. Everything appears to be working fine for me so far.

Problem serialising generated class

I am using GWT 2.3 for my application. I created a generator to generate classes and add behaviour to them.
My generator works fine and I can call GWT.create(MyClass.class) on the client. This does return a MyClassImpl object with the correct fields/methods. When I try to serialise the object to send it back to the server I have a SerializationException.
After debugging it appears that the RPC generator cannot find the class definition for MyClassImpl.
Is there a way of fixing this? I assumed the class definition generated by my own generator would be available to the RPC generator unless this one is run before my generator?
Thank you in advance for your help.
Farid
Hello and thank you for you quick answer,
My generated class is as follows:
- it has a public no arg constructor
- it implements Serializable (and to be sure I tried all combinations of Serializable and IsSerializable)
- is is generated (by my generator when I call GWT.create() ) in a shared package
- All its attributes are "Simple" (primitive or String)
It looks like this (where TestClass is my marker interface for the generator):
package com.test.shared;
import com.test.shared.TestClass;
public class TestClass_Impl implements TestClass, Serializable {
private String testString = "TestString";
public TestClass_Impl() {}
public String getTestString() {
return testString;
}
}
I can call GWT.create(TestClass.class) on the client. I get a instance of TestClass_Impl but as soon as I try to send it over the network to teh server through a GWT RPC call I get an exception:
com.test.server.TestServiceServlet-29927840: An IncompatibleRemoteServiceException was thrown while processing this call.
com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException: java.lang.ClassNotFoundException: com.test.shared.TestClass_Impl
at com.google.gwt.user.server.rpc.RPC.decodeRequest(RPC.java:315)
at com.google.gwt.user.server.rpc.RemoteServiceServlet.processCall(RemoteServiceServlet.java:206)
at com.google.gwt.user.server.rpc.RemoteServiceServlet.processPost(RemoteServiceServlet.java:248)
at com.google.gwt.user.server.rpc.AbstractRemoteServiceServlet.doPost(AbstractRemoteServiceServlet.java:62)
....
Caused by: com.google.gwt.user.client.rpc.SerializationException: java.lang.ClassNotFoundException: com.test.shared.TestClass_Impl
at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamReader.deserialize(ServerSerializationStreamReader.java:573)
at com.google.gwt.user.client.rpc.impl.AbstractSerializationStreamReader.readObject(AbstractSerializationStreamReader.java:119)
...
Caused by: java.lang.ClassNotFoundException: com.test.shared.TestClass_Impl
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at org.mortbay.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:366)
at org.mortbay.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:337)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:247)
at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamReader.deserialize(ServerSerializationStreamReader.java:543)
It looks like GWT RPC cannot find the class TestClass_Impl on the server when it tries to instantiate it.
Any idea?
Thanks,
farid
Thank you Jusio. That is exactly what was going on. GWT seems to generate the java source only for the purpose of cross-compiling it into javascript and then discards the generated java files. There is a compiler option to keep the generated java code in a specific folder but the resulting .java file is not compiled with the build.
It is possible, although very convoluted and clumsy, to change the build process to pick up source files generated by my generator and include them in the build path so they can be compiled and available at runtime.
I have instead created a separate class to generate my java source code. This class is used by the generator to generate the java source to be cross-compiled by GWT. The same class is then used by my application to dynamically generate and load these java classes into the VM. They are then available at runtime and all seems to be working fine.
Thank you again for your help and if anyone needs more information about this workaround I will be happy to send it to them.
I believe the problem is, that generated class should exist on both client and server. That's why you get this error. As far as i know generators don't work on the server side. May be there is a way to make them work, but I don't know about it. Possible solution - launch compiler with -gen option to save generated classes to the disk, compile them to *.class and copy to the server class path. Or don't use GWT-RPC =)
Ensure that your generator makes the generated class IsSerializable (i.e., implements the IsSerializable interface).

Autofac: Is there a hidden debug feature?

I remember I have read somewhere here in SO (maybe I was dreaming) that I can enable a "hidden" debug feature of Autofac, so that it can give me more information on what Autofac is doing in the background.
I asked because I just encountered a bug in my project. After I have added the following code into my AutofacModule:
builder.RegisterAssemblyTypes(typeof(MainWindowViewModel).Assembly)
.AssignableTo(typeof(ViewModelBase))
.EnableClassInterceptors()
.InterceptedBy(typeof(NotifyPropertyChangedInterceptor));
when compile, at:
using (var container = builder.Build())
{
...
}
Autofac throws:
System.NotSupportedException was unhandled. Parent does not have a default constructor. The default constructor must be explicitly defined.
But it didn't tell me which class does not have a default constructor (maybe I have missed something in the output window?). I ended up opened all my ViewModel classes one by one... to check if they have a default constructor.
So it would be wonderful for me if Autofac has a hidden debug feature. If not, is there an automatic way to find all classes which don't have a default constructor?
Thanks
(sorry for my English)
this isn't an Autofac exception - it looks like it might be a WPF one? If you can get the call stack from the debugger when the exception is thrown it should offer a clue.
Cheers!