Flex: Unexpected leakage with RemoteObject + IExternalizable? - apache-flex

I've been tinkering with IExternalizable, but I've noticed some unexpected behavior. I've got this class:
public function readExternal(input:IDataInput):void {
input.readObject();
input.readObject();
input.readObject();
}
public function writeExternal(output:IDataOutput):void {
output.writeObject("first string");
output.writeObject(424242);
output.writeObject("second string");
}
But when I try to serialize this class using AMF and send it to a remote server (via RemoteObject), Charles shows me that the request looks like this:
unexpected result http://img.skitch.com/20100406-cjawastycagp1x2chbe76k2suu.png
But it seems wrong that my serialized object is leaking out into the rest of the request.
So, what am I doing wrong? Is there some part of the documentation I've missed?

You code seems fine, however you should serialize using the proper methods (writeUTF for strings, writeInt for int etc). Anyway Charles seems to not work properly with objects implementing IExternalizable (I'm using version 3.4.1), so you should not rely on what it is showing.
Not directly related to your question - do you really need to use IExternalizable? You are going to lose some benefits related to AMF compression algorithm (unless you are not going to implement all this things in your writeExternal method).

Related

Is it possible to serialize an object into data which will be passed to the compiler pass?

I have a symfony bundle which needs to store a lot of data. Currently said data is stored as arrays, read and put into the memory of a service. While this approach works, it's not very readable.
It's not possible to simply set an argument to a list of X, as such I'm unable to store said data in a better way.
My data will not change between cache compiles, so I was wondering if there's anything where I can do something like the following
class MyModel {
public function __construct(
public readonly string $from,
public readonly string $to
) {}
}
// on compiler pass
$model = new MyModel('aaa', 'bbbb');
$myDefinition->addMethodCall('myMethod', [[$model], $otherScalarArguments]);
I was also wondering if Symfony's expressions could help in this case, but I'm unsure.
My current use of ->addMethodCall has 7 arguments, so this would make my life easier.
At first I thought the container could handle this sort of thing so I reproduced the issue and got:
Unable to dump a service container if a parameter is an object or a resource.
So even though you can pass an object as an argument, the caching code which writes the compiled container out as a php file is not smart enough to handle it. Note: it is often useful to add error messages to questions.
The trick is to serialize the object in the pass itself and then unserialize it in the service.
class MyService
{
private MyModel $myModel;
public function __construct(string $myModel)
{
$this->myModel = unserialize($myModel);
dump($this->myModel);
}
}
# pass
$model = serialize(new MyModel('aaa', 'bbbb'));
$def = $container->getDefinition(MyService::class);
$def->addArgument($model);
I tested it and it all seemed to work. I did take take the liberty of simplifying the original code a bit but it will work work just fine for addMethodCall as well.
Might be worthwhile proposing this to the Symfony core group. It is niche functionality but might come in handy now and then.

Dart: Code design for interface to construct objects from HTTP requests

I'm trying to implement an abstract base class for objects that will be parsed from HTTP calls. The goals is to create a CachedFuture<T> class that, when accessed, makes an HTTP call to get the object and caches the result.
My inclination was to implement the classes as follows:
class HTTPGetable<T extends HTTPGetable<T>> {
static Future<T> httpGet(int id);
}
class CachedFuture<T extends HTTPGetable<T>> {
int _id;
Future<T?>? _cachedResult;
bool _has_already_made_request;
CachedFuture({required int this._id});
Future<T?> get() {
if(this._cachedResult == null)
try {
this._cachedResult = T.httpGet(this._id);
} except {
// parse error or other error
this._cachedResult = CompletableFuture.completedFuture(null);
}
}
return this._cachedResult;
}
}
The intuition here is that there are a lot of objects with "pointers" to other objects in the database on the backend. It doesn't make sense to follow every pointer when constructing objects to return in the HttpRequest, so my intent is to wrap "pointers" in this CachedFuture class.
This should enable someone to "follow" one of these "pointers" without ever having to worry about caching the http request or about the specifics of constructing that request. Hopefully this provides another level of abstraction for the user of the class so they can right code that's agnostic to what's going on under the hood.
However, static interfaces aren't in Dart, so this pattern doesn't work. My intuition is that this is a sign I should be using a different pattern instead of trying to force my way.
httpGet is basically a factory method, but the functionality of CachedFuture needs a way to look up the factory from the type, so I don't immediately see a good way to implement a true factory either.
Could anyone recommend a good programming pattern for solving this? I imagine it's a pretty common usecase for both http requests and database requests.
Update: The best workaround I've found is to do different "factories" to httpGet each T, then use reflection to look up the appropriate factory. However, as the description sounds, this seems pretty convoluted & error prone, so I'm still convinced that there's almost certainly a better pattern to use.
Can't you just create the abstract class CachedFuture along the lines of what you wrote, with an abstract method httpGet(int id) to be implemented by the subclass?
If there is only ever one instance of an object of type <T extends CachedFuture> then you could consider making the subclass a Singleton.
Apologies if I misunderstood your question!

Is there any difference between Request.Cookies(name) and Request.Cookies.Get(name)?

As both of them can be used for retrieving cookie through name string, I would like to know if there is any difference between them.
A great way to answer a question like this yourself, for the .NET Framework, is to make use of the Microsoft Reference Source. This lets you see and navigate through the source for the .NET Framework.
Looking at this, Request.Cookies returns an HttpCookieCollection and Request.Cookies.Get is therefore a method on HttpCookieCollection.
The most useful part of the code is for the indexer on HttpCookieCollection that retrieves a cookie by name:
public HttpCookie this[String name]
{
get { return Get(name);}
}
As you can see from that, this calls into the Get(string name) method, meaning that using the Request.Cookies(name) indexer is fundamentally the same as using Request.Cookies.Get(name) as one calls the other.
It is worth mentioning that anything you see here is an implementation detail that's subject to change. You should rely on documented behaviour, not on anything you discover through digging through the code, no matter how informative and interesting it is!

SonarQube complains about using ResponseEntity with a wildcard

I use SpringBoot for REST web services development and SonarQube for static analysis.
I have a few endpoints in my application that look the following way:
#PostMapping
ResponseEntity<?> addSomething(#RequestBody Some object) {
// some code there
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
SonarQube complains about using ResponseEntity with a wildcard, reporting me a Critical issue "Generic wildcard types should not be used in return parameters".
I wonder if I should disable this verification in SonarQube or come up with something different for return type for these cases.
What do you think about it?
#PostMapping
ResponseEntity<Object> addSomething(#RequestBody Some object) {
// some code there
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
This will also remove the error. It is still very generic, but it is one of the solutions if you want to return different types based on the outcome. For instance:
#PostMapping
ResponseEntity<Object> addSomething(#RequestBody Some object) {
//Will return ResponseEntity<> with errors
ResponseEntity<Object> errors = mapValidationService(bindingResult);
if (!ObjectUtils.isEmpty(errors)) return errors;
// some code there
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
So actually i find the rule pretty self describing:
Using a wildcard as a return type implicitly means that the return value should be considered read-only, but without any way to enforce this contract.
Let's take the example of method returning a "List". Is it possible on this list to add a Dog, a Cat, ... we simply don't know. The consumer of a method should not have to deal with such disruptive questions.
https://sonarcloud.io/organizations/default/rules#rule_key=squid%3AS1452
So Actually in your case, you do not want any kind of Class in there, you specifically want an Serializable-object - for obvious reasons: it should be serialized later on
So instead of using ? it would be more suitable in your case to use Serializable. This is always case dependent, but normally you definitly expect some kind of common interface or base class as a return value. Hence that, the follow up developer, definitly knows what he can expect, and what kind of functionality he definitly can use.
Finally I've removed <?> from return value, so the code looks like the following now:
#PostMapping
ResponseEntity addSomething(#RequestBody Some object) {
// some code there
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
SonarQube doesn't complain anymore and code seems a little bit simpler now.

NHibernate.IFutureValue<> when serialized includes .Value

I'm building an ASP.NET (2.0, no, I can't change it) site with NHibernate, and have a custom JSON converter so I can not-serialize properties I want hidden from the client. This lets me just return the objects, and never have to worry about their serialized values - they're always secure.
Unfortunately, it appears that if I use query.FutureValue<class>(), the object that gets serialized is first the NHibernate.Impl.FutureValue<class> and not my entity, which means I get JSON that looks like this if I throw it in a dictionary and return it to the client:
{key: { Value: { /* my serialized object properties */ } }
Previously I discovered that I can't get any interfaces to work in ASP's JavaScriptConverter implementations... only regular or abstract classes. So returning typeof(IFutureValue<MyBaseClass>) as a supported type means my converter is completely ignored. I can catch MyBaseClass, because I refactored things earlier to use an abstract base instead of an interface, but not the interface.
And then I discover that the FutureValue implementation in .Impl is internal to the assembly, or some other such nonsense that only serves to make my .NET experience even more painful. So I can't use typeof(FutureValue<MyBaseClass>) to handle it all, because FutureValue exists only in my debugging sessions.
Is there a way to get the class type out of the assembly? Or a way to convince ASP that interfaces do in fact have uses? Or might there be some superclass I can access that would let me get around the whole issue?
Help! I like my Futures, it lets me batch a whole heck-ton of calls at once!
(if something isn't clear, or you want more code, by all means, ask! I can post quite a bit.)
If I'm understanding you correctly, it seems you are mixing things a together a little bit.
It sounds like you're trying to serialize an instance of query.FutureValue<class>(), which unsurprisingly gives you just that: a JSON object where the Value fields has JSON representing your entity.
To me it sounds like you really want to just serialize query.FutureValue<class>().Value.
Using NHibernate futures like this gives you little benefit though, so you're probably after something like:
var future1 = query1.FutureValue<SomeEntity>();
var future2 = query2.FutureValue<AnotherEntity>();
var json1 = serializer.Serialize(future1.Value); //<BAM! Multi-query gets fired!
var json2 = serializer.Serialize(future2.Value);
Does that make sense?

Resources