Why does default AsyncController's index not work in Grails? - asynchronous

I came back to Grails after [oh so many] years, and was happy to find the Async Controllers.
I wanted to experiment, so I have created a very simple domain class:
class ClientDevice implements AsyncEntity<ClientDevice> {
int width
int height
static constraints = {
}
}
And generated the default async controller and views.
Upon running the app using grails run-app, I've browsed to http://localhost:8080/clientDevice/index, and I'm getting HTTP Error 500.
I've looked at the logs - nothing.
The http://localhost:8080/clientDevice/create page works fine, but saving new clientDevice does not work.
I'm using the default development devDb H2 memory database.
This is happening on Grails 3.3.3 with Java 1.8_161
Any tips? I was really looking forward to trying the async stuff.

Related

Blazor Fails to Connect to Server When Component Parameter is Too Big

I'm running a .NET 6 MVC app with a few Blazor components. All of them work fine, except one.
In a view, I embed the problematic component like so, passing in two parameters, Students and IsUserPartner.
<component
type="typeof(IndexRoster)"
render-mode="ServerPrerendered"
param-Students="#Model.Students"
param-IsUserPartner="#User.IsInRole("Partner")"
/>
The component seems to render fine initially, but after a second or two the app disconnects and the page displays the message, "Attempting to reconnect to the server...".
I figured out that it's the Students parameter that's the culprit, because when I remove it, the app works fine. This parameter is a List of DTOs:
public class StudentIndexDTO {
public List<StudentDisplayDTO> Students { get; set; }
// ...
}
What's most interesting is that substantially limiting the amount of items in the Students List with param-Students="#Model.Students.GetRange(0, 10)", also fixes the issue. So, it seems that it's not a problem with the List per se, but rather with its size. Unfortunately, I can't limit the amount of items fetched from the Student List; the app needs to display all of them (400 - 1,000).
The only other solution I was able to come up with is setting the render mode to Static, but again, that's not an adequate solution since it removes other necessary functionalities.
So, how can I pass the full List to my component without causing the app to disconnect?
I seem to have found a workaround thanks to the suggestion of #MisterMagoo. In the Blazor component, within OnInitializedAsync(), I made an async request to a backend Controller Action using HttpClient, which then populates the Students List with the response.

Migrated from Glide 3 to 4 and having a AbstractMethodError when launching the app

I have an application using Glide 3.8.0 and I've just migrated it to 4.8.0. After migrating all the code to use the new Glide's API, I've found that my app launches this error when trying to load an image from the network:
java.lang.AbstractMethodError: abstract method "void com.bumptech.glide.module.RegistersComponents.registerComponents(android.content.Context, com.bumptech.glide.Glide, com.bumptech.glide.Registry)"
at com.bumptech.glide.Glide.initializeGlide(Glide.java:268)
at com.bumptech.glide.Glide.initializeGlide(Glide.java:221)
at com.bumptech.glide.Glide.checkAndInitializeGlide(Glide.java:182)
at com.bumptech.glide.Glide.get(Glide.java:166)
at com.bumptech.glide.Glide.getRetriever(Glide.java:680)
at com.bumptech.glide.Glide.with(Glide.java:732)
at com.fewlaps.android.quitnow.usecase.main.MainActivity.updateAvatar(MainActivity.java:356)
etc...
I've done the setup explained in the official documentation. As it requests, I wrote a class that extends AppGlideModule, it's annotated by #GlideModule, and it's empty. Empty? The official documentation says:
You’re not required to implement any of the methods in AppGlideModule for the API to be generated. You can leave the class blank as long as it extends AppGlideModule and is annotated with #GlideModule.
According to the Error's message, my issue is related with registerComponents() for sure, but I also tried to implement it with a blank implementation, and the issue remains.
As explained in AppGlideModule's JavaDoc (and as far as I know, only there...), if you are done with the migration from 3.x.x to 4.x.x, you have to implement isManifestParsingEnabled() returning false.
So, you'll end with a CustomAppGlideModule like this one:
#GlideModule
public class QNGlideModule extends AppGlideModule {
#Override
public boolean isManifestParsingEnabled() {
return false;
}
}

web api calls routing to wrong method

I have a webapi controller which goes against the default webapi convention to expose a few different "get" methods
[HttpGet]
[WebAPIValidateAntiForgeryTokenAttribute]
public Manufacturer[] GetManufacturers()
{
var profiler = MiniProfiler.Current;
using (profiler.Step("WCF Service Call: GetManufacturers"))
{
return IvService.GetManufacturers();
}
}
[HttpGet]
[WebAPIValidateAntiForgeryTokenAttribute]
public Range[] GetRanges(string manufacturer_code)
{
var profiler = MiniProfiler.Current;
using (profiler.Step("WCF Service Call: GetRanges"))
{
return IvService.GetRanges(manufacturerCode);
}
}
They are very simple methods which are called from Javascript and make another call out to an external system via WCF, then return the result. This has been working fine on dev for a while but recently stopped working- both calls from javascript to GetManufacturers and GetRanges now hit the same break point in GetManufacturers. I checked fiddler and its definitely calling the correct url.
Some refactoring had taken place to enforce some coding standards to do with parameter names and the call from javascript had been adjusted to from
VehicleController/GetRanges?manufacturer_code=AB
to
VehicleController/GetRanges?manufacturerCode=AB
without adjusting the corresponding webapi method. At first I had suspected this was some weird routing issue but it turns out because the parameters names no longer contained anything it recognized, it resolved to the only method which didn't required any parameters, which makes sense but kept me scratching my head for a little while!

Custom Assetic Filter Development - Constantly Cached?

I'm having an issue with my development of a custom assetic filter. I loosely followed the steps in the blog article found here and got things working for the most part. The thing that's causing me hang up is the fact that if I make a change to the filterLoad or filterDump methods it usually shows up the first time but additional changes won't. It seems like things are getting cached but not in the usual Symfony2 cache directory. This is pretty vague so far so let me know if there's any additional information I can provide.
Example of change:
public function filterLoad(AssetInterface $asset)
{
$asset->setContent('this');
}
public function filterDump(AssetInterface $asset)
{
$asset->setContent('that');
}

Setting the WebServiceWrapper endpointURI at run time

I'm in the middle of switching from Flex Builder 3 to Flash Builder 4, and one of the problems I have run into is that support for web services in 4 is substantially different. In both IDE's I am able to import a WSDL for my web service and it will generate the appropriate client classes for communicating with the service. The generated code in each is different.
In my Flex3 code I was able to access the endpointURI property of the mx.rpc.soap.AbstractWebService, but in the Flex4 code that is generated, the new class extends com.adobe.fiber.services.wrapper.WebServiceWrapper which does not have the endpointURI property.
My project has mulitple game servers and the player picks which server they want to play on. In the past if the player wanted server 1, I would set the endpoint URI to http://game1.server.com/service.asmx, and like wise if they wanted server 2 I would set the endpoint to http://game2.server.com/service.asmx.
What am I looking for to accomplish this in Flash Builder 4?
Short Answer:
var s:ClassThatExtendsWebServiceWrapper = new ClassThatExtendsWebServiceWrapper;
s.serviceControl.endpointURI = 'http://service.com/service.asmx';
Long Answer:
Well I finally found a solution. Adobe seems to have made this much harder than it should have been.
Web Service classes that are generated by Flash Builder 4 extend the com.adobe.fiber.services.wrapper.WebServiceWrapper. WebServiceWrapper has a property called serviceControl that can be used to control the service. The problem is that not all the members of serviceControl are accessible at the application code level. Lets assume that I have a web service called GameService. When I use the data tool to connect to the web service by providing a WSDL, Flash Builder will create two classes for me automcatically.
internal class _Super_GameService extends
com.adobe.fiber.services.wrapper.WebServiceWrapper
{ ... }
public class GameService extends _Super_GameService
{}
_Super_GameService contains all the automatically generated code to make calls to the web service. GameService contains no code itself, but unlike _Super_GameService, it is public. The idea here is that any enhancements that we need to make can be made to GameService, then later on if we need to update, _Super_GameService can be regenerated, but out changes to GameService will not be overwritten by the code generation tool.
Now this leads us to usage of these generated classes. Typically all I should have to do is create an instance of GameService and call a method on it. In this example DoSomethingAwesome is a method available on the web service.
var gs:GameService = new GameService();
var token:AsyncToken = gs.DoSomethingAwesome();
Now this will call the service using the URI of the service specified in the WSDL file. In my situation I wanted GameService to connect to a different URI. This should have been simple, but things fell apart.
My first problem was that viewing the documentation on WebServiceWrapper (http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/com/adobe/fiber/services/wrapper/WebServiceWrapper.html) did not render properly in Firefox. So when I was reading the documentation I wasn't getting the full picture. This really needs to be fixed by Adobe.
Viewing the documentation in another browser helped me find out about the serviceControl property of WebServiceWrapper. serviceControl is declared as a mx.rpc.soap.AbstractWebService. AbstractWebService does have an endpointURI property which makes the following code valid.
var gs:GameService = new GameService();
gs.serviceControl.endpointURI = 'http://game1.service.com/GameService.asmx';
The other problem I had is that for some reason the endpointURI property of serviceControl does not appear in the Intellisense context menu. So since I didn't see serviceControl in the online documentation at first, and I didn't see endpointURI in intellisense, I didn't realize the property was there to be set.
If you look at the source for AbstractWebserivce, (http://opensource.adobe.com/svn/opensource/flex/sdk/trunk/frameworks/projects/rpc/src/mx/rpc/soap/AbstractWebService.as) there doesn't seem to be an Exclude tag to explain why endpointURI does not appear in the Intellisense context menu. So I don't know what is going on there.
You should be able to override the endpointURI on the WebService. But I'm not sure where to do that with the generated code since I use <s:WebService/>.
This is the only way I could get it to work, in the generated stub for your service:
import com.adobe.fiber.core.model_internal;
Also:
/**
* Override super.init() to provide any initialization customization if needed.
*/
protected override function preInitializeService():void
{
_needWSDLLoad = false; // to prevent loading the default WSDL
super.preInitializeService();
// Initialization customization goes here
wsdl = "http://localhost/yourservice?wsdl";
_needWSDLLoad = true;
model_internal::loadWSDLIfNecessary();

Resources