RazorEngine extension method fails with RuntimeBinderException after upgrade to Razor 2/ RE 3.2 - razor

I have a RazorEngine project that fails following an upgrade to Razor 2.0 and RazorEngine 3.2.0
This worked fine in the previous Razor 1.0 based version of RazorEngine (3.0.8).
I have an instance (myInstance) of a class (MyClass) and and extension method:
namespace MyCompany.Extensions
{
public static class MyClassExtensions
{
public static string ExtensionMethod(this MyClass thing)
{
// do stuff
}
}
}
I want to call this in a RazorEngine view (simplified example, there are loads of these methods, and all fail the same way):
#using MyCompany.Extensions
#using MyCompany
#{
var myInstance = new MyClass(Model, ...);
}
Some text #myInstance.ExtensionMethod() some more text
This is in a text file that's compiled by RazorEngine:
string parsedResult = RE::Razor.Parse(fileContent, myModel, "testfile.txt");
The problem is that this line (which used to work) throws a RuntimeBinderException:
'MyCompany.MyClass' does not contain a definition for 'ExtensionMethod'
Note that if I change the text file to:
Some text #MyClassExtensions.ExtensionMethod(myInstance) some more text
It works fine, so I think it must find the extension method's namespace.
My first thought was that it must be considering the passed model as a dynamic (and hence anything derived from it as dynamic too), but it knows the expected type in the RuntimeBinderException. As the exception is run-time I think it must be failing to identify the extension method while the template is compiled, but why would that have changed?
I'm not sure what's changed between 3.0.8 and 3.2.0, or why this is broken. Is there something I need to add so that the extension method can be found while the template is compiled?

This is a bug in RazorEngine: the Razor.Compile works on TemplateBase<dynamic> (so Model and everything derived from it is dynamic too) and that means that no extension methods undergo the 'compiler-magic' to convert them to the static calls. Then Razor.Run passes the Model as the correct type, but the extension method syntax is called as an instance method.
There will probably be a fix for this soon (the bug's only a few days old and this is a corner case), but in the meantime I have a workaround: explicitly type the Model in the Razor template
#using MyCompany.Extensions
#using MyCompany
#{
ExpectedModelClass strongTypeModel = Model as ExpectedModelClass;
MyClass myInstance = new MyClass(strongTypeModel , ...);
}
Some text #myInstance.ExtensionMethod() some more text
This now works, because even though Model is still dynamic at compile-time that doesn't spread to myInstance any more.
It's not ideal, and everywhere I used Model now has to be strongTypeModel, but that's a much simpler substitution.

Related

Unexpected behaviour from Gson

I developed a small application that stores data coming from a device: I chose to store data in JSON format, and the serialization/deserialization of the data works just fine, even if it involves some custom types created by me...but only I work in the IDE (Eclipse, for that matter).
When I export a runnable JAR file though, the deserialization of the data encounters some kind of problem, because the software always throws this exception:
Caused by: java.lang.UnsupportedOperationException: Cannot allocate class LocalDateTime
at com.google.gson.internal.UnsafeAllocator$4.newInstance(UnsafeAllocator.java:104)
at com.google.gson.internal.ConstructorConstructor$14.construct(ConstructorConstructor.java:225)
... 88 common frames omitted
I thought I'd encounter problems with custom types, not a built-in one. At this point, I discovered two things:
if I use a full JRE 9 to run the JAR file, the exception is not thrown: I double checked the modules included in the custom JRE I created with Jlink.exe, and everything is included correctly. I still want to use a smaller JRE, so I did not investigate further yet (I guess this explains why in the IDE it works perfectly)
I added a custom deserializer to the Gson object (see below), with which I simply manually converted the JSON string into a valid data, and that avoided the exception on the LocalDateTime class...but the exception reappeared simply on another class, this time a custom-made one.
At this point, I guess I can simply add a deserializer for each data type that causes problem, but I'm wondering why the issue won't happen with a full JRE, and why a smaller JRE causes this, even if all the modules required are included. Maybe it's worth mentioning also that I added no custom serializer to the Gson object that saves the data, it is all serialized as per Gson default.
LocalDateTime deserializer:
#Override
public LocalDateTime deserialize(JsonElement json, java.lang.reflect.Type type,
JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
JsonObject joDate = json.getAsJsonObject().get("date").getAsJsonObject();
JsonObject joTime = json.getAsJsonObject().get("time").getAsJsonObject();
//JSON example: {"date":{"year":2019,"month":1,"day":9},"time":{"hour":6,"minute":14,"second":1,"nano":0}
return LocalDateTime.of(joDate.get("year").getAsInt(),
joDate.get("month").getAsInt(),
joDate.get("day").getAsInt(),
joTime.get("hour").getAsInt(),
joTime.get("minute").getAsInt(),
joTime.get("second").getAsInt(),
joTime.get("nano").getAsInt());
}
}
Jdeps.deps modules list:
com.google.gson
java.base
javafx.base
javafx.controls
javafx.fxml
javafx.graphics
org.slf4j
After the answer I received, I opened an issue here.
TL;DR
You need a runtime image (e.g. full JDK or something built with jlink) that includes the module jdk.unsupported.
Full Answer
GSON wants to create instances of classes it deserializes without calling any constructors (so nothing gets initialized without GSON saying so). This can't normally be done, but sun.misc.Unsafe offers a way to do this with the method allocateInstance. To that end, GSON needs an instance of sun.misc.Unsafe. The topmost frame in the call stack is from UnsafeAllocator, which uses common trickery to get Unsafe.
The problem is, sun.misc.Unsafe is in module jdk.unsupported, which is present in a full JDK but you won't usually find in runtime images.
When creating your runtime image with jlink, make sure to include the option --add-modules jdk.unsupported and you should be good to go.
Arguably, GSON should declare an optional dependency on jdk.unsupported with requires static.
I have faced the same issue when packing compose a desktop application.
update build.gradle file, add an unsupported module.
compose.desktop {
application {
mainClass = "MainKt"
nativeDistributions {
targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb)
packageName = "admin"
packageVersion = "1.0.0"
modules("java.sql")
modules("jdk.unsupported")
}
}
}

ASP.NET 5: Configuring IdentityServer3 authentication

I've just started digging into the new ASP.NET 5 by creating a test single page application with the OAuth login. I already know that I can use IdentityServer3 for that purpose and it seems pretty nice. I've found a post by Dominick Baier which is explaining how to set up the IdentityServer3. However, the post seems to be out of date or the identity server itself isn't working with the latest version of the ASP.NET 5 (which is beta7 at the moment).
The problem is, when I try to configure the IdentityServer in the Startup.cs I got an error from VS telling me that IApplicationBuilder has no extension method called UseIdentityServer. And this seems to be true, since in the IdentityServer3 source code they have this extension method declared for IAppBuilder (not IApplicationBuilder).
Here is my code (Startup.cs):
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
// Add MVC to the request pipeline.
app.UseMvc();
var options = new IdentityServerOptions
{
Factory = new IdentityServerServiceFactory()
};
app.UseIdentityServer(options);
}
And the error (on the last line) is
'IApplicationBuilder' does not contain a definition for 'UseIdentityServer' and the best extension method overload 'UseIdentityServerExtension.UseIdentityServer(IAppBuilder, IdentityServerOptions)' requires a receiver of type 'IAppBuilder'
Obviously, if I change the parameter type in the Configure method to IAppBuiler, it'll throw a runtime error because the dependency injection will not be able to inject that type. Even if it would, I'd lose the UseMvc() extension method.
So could you point me in the right direction please?
Perhaps I'm just missing something tiny but crucial here.
Thanks in advance!

WINRT XAML System.Void Compile Error in

after a little code change inside a Store App I ran into a compilation error:
-> System.Void cannot be used from C# -- use typeof(void) to get the void type object.
Problem is: this comes from a generated file: XamlTypeInfo.g.cs.
case "System.Void"
userType= new ... ,typeof(global::System.Void), ...
...
Rolling back the changes did not help, as deleting bin & obj, restarting, etc.
Is the actual System.Void case entry maybe an indicator that something within a XAML file could not be recognized by the code generator? Is there an System.Void entry in a working XamlTypeInfo.g.cs?
--- ADDITION ---
I can now produce the compile error when changing specific lines. I have a custom control deriving from ItemsControl. I define a regular DP which works fine. I am also providing AttachedProperties for Template, TemplateSelector and Style. Think of a Textbox that gets an Label via an AttachedProperty and its not just a string but like HeaderedControls you can define a Template etc. for the Lable.
The Problem is related to the Get/Set Methods for the AttachedProp. When I either change the Getter return type to DataTemplate or I comment out the Setter fully then the compile error comes:
public static DataTemplate GetLabelTEmplate(UIElement element)
{
return (DataTemplate)element.GetValue(LabelTemplateProperty;
}
public static void SetLabelTemplate(UIElement element, object value)
{
element.SetValue(LabelTemplateProperty, value);
}
Any ideas would be highly appreciated.
Best regards
Gope
After filing a bug complaint with microsoft they pointed me to the problem: The setter's value cannot be of type object. This information is needed for the XamlTypeInfo generation so when I changed object to DataTemplate it compiled.
Although I haven't tried it yet, I believe object is fine for plain WPF, but for Win 8 Store apps this does result in an compilation Error. Funny stuff... :)

How to map the PHP DateTime class to ActionScript / Flex Date class using Zend Framework AMF

Background
Okay I'm one of those guys who NEVER asks questions and who can usually find what I need from existing questions or forums....but alas I have spent the last few days trying to figure this one out and have come up with very little existing information.
I am using Flash Builder 4.6 for PHP Premium to build a Flex application that uses the PHP Zend Frameworks's AMF capabilities to map classes from PHP to Flex and to use them as objects to send back and forth instead of using XML or JSON. Right now I am doing it all on a single local machine for ease.
Issue
I am not having trouble mapping my own custom PHP classes into ActionScript/Flex classes but I cannot for the life of me manage to map a DateTime PHP class into an ActionScript Date class. I have read elsewhere that it automatically maps DateTime objects to Date objects but I have never gotten it to work.
Strangely though, I can get it to work if I replace all instances of, in my case, valueObjects.DateTime (the auto-generated ActionScript class) to Date in the _Super_Foo.as class that has the DateTime property. This basically forces Flex to interpret the data of that property as a Date. However, since all the _Super_XXX.as files are files that autogenerated by Flex, it gets rewritten any time I refresh or edit ANY PHP service that Flex is linking to in Flash Builder.
Remarks
I could of course do this the quick and dirty way by keeping the variable as a string (it's coming from MySQL in a DateTime field) and then just create some functions to convert it to a Date object on the client side but I need a more permanent and stable solution.
Example:
<?php
class Foo {
public $id; // int
public $name; // string
public $date; // DateTime
public $bar; // custom object
}
?>
should go to --->
package {
class Foo {
public var id:int;
public var name:String;
public var date:Date; // native class
public var bar:Bar;
}
}
but I am getting
package {
class Foo {
public var id:int;
public var name:String;
public var date:DateTime; // custom class
public var bar:Bar;
}
}
I have tried things such as the following:
in the gateway.php file
$server->setClassMap("Date", "DateTime");
using the Zend_Date object instead
$foo->date = new Zend_Date($blah);
and after trying to map it as well explicitly
$server->setClassMap("Date", "Zend_Date");
the change I currently have working in the _Super_Foo.as file (which gets written over frequently)
private var _internal_date : valueObjects.DateTime; // custom object
to
private var _internal_date : Date; // native object
I just need it to do this automatically like I have read it should.
Well I have to admit, that I usually use BlazeDS on Java and not Zend, but I have had similar problems in transfering Calendar objects (I wanted to prevent loosing the timezone data). For This BlazeDS supported so-called PropertyProxys, which are components that allow to takeover the serialization/deserialization process for certain types.
I would assume that ZEND would support a similar thing. So another option would actually be to make Zend zupport the full Flex type. I have searched a little and it seems that the entire terminology is different in Zend, but I think this stackoverflow article should explain it a little: Zend AMF custom dispatcher
Chris
In my experience, Zend Framework has taught me that it offers many features but many times they don't work exactly how you'd expect. For example:
Recently I was working with a bug in "digitalus-cms" (A blog-like framework built on top of ZF) that it couldn't post new articles with a hyphen in their title name. I tracked it down to Zend_Form_Element::filterName. It uses a regular expression that matches any character that falls into the category of: [^a-zA-Z0-9_\x7f-\xff] then removes it. This ends up removing hyphens from the names of form elements which wound up being the cause of the bug.
If Zend_Amf or Zend_Date doesn't work the way you want it to, find a workaround such as passing a unix timestamp number around so everything works the way it should. Then afterwards, you can write a class to extend off one of Zend's classes. Zend Framework is meant to be extended upon, that's the way the framework was built so you can fix issues like these on your own to get the framework to behave how you want it to. That's the whole point of wrappers. Go ahead, create some of your own wrapper classes and toss in some methods to interact with ZF so you can fine-tune everything.
As far as finding the cause of your issue, all I can tell you is keep on debugging and isolating code so you know what you are passing flex, and how flex responses to that. After you play around with it enough, I'm sure you'll find the culprit.
AmfPHP automatically maps it. http://www.silexlabs.org/amfphp/

Registering derived classes with reflection, good or evil?

As we all know, when we derive a class and use polymorphism, someone, somewhere needs to know what class to instanciate. We can use factories, a big switch statement, if-else-if, etc. I just learnt from Bill K this is called Dependency Injection.
My Question: Is it good practice to use reflection and attributes as the dependency injection mechanism? That way, the list gets populated dynamically as we add new types.
Here is an example. Please no comment about how loading images can be done other ways, we know.
Suppose we have the following IImageFileFormat interface:
public interface IImageFileFormat
{
string[] SupportedFormats { get; };
Image Load(string fileName);
void Save(Image image, string fileName);
}
Different classes will implement this interface:
[FileFormat]
public class BmpFileFormat : IImageFileFormat { ... }
[FileFormat]
public class JpegFileFormat : IImageFileFormat { ... }
When a file needs to be loaded or saved, a manager needs to iterate through all known loader and call the Load()/Save() from the appropriate instance depending on their SupportedExtensions.
class ImageLoader
{
public Image Load(string fileName)
{
return FindFormat(fileName).Load(fileName);
}
public void Save(Image image, string fileName)
{
FindFormat(fileName).Save(image, fileName);
}
IImageFileFormat FindFormat(string fileName)
{
string extension = Path.GetExtension(fileName);
return formats.First(f => f.SupportedExtensions.Contains(extension));
}
private List<IImageFileFormat> formats;
}
I guess the important point here is whether the list of available loader (formats) should be populated by hand or using reflection.
By hand:
public ImageLoader()
{
formats = new List<IImageFileFormat>();
formats.Add(new BmpFileFormat());
formats.Add(new JpegFileFormat());
}
By reflection:
public ImageLoader()
{
formats = new List<IImageFileFormat>();
foreach(Type type in Assembly.GetExecutingAssembly().GetTypes())
{
if(type.GetCustomAttributes(typeof(FileFormatAttribute), false).Length > 0)
{
formats.Add(Activator.CreateInstance(type))
}
}
}
I sometimes use the later and it never occured to me that it could be a very bad idea. Yes, adding new classes is easy, but the mechanic registering those same classes is harder to grasp and therefore maintain than a simple coded-by-hand list.
Please discuss.
My personal preference is neither - when there is a mapping of classes to some arbitrary string, a configuration file is the place to do it IMHO. This way, you never need to modify the code - especially if you use a dynamic loading mechanism to add new dynamic libraries.
In general, I always prefer some method that allows me to write code once as much as possible - both your methods require altering already-written/built/deployed code (since your reflection route makes no provision for adding file format loaders in new DLLs).
Edit by Coincoin:
Reflection approach could be effectively combined with configuration files to locate the implmentations to be injected.
The type could be declared explicitely in the config file using canonical names, similar to MSBuild <UsingTask>
The config could locate the assemblies, but then we have to inject all matching types, ala Microsoft Visual Studio Packages.
Any other mechanism to match a value or set of condition to the needed type.
My vote is that the reflection method is nicer. With that method, adding a new file format only modifies one part of the code - the place where you define the class to handle the file format. Without reflection, you'll have to remember to modify the other class, the ImageLoader, as well
Isn't this pretty much what the Dependency Injection pattern is all about?
If you can isolate the dependencies then the mechanics will almost certainly be reflection based, but it will be configuration file driven so the messiness of the reflection can be pretty well encapsulated and isolated.
I believe with DI you simply say I need an object of type <interface> with some other parameters, and the DI system returns an object to you that satisfies your conditions.
This goes together with IoC (Inversion of Control) where the object being supplied may need something else, so that other thing is automatically created and installed into your object (being created by DI) before it's returned to the user.
I know this borders on the "no comment about loading images other ways", but why not just flip your dependencies -- rather than have ImageLoader depend on ImageFileFormats, have each IImageFileFormat depend on an ImageLoader? You'll gain a few things out of this:
Each time you add a new IImageFileFormat, you won't need to make any changes anywhere else (and you won't have to use reflection, either)
If you take it one step further and abstract ImageLoader, you can mock it in Unit Tests, making testing the concrete implementations of each IImageFileFormat that much easier
In vb.net, if all the image loaders will be in the same assembly, one could use partial classes and events to achieve the desired effect (have a class whose purpose is to fire an event when the image loaders should register themselves; each file containing image loaders can have use a "partial class" to add another event handler to that class); C# doesn't have a direct equivalent to vb.net's WithEvents syntax, but I suspect partial classes are a limited mechanism for achieving the same thing.