mardi 31 janvier 2023

Programmatically check in runtime whether variable is const in JavaScript?

Is it possible to know programmatically in runtime whether variable is const in JS?

For example:

const a = {};
const b = 5;

var c = {};
var d = 6;

var e = a;
var f = b;
var g = c;
var h = d;

isConst(a); // true
isConst(b); // true
isConst(c); // false
isConst(d); // false
isConst(e); // false
isConst(f); // false
isConst(g); // false
isConst(h); // false

I don't even know how to approach this issue, assuming I don't want to use external tools (from outside the JS runtime environment), or something like eval().

Maybe it's possible somehow with JavaScript's Proxy() or Reflect()?

If there's no solution that determine if const or not without making changes in the checked code/module/function/block itself, I can maybe accept solutions that require some decorative/wrapping modifications to the code/function.

Maybe something that parse the Function() prototype field that contains the stringified text of the function body?

Maybe we can leverage exceptions here? For example, to catch the exception that raised when you try to manipulate a constant variable, and use it to understand the situation?





Loading System.IO.Ports.dll from dynamically loaded class library

Using .net6 or .net7, I can't make a dynamically loaded class library (read plugin) load the System.IO.Ports.dll. I'm using VS2022, but had the same problem on .net5 and VS2019. I'm only using Windows.

I have dropped some demonstration code here: https://github.com/JanJorgensen/Net5AddonLoadProblemDemo

The application loads the plugin like this:

        public static void LoadAndActivateTheAddon()
        {
            var assembly = Assembly.LoadFrom("TheAddon.dll");
            var type = assembly.GetExportedTypes().Where(t => t.Name == "AddonMain").FirstOrDefault();
            object obj = Activator.CreateInstance(type);
            var addon = obj as IAddon;

            addon.Action();     // Call a method in the loaded plugin object.
        }

Exception thrown when trying to create instance of SerialPort class is: System.PlatformNotSupportedException, "System.IO.Ports is currently only supported on Windows."

In .Net Framework (2 through 4.5), it worked perfectly. Maybe because that was only for Windows.

If I create a .net application (console, WinForms or WPF) and use System.IO.Ports directly from that, it works perfectly.

But while I'm unfortunately not a .net pro, I think there's something I don't know about building and distributing .net5-7 applications for Windows.

In the output folder, a 'runtimes' folder is created when building, with the Ports assembly in a version for different target systems.

So why can't the dynamically loaded class library load the System.IO.Ports.dll? In a deployed installation it doesn't work either. It seems the plugin assembly should be configured to use the .net7 version of the assembly when on Windows.

I have a dirty solution at the moment, where I add the library as a dependency in my top level application, just to make sure it is loaded, making the plugin work. But that's so ugly and should not be necessary.

I posted the question before, but back then I didn't have the example code.

I'm sure the solution is simple, but ...

I rely on all you good people to help me with this. Thanks in advance.





lundi 30 janvier 2023

Java Records Reflection and Synthetic Methods

Based on the older Java (7) Language Specifications (13.1.7):

Any constructs introduced by a Java compiler that do not have a corresponding construct in the source code must be marked as synthetic, except for default constructors, the class initialization method, and the values and valueOf methods of the Enum class.

On newer ones (Java (17) Language Specifications (13.1.7): ) that wording changes to:

A construct emitted by a Java compiler must be marked as synthetic if it does not correspond to a construct declared explicitly or implicitly in source code, unless the emitted construct is a class initialization method (JVMS §2.9).

I wonder how would this apply to the accesor methods created for the components of java Records (JEP 395)

For example

record ARecord(int a){}

would have a method int a() yet there is no code representing such method, according to the wording of the older JLS such method is added by the compiler so I would expect it to be synthetic but its not, as it can be corroborated by running the following 2 lines on JShell

jshell
|  Welcome to JShell -- Version 17.0.1
|  For an introduction type: /help intro

jshell> record ARecord(int a){}
|  created record ARecord

jshell> ARecord.class.getDeclaredMethod("a").isSynthetic();
$2 ==> false

jshell>

The reason I ask is because I would like to use reflection (or any other programmatic mean at runtime) to determine which elements on the class have a matching code structure, basically those have code representing them, meaning:

For the following code

record ARecord(int a){

  pubic void someMethod() {}

}

that entity would have 2 methods (a and someMethod), a has no code representing it and someMethod does, I need a way to differentiate those based on that criteria





How to set new tag value of nested struct using reflection

I have this structures:

type Library struct {
    Book            Book           
    Owner           Owner           
    Editorial.       Editorial
}

type Book struct {
    ID             string           `json:"id"`
    Title          string           `json:"title"`
    Description    string           `json:"description"`
    Category       string           `json:"category"`
} 

My code changes the json tag of the Book structure (autogenerated). How can I assign the new tag value ("categoryID") to the final structure, as in order to set new value I had to create a new variable "sub". How can I assign "sub" to f ?

func renameTags(p interface{}) any {
    rv := reflect.ValueOf(p)
    rt := rv.Elem().Type()
    fields := make([]reflect.StructField, rt.NumField())
    for i := range fields {
        f := rt.Field(i)
        if f.Type.Kind() == reflect.Struct && f.Type.Name() == "Book" {
            sub := f.Type.Field(13)
            sub.Tag = reflect.StructTag(`json:"` + "categoryID" + `"`)
            
        }

        fields[i] = f
    }

    st := reflect.ValueOf(fields)
    x := st.Interface()
    return x 
}

Thanks in advance!





dotnet, use dynamic object to initiate generic type

I need to create an Instance of a generic class using dynamic object

Using the following code sample

using System;
using System.Dynamic;

public class Program
{
    public static void Main()
    {
        dynamic obj = new ExpandoObject();
        obj.num = 1;
        obj.str = "a";

        Type t = obj.GetType();
        Type myType = typeof(RulesService<>).MakeGenericType(t);
        object instance = Activator.CreateInstance(myType, 999);

        myType.GetMethod("GetMatchingRules")
            .Invoke(instance, obj);
    }
}

public class RulesService<T>
{
    private readonly int _retNum = 0;

    public RulesService(int retNum)
    {
        _retNum = retNum;
    }

    public int GetMatchingRules(T objectToMatch)
    {
        Console.WriteLine("GetMatchingRules");
        return _retNum;
    }
}

and getting the next exception

Unhandled exception. Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: The best overloaded method match for 'System.Reflection.MethodBase.Invoke(object, object[])' has some invalid arguments at CallSite.Target(Closure , CallSite , MethodInfo , Object , Object ) at System.Dynamic.UpdateDelegates.UpdateAndExecuteVoid3[T0,T1,T2](CallSite site, T0 arg0, T1 arg1, T2 arg2) at Program.Main()





c# Get all properties of an inherited class in a function using generic type

I have a function that converts a DataTable to a List of an object. I use reflection to get the properties of the type T given.

public static List<T> ConvertToList<T> (DataTable dt)
{
    List<string> columnNames = dt.Columns.Cast<DataColumn>().Select(c => c.ColumnName.ToLower()).ToList();
    System.Reflection.PropertyInfo[] properties = typeof(T).GetProperties();
    ... (code to create the List from the DataTable)
}

I use it this way :

DataTable FooTable = BD_SolEx.GetFoo();

It gets a DataTable. Column names should match the property names of the object I want. For this example, let's consider that the column names are ID, Name.

ListFoo = new ObservableCollection<Foo>(CommonMethods.ConvertToList<Foo>(FooTable));

with the Foo class written like

public class Foo
{
    public int ID { get; set; }
    public string Name { get; set; }
}

So with ConvertToList, I get the DataTable column names with the first instruction. I get the type T property names with the second instruction. Then I do my other operations to get the List from the DataTable, but I don't have any problem with this part.

And I get my List of Foo items with their ID and Name.

It works well until I try to pass an inherited class. In this case, I only get the parent class property and none of the child's one.

For example, if I create :

public class FooChild : Foo
{
    public bool IsFoo;
}

and use it with

DataTable FooTable = BD_SolEx.GetFooChild();
ListPN = new ObservableCollection<FooChild>(CommonMethods.ConvertToList<FooChild>(FooTable));

I don't get IsFoo field in the list of my fields. I checked my generic type is ConvertToList function and T is type of FooChild.

I tried different Flags (System.Reflection.BindingFlags.Public, System.Reflection.BindingFlags.Instance, System.Reflection.BindingFlags.DeclaredOnly...) but none of them gave me the result I wanted. Am I missing something, or is it the intended way of reflection to work ?





vendredi 27 janvier 2023

How to convert interface to another interface which it implements?

In short - I would like to be able to cast an interface type whose underlying type implements a specific interface to that specific interface.

I am using the plugin package to lookup a New function which looks like so (I have many others the same):

func NewDomainPrimaryKey() any { return DomainPrimaryKey{} }

(This is generated at run-time so I can't just reference it as DomainPrimaryKey)

My lookup and call is like so:

                plugin, err := plugin.Open("my-plugin")
                if err != nil {
                    return err
                }

                symGet, err := plugin.Lookup("New" + pluginName)
                if err != nil {
                    return err
                }

                newGenModel, ok := symGet.(func() any)
                if !ok {
                    return errors.New("unexpected type from module symbol")
                }

                anyGenModel := newGenModel()
                genModel, ok := anyGenModel.(GenModel) // **this is where the problem is
                if !ok {
                    return errors.New("unexpected type from module symbol")
                }

                genModelInstance := genModel.Get()

In the above I am trying to cast 'anyGenModel' (an interface) to the 'GenModel' interface which it implements, however, this doesn't work.

I am certain it implements this interface because when I do the following, I get no errors.

type GenModel interface {
    Get() any
    TableName() string
}

var _ GenModel = (*DomainPrimaryKey)(nil) // this doesn't complain

How can I do this? I found this article which I don't think is what I am looking for but seems similar.

Thanks in advance for any help on this - this has become a real blocker for me.





can I have global --add-opens instead of package specific?

instead of specifying --add-opens java.base/java.util=ALL-UNNAMED to allow reflection to java.util package at jvm startup, is there an option to allow it for all packages i.e. --add-opens all/all=ALL-UNNAMED ?





jeudi 26 janvier 2023

How to find property and their values if they are property of another class using reflection in C#?

How To Get Properties and Their values ? //Employee Class

public class Employee
    {
        public string Name { get; set; }
        public Address HomeAddress { get; set; }
        public DateTime Joiningdate_With_Time{ get; set; }
        public List<Phone> PhoneNumbers { get; set; }
    }

//Address Class

public class Address
    {
        public string Road{ get; set; }
        public string PostOffice{ get; set; }
    }

//Phone Class

    public class Phone
    {
        public string Number { get; set; }
        public string Extension { get; set; }
    }
public static string GetNestedPropertiesValues(object obj){
//This should return a string which can contains property Name & Their values of Instructor Class 
// Here reflection should be used 
}
Employee e1 = new Employee{
Name = "Asish",
HomeAddress = new Address{Road = "8",PostOffice="Mumbai"},
Joiningdate_With_Time = new DateTime(2022,5,28,12,5,55),
PhoneNumbers = new List<Phone>{
new Phone {Number = "123456",Extension="+330"},
new Phone {Number = "22586",Extension="+980"},
 }
};

Console.WriteLine(GetNestedPropertiesValues(e1));//This will print the values with property Name

GetNestedPropertiesValues method should return all the values with property names. Here Only Use Reflection and Recursion can be used.





lundi 23 janvier 2023

get pointer to variable stored in reflect.Value in Golang [closed]

Probably this is question is very simple, but i've spent some time and was not able to find any good solution( For example we have the following code:

var someValue int = 10
v := reflect.ValueOf(someValue)
var v1 reflect.Value // should refer to &someValue, but with using of the "v" variable only

I know that the easiest solution will be v1 := reflect.ValueOf(&someValue) or using of reflect.New() function, but unfortunately this will not work in my case.

The "v1" variable should be initialized only with using of the "v" variable.





vendredi 20 janvier 2023

How to mock one private method while testing another private method? PowerMock and reflection in the same test class and in the same test

I have a chain of methods in my class. Here is the simplified version:

public class SomeClass {
    public String run (String someString1, String someString2, String someString3) {
        return firstAction(someString1, someString2, someString3);
    }

    private String firstAction(String someString1, String someString2, String someString3) {
        return someString1 + secondAction(someString2, someString3);
    }

    private String secondAction(String someString2, String someString3) {
        return someString2 + someString3;
    }
}

I can test "secondAction" using the reflection. Or I can test "run" using PowerMock to mock "firstAction". Individual tests work fine. But when I try to test both methods at the same time it ends with error. The same problem in case of testing "firstAction" (using reflection) and mocking "secondAction" (using PowerMock).

@RunWith(PowerMockRunner.class)
@PrepareForTest(SomeClass.class)
public class SomeClassTest {
    private Method getSecondActionMethod() throws NoSuchMethodException {
        Method method = SomeClass.class.getDeclaredMethod("secondAction", String.class, String.class);
        method.setAccessible(true);
        return method;
    }

    @Test
    public void runTest() throws Exception {
        SomeClass someClassSpy = PowerMock.createPartialMock(SomeClass.class, "firstAction");
        PowerMock.expectPrivate(someClassSpy, "firstAction", "Hello", ", ", "World!").andReturn("Hello, World!");
        PowerMock.replay(someClassSpy);
        assertEquals("Hello, World!", someClassSpy.run("Hello", ", ", "World!"));
        PowerMock.verify(someClassSpy);
    }

    @Test
    public void secondActionTest () throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        SomeClass someClass = new SomeClass();
        assertEquals("Hello, World!", getSecondActionMethod().invoke(someClass, "Hello, ", "World!"));
    }
}
    at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354)
    at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297)
    at java.base/java.lang.reflect.Method.checkCanSetAccessible(Method.java:200)
    at java.base/java.lang.reflect.Method.setAccessible(Method.java:194)
    at org.powermock.reflect.internal.WhiteboxImpl.doGetAllMethods(WhiteboxImpl.java:1508)
    at org.powermock.reflect.internal.WhiteboxImpl.getAllMethods(WhiteboxImpl.java:1482)
    at org.powermock.reflect.internal.WhiteboxImpl.getMethods(WhiteboxImpl.java:1750)
    at org.powermock.reflect.internal.WhiteboxImpl.getMethods(WhiteboxImpl.java:1789)
    at org.powermock.reflect.internal.WhiteboxImpl.getBestMethodCandidate(WhiteboxImpl.java:1008)
    at org.powermock.core.MockInvocation.findMethodToInvoke(MockInvocation.java:58)
    at org.powermock.core.MockInvocation.init(MockInvocation.java:35)
    at org.powermock.core.MockInvocation.<init>(MockInvocation.java:22)
    at org.powermock.core.MockGateway.doMethodCall(MockGateway.java:155)
    at org.powermock.core.MockGateway.methodCall(MockGateway.java:138)
    at somePackage.SomeClassTest.getSecondActionMethod(SomeClassTest.java:26)
    at somePackage.SomeClassTest.secondActionTest(SomeClassTest.java:54)
    at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
    at java.base/java.lang.reflect.Method.invoke(Method.java:577)
    at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:59)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:326)
    at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:79)
    at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:87)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:310)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:298)
    at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:77)
    at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:42)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:218)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:160)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$1.run(PowerMockJUnit44RunnerDelegateImpl.java:134)
    at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27)
    at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:136)
    at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:117)
    at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:57)
    at org.powermock.modules.junit4.PowerMockRunner.run(PowerMockRunner.java:59)

Please help me to understand this error. Is there another way to test and mock private methods at the same time? Especially when you need to mock a private method called inside another private method. Please do not suggest something like:

  1. Changing private to public/protected.
  2. Combining all private methods into one.
  3. Not to test private methods.




Go (Golang) reflect Kind is never interface? [duplicate]

Assume we have a struct implementing an interface:

type SomeStruct struct {}
type SomeInterface interface { SomeMethod() }

func (s *SomeStruct) SomeMethod() {}

and some instantiations:

var (
  asValue := SomeStruct{}
  asPointer := &asValue
  asInterface SomeInterface = asPointer
)

Now, using the reflect package, we can see that

reflect.TypeOf(asValue).Kind() == reflect.Struct
reflect.TypeOf(asPointer).Kind() == reflect.Pointer
reflect.TypeOf(asInterface).Kind() == reflect.Pointer // This!
                                                      // Why not reflect.Interface?

So, my question is: what should x be so that we get reflect.TypeOf(x) == reflect.Interface?





jeudi 19 janvier 2023

How to access the methods of a generic ObservableCollection?

public class Car
{
    public ObservableCollection<int> ints = new ObservableCollection<int> { 12, 3, 4, 1, 2 };
    public ObservableCollection<double> doubles = new ObservableCollection<double> {  };
    public ObservableCollection<string> strings = new ObservableCollection<string> { 12, 3, 4, 1, 2 };
    public ObservableCollection<Color> colors = new ObservableCollection<Color> { ColorA, ColorB, ColorC };

}

Let's say I have a class call Car, inside the class, I have 4 lists.

In another class, I would like use Reflection to call a Linq method to find if these four lists contain anything.

    public void FindProperties()
    {
        foreach (var prop in typeof(Car).GetProperties())
        {
            if (prop.PropertyType == typeof(ObservableCollection<T>))
            {
                var list = (ObservableCollection<T>)prop.GetValue(Car);
                if (list.Any()) 
                  {//Do something}
            }
        }
     }

Since ObservableCollection< T > isn't a thing, the code is not working, but hopefully it explains what I attempt to do. Inside the Car class I actually have 40+ of these lists and I really don't want to do a switch and case cast to do that. It doesn't seem very clean and smart to do that either.

I don't need to know what is T, I just need to know if the list contains anything and maybe use the CollectionChanged event as well. What is the best way to do it apart from casting each field?





How to get types which implements specific interface from referenced nuget packages?

i try to find a way to get all classes which implements some interface and the location of these classes are referenced nuget packages. I know how to do it with referenced dll files by using Assembly.GetReferencedAssemblies. But how i can explore nuget packages? Is there some nuget which can help with this task?

Thank you!

I tried to look on PackageManager class but i didn't find what i want.





mercredi 18 janvier 2023

Using reflection, how do I find the method an interface is implementing when it's implementing another interface

Let's say I have two interfaces:

public interface IDeclaring
{
    String GetValue();
}

public interface IImplementing : IBase
{
    String IDeclaring.GetValue() => "IDerived";
}

I'm writing a library that implements interfaces at runtime and therefore needs to understand which interface methods need implementing, and which are already implemented.

Using reflection, I now have one MethodInfo per interface, say delcaringMethodInfo and implementingMethodInfo but I can't figure out how to get the information that the latter implements the former.

There's MethodInfo.GetBaseDefinition but that doesn't work on interfaces.

That information must somewhere be present and accessible though.

It would probably be enough to be able to check if the two MethodInfos have the same signature, but I don't know how to do that either easily as that's not trivial. I suspect I need to check whether they have the same parameters and parameter modifiers.





Problems in changing value of a runtime annotation with reflection (Java 17)

I'm stuck into trying to change the value of a @Retention(RetentionPolicy.RUNTIME) annotation with Java 17. I think my code has some problems also related to the Java 9 illegal reflective access.

That's what I've tried, but it doesn't work:

public static void changeAnnotationValue(String value) {
        Greeter oldAnnotation = Greetings.class.getAnnotation(Greeter.class);
        Greeter newAnnotation = new Greeter() {

            @Override
            public Class<? extends Annotation> annotationType() {
                return oldAnnotation.annotationType();
            }

            @Override
            public String value() {
                return value;
            }
        };
        try {
            Method method = Greetings.class.getDeclaredMethod("annotationData", null);
            method.setAccessible(true);

            Field annotations = method.getClass().getDeclaredField("annotations");
            annotations.setAccessible(true);

            Map<Class<? extends Annotation>, Annotation> map = (Map<Class<? extends Annotation>, Annotation>) annotations.get(method);
            map.put(Greeter.class, newAnnotation);
        } catch (NoSuchMethodException | IllegalAccessException | NoSuchFieldException e) {
            //Handle exceptions
            e.printStackTrace();
        }
    }




mardi 17 janvier 2023

How to change an annotation at runtime with Reflection (JDK 17)

I'm trying to change the value of an annotation at runtime with Reflection, but I can't find out how to do that with JDK 17, I've done it in JDK 8, but it doesn't work in 17.

I've tried to do something, but nothing works...That's the code where I'm stuck into:

public void changeAnnotation(Class<?> clazz, Class<? extends Annotation> annotation) {
        Annotation oldAnnotation = clazz.getAnnotation(annotation);
    }




dimanche 15 janvier 2023

Why is DirectMethodHandle$Holder not a member class of DirectMethodHandle, according to reflection?

Consider the DirectMethodHandle$Holder class. (It is one of the classes returned by Class.forName("java.lang.invoke.DirectMethodHandle").getDeclaredClasses(), which is documented to return member classes.)

The following assertion fails under JDK 19:

assert Class.forName("java.lang.invoke.DirectMethodHandle$Holder").isMemberClass();

Why? Which rule of section 8.5 does it violate?

Like some of the commenters, I am coming to the conclusion that this is a very weird bug. For example, using some javax.annotation.processing and some javax.lang.model.* classes, the following assertion does not fail:

assert NestingKind.MEMBER == ((TypeElement)processingEnvironment.getElementUtils().getTypeElement("java.lang.invoke.DirectMethodHandle.Holder")).getNestingKind();

So the outputs of the mechanisms underpinning the compiler do not agree with the outputs of the reflection machinery. I've filed a bug against the JDK.





Cannot inject already loaded type

I want to add some variables to the Author class, using the bytebuddy library. The problem that is displayed to me after the second call to the apply method is

Exception in thread "main" java.lang.IllegalStateException: Cannot inject already loaded type: class pl.edu.testowy.entity.Author

I have no idea how to fix this, I know it's probably about classLoader

package pl.edu.wat.testowy.reflection;

package pl.edu.wat.testowy.reflection;

import net.bytebuddy.ByteBuddy;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.dynamic.ClassFileLocator;
import net.bytebuddy.dynamic.DynamicType;
import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
import net.bytebuddy.implementation.MethodCall;
import net.bytebuddy.matcher.ElementMatchers;
import net.bytebuddy.pool.TypePool;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import static net.bytebuddy.matcher.ElementMatchers.named;

public class Reflection {
    private TypeDescription entityDefinition;
    private TypeDescription requestDefinition;
    private TypeDescription responseDefinition;

    private TypeDescription mapperDefinition;
    private TypePool typePool;
    private ByteBuddy byteBuddy;

    public Reflection() {
        this.typePool = TypePool.Default.ofSystemLoader();
        this.byteBuddy = new ByteBuddy();
        this.entityDefinition = typePool.describe("pl.edu.wat.testowy.entity.Author").resolve();
        this.requestDefinition = typePool.describe("pl.edu.wat.testowy.dto.AuthorRequest").resolve();
        this.responseDefinition = typePool.describe("pl.edu.wat.testowy.dto.AuthorResponse").resolve();
        this.mapperDefinition = typePool.describe("pl.edu.wat.testowy.mapper.AuthorMapper").resolve();

    }


    FieldInformation fieldInformation = new FieldInformation();
    FieldInformation2 fieldInformation2 = new FieldInformation2();


    //nie beda to pola final bo one beda sie zmienialy
    public static void apply(String test){

        var ref = new Reflection();
        ref.applyEntity(test);
        ref.applyRequest(test);
        ref.applyResponse(test);
        ref.applyAuthorMapper(test);

    }

    public List<String> getFieldNames() {
        FieldInformation2.readJson("fields2.json");
        List<FieldInformation2> fields = FieldInformation2.getFields();
        List<String> fieldNames = new ArrayList<>();
        fields.forEach(f -> fieldNames.add(f.getFieldName()));
        return fieldNames;
    }

    private void applyAuthorMapper(String test) {//musimy wyciagnac mappera

        DynamicType.Builder <Object> builder = byteBuddy
                .redefine(mapperDefinition,
                        ClassFileLocator.ForClassLoader.ofSystemLoader())
                .method(named("fillAuthorRequest"))
                .intercept(MethodCall.invoke(setterAuthorEntity(test))
                        .onArgument(0)
                        .withMethodCall(MethodCall
                                .invoke(getterRequest(test))
                                .onArgument(1)))
                .method(named("fillAuthor"))
                .intercept(MethodCall.invoke(setterAuthorResponse(test))
                        .onArgument(0)
                        .withMethodCall(MethodCall
                                .invoke(getterEntity(test))
                                .onArgument(1)));

        try(var unloadedAuthor = builder.make()){
            mapperDefinition = unloadedAuthor.load(ClassLoader.getSystemClassLoader(), ClassLoadingStrategy.Default.INJECTION)
                    .getTypeDescription();

        } catch(IOException e){
            throw new RuntimeException();
        }

    }

    private MethodDescription getterEntity(String test){
        return  entityDefinition
                .getDeclaredMethods()
                .filter(ElementMatchers.isGetter(test))
                .stream()
                .findFirst()
                .orElseThrow();
    }
    private MethodDescription setterAuthorResponse(String test) {
        return  responseDefinition
                .getDeclaredMethods()
                .filter(ElementMatchers.isSetter(test))
                .stream()
                .findFirst()
                .orElseThrow();
    }

    private MethodDescription getterRequest(String test) {
        return  requestDefinition
                .getDeclaredMethods()
                .filter(ElementMatchers.isGetter(test))
                .stream()
                .findFirst()
                .orElseThrow();
    }

    private MethodDescription setterAuthorEntity(String test) {
        return  entityDefinition
                .getDeclaredMethods()
                .filter(ElementMatchers.isSetter(test))
                .stream()
                .findFirst()
                .orElseThrow();
    }

    private void applyResponse(String test) {

        DynamicType.Builder <Object> builder = byteBuddy
                .redefine(responseDefinition,
                        ClassFileLocator.ForClassLoader.ofSystemLoader())
                .defineProperty(test,typePool.describe("java.lang.String").resolve());

        try(var unloadedAuthor = builder.make()){
            responseDefinition = unloadedAuthor.load(ClassLoader.getSystemClassLoader(), ClassLoadingStrategy.Default.INJECTION)
                    .getTypeDescription();


        } catch(IOException e){
            throw new RuntimeException();
        }

    }

    private void applyRequest(String test) {
        DynamicType.Builder <Object> builder = byteBuddy
                .redefine(requestDefinition,
                        ClassFileLocator.ForClassLoader.ofSystemLoader())
                .defineProperty(test,typePool.describe("java.lang.String").resolve());

        try(var unloadedAuthor = builder.make()){
            requestDefinition = unloadedAuthor.load(ClassLoader.getSystemClassLoader(), ClassLoadingStrategy.Default.INJECTION)
                    .getTypeDescription();


        } catch(IOException e){
            throw new RuntimeException();
        }

    }

    public void applyEntity(String test) {
        DynamicType.Builder <Object> builder = byteBuddy
                .redefine(entityDefinition,
                        ClassFileLocator.ForClassLoader.ofSystemLoader())
                .defineProperty(test,typePool.describe("java.lang.String").resolve());

        try(var unloadedAuthor = builder.make()){
            entityDefinition = unloadedAuthor.load(ClassLoader.getSystemClassLoader(), ClassLoadingStrategy.Default.INJECTION)
                    .getTypeDescription();

        } catch(IOException e){
            throw new RuntimeException();
        }

    }



}


package pl.edu.wat.testowy;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import pl.edu.wat.testowy.reflection.Reflection;


@SpringBootApplication
public class TestowyApplication {

    public static void main(String[] args) {
        //tak jak tu korzystam z mechanizmu refleksji tak wystarczy utworzyc zalozmy 10 obiektow, gdzie podajemy nazwe i typ zmiennej
        Reflection.apply("test");
        Reflection.apply("test2");
        SpringApplication.run(TestowyApplication.class, args);
    }

}

I have tried modifying the classLoader but to no avail, not too sure how.





I can't get access to static properties or fields of my generic base class in C#

This is the code of my base class:

namespace Business;

public abstract class Business<ReadModel, WriteModel> : ReadBusiness<ReadModel>
    where ReadModel : class, IEntity, new()
    where WriteModel : class, IEntity, new()
{
    protected abstract Write<WriteModel> Write { get; }

    public static List<Action<WriteModel>> PreCreationAugmenters = new List<Action<WriteModel>>();

    public static List<Action<WriteModel>> PostCreationAugmenters = new List<Action<WriteModel>>();

    public static List<Action<WriteModel>> PreUpdateAugmenters = new List<Action<WriteModel>>();

And this is my derived class:

namespace Taxonomy;

public class TagBusiness : Business<TagView, Tag>
{

And now I want to access the PostCreationAugmenters of the base class from typeof(TagBusiness).

I tried:

typeof(TagBusiness).GetProperty("PostCreationAugmenters", BindingFlags.Static); // null
typeof(TagBusiness).GetField("PostCreationAugmenters", BindingFlags.Static); //null
typeof(TagBusiness).BaseType.GetProperty("PostCreationAugmenters"); // null

I want to get access to that list, and add an augmenter to it.

What do I do wrong here?





samedi 14 janvier 2023

Method overload emitted via dynamic IL is not being called

So I am attempting to create a class that will wrap up all the bits necessary to implement a single-instance application (SIA). It should be a drop-in replacement for Application.Run<T>().

Since the SIA needs to override the WndProc method so that the running instance can bring itsself to the foreground, and that override needs to call the base class method, I landed on creating a wrapper class at runtime that inherits from whatever the Form class is which implements an override for WndProc.

The SIA portion is working, as is the wrapper class. But the WndProc override does not appear to be getting called.

Any direction regarding getting the dynamic WndProc override to be called would be appreciated.

Code so far:

using System.Diagnostics;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.InteropServices;

namespace ScreenSaverControl {
    public static class SingleInstanceApplication<T> where T : Form {
        private const string APP_NAME = "SCREENSAVER_CONTROL";
        private const string COMPANY_NAME = "DWAK";

        private const int HWND_BROADCAST = 0xffff;
        public static readonly int WM_SHOW_RUNNING_INSTANCE = Win32Helper.RegisterWindowMessage($"WM_SHOW_RUNNING_INSTANCE_{APP_NAME}");

        private static Mutex _singleInstanceMutex = new Mutex(true, $"{APP_NAME}::{COMPANY_NAME}");

        private static Form? _instanceForm = null;
        private static Action _showRunningInstanceAction = ActivateRunningInstance;



        public static void Run() {
            MessageBox.Show(WM_SHOW_RUNNING_INSTANCE.ToString());
            if (_singleInstanceMutex.WaitOne(TimeSpan.Zero, true)) {
                CreateSingleInstanceFormRunner();
                Application.Run(_instanceForm);
                _singleInstanceMutex.ReleaseMutex();
            } else {
                ActivateRunningInstance();
            }
        }


        private static void ActivateRunningInstance() {
            Win32Helper.PostMessage(
                (IntPtr)HWND_BROADCAST,
                WM_SHOW_RUNNING_INSTANCE,
                IntPtr.Zero,
                IntPtr.Zero);
        }


        private static void MessageHandler(ref Message m) {
            Debug.WriteLine($"*SIA: {m.Msg}");    // This never fires.
            if (null == _instanceForm) { return; }
            if (SingleInstanceApplication<T>.WM_SHOW_RUNNING_INSTANCE == m.Msg) {
                if (_instanceForm.WindowState == FormWindowState.Minimized) {
                    _instanceForm.WindowState = FormWindowState.Normal;
                }
                if (!_instanceForm.Visible) { _instanceForm.Show(); }

                bool topMost = _instanceForm.TopMost;
                _instanceForm.TopMost = true;
                _instanceForm.TopMost = topMost;
            }

            //base.WndProc(ref m);
        }



        delegate void RefAction(ref Message message);

        private static void CreateSingleInstanceFormRunner() {
            //if (null == _instanceForm) { return; }
            string methodName = "WndProc";
            Type type = typeof(T);
            MethodInfo? methodInfo = type.GetMethod(methodName, BindingFlags.Instance | BindingFlags.NonPublic);
            if (null == methodInfo) {
                methodInfo = typeof(Form).GetMethod(methodName, BindingFlags.Instance | BindingFlags.NonPublic);
            }
            Type[] methodParams = methodInfo!.GetParameters().Select(p => p.ParameterType).ToArray();

            AssemblyName assemblyName = new AssemblyName("SingleInstanceAssembly");
            AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
            ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("SingleInstanceModule");
            TypeBuilder typeBuilder = moduleBuilder.DefineType("SingleInstanceFormRunner", TypeAttributes.Public, type);

            // Define the new method with ref parameter
            MethodBuilder methodBuilder = typeBuilder.DefineMethod(methodName, MethodAttributes.Private, methodInfo.ReturnType, new Type[] { typeof(Message).MakeByRefType() });
            RefAction newWndProc = MessageHandler;
            ILGenerator il = methodBuilder.GetILGenerator();
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldarg_1);
            il.Emit(OpCodes.Ldarg_2);
            il.Emit(OpCodes.Call, newWndProc.Method);

            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldarg_1);
            il.Emit(OpCodes.Call, methodInfo);
            il.Emit(OpCodes.Ret);

            Type dynamicType = typeBuilder.CreateType();
            _instanceForm = (T)Activator.CreateInstance(dynamicType);
        }
    }




    internal static class Win32Helper {
        [DllImport("user32")]
        public static extern bool PostMessage(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam);
        [DllImport("user32")]
        public static extern int RegisterWindowMessage(string message);
    }
}

Program.cs:

namespace ScreenSaverControl {
    internal static class Program {
        [STAThread]
        static void Main() {
            ApplicationConfiguration.Initialize();
            SingleInstanceApplication<MainDialog>.Run();
        }
    }
}

Test procedure + results:

  1. Run the first instance via VS debug run.
  2. Minimize the running instance.
  3. Run the second instance via the .exe in the output folder.
  • Observe the output window and notice that no "*SIA" messages are present.
  • Observe that the MessageHandler breakpoint never fires.
  • Observe that the debug (first) instance does not bring itself to the foreground.

For debugging purposes I implemented a WndProc override on MainDialog which outputs the m.Msg value to the output window. I DO see those messages.

protected override void WndProc(ref Message m) {
    Debug.WriteLine(m.Msg);
    base.WndProc(ref m);
}

I have confirmed that the running form is an instance of SingleInstanceFormRunner.

This code is WinForms on .NET 7.0.

Let me know if there's additional information that's needed to assist. Thank you.





jeudi 12 janvier 2023

How to get the method's parameter expression stack or string representation?

I am writing a method for debugging and metrics capturing, such that:

void capture(Object value, String debugName) {
  System.out.println("captured " + debugName + " with value " + value);
}

and calling it with:

capture(foo.bar(), "foo.bar");

Is there any way to get the value expression string directly, so I don't need to pass the debugName? Something like:

void capture(Object value) {
  System.out.println("captured " + getStack(value) + " with value " + value);
}




mercredi 11 janvier 2023

"Object of type 'System.EventHandler' cannot be converted to type 'System.Action'" when trying to add event handler for dll action using reflection

I have the following two programs

WindowsFormsApplication

ClassLibrary1 dll

The ClassLibrary1 dll is loaded to the Windowsform via appdomain loading. I have subscibed to the dll events through reflection across the appdomain. I am trying to subscribe to the dll action(TestAction) and also handle the action in windows forms. But I get this error 'Object of type 'System.EventHandler' cannot be converted to type 'System.Action'

This is the windows form code:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Reflection;
using System.Diagnostics;
using ClassLibrary1;

namespace WindowsFormsApplication2
{
    [Serializable]
    public partial class Form1 : Form
    {
        void HandleEvent(object sender, EventArgs e)
        {
            Debug.WriteLine("HandleEvent called");
        }
        void HandleAction(object sender, EventArgs e)
        {
            Debug.WriteLine("HandleAction called");
        }
        public Form1()
        {
            InitializeComponent();
            Loader.Call(  "RaiseEvent", HandleEvent, DateTime.Now.ToShortDateString());
            Loader.Call( "RaiseAct", HandleAction, DateTime.Now.ToShortDateString());
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Application.Restart();
            Application.Run(new Form1());
            this.Close();
        }
    }

    public class Loader : MarshalByRefObject
    {
        static string dll = @"..\ConsoleApplication1\ClassLibrary1\bin\Debug\ClassLibrary1.dll";
        static AppDomain ad = AppDomain.CreateDomain("Test");
        static Assembly a = Assembly.LoadFile(dll);
        static object o = a.CreateInstance("ClassLibrary1.Class1");
        static Type t = o.GetType();

        object CallInternal1( string method, EventHandler handler, object[] parameters)
        {
            // Subscribe to the event
            EventInfo eventInfo1 = t.GetEvent("TestEvent");
            eventInfo1.AddEventHandler(o, handler);

            MethodInfo m = t.GetMethod(method);
            return m.Invoke(o, parameters);
        }

        object CallInternal2( string method, EventHandler handler, object[] parameters)
        {
            // Subscribe to the event
            EventInfo eventInfo2 = t.GetEvent("TestAction");
            eventInfo2.AddEventHandler(o, handler);               // Error: Object of type 'System.EventHandler' cannot be converted to type 'System.Action

            MethodInfo m = t.GetMethod(method);
            return m.Invoke(o, parameters);
        }

        public static object Call( string method, EventHandler handler, params object[] parameters)
        {
            Loader ld = (Loader)ad.CreateInstanceAndUnwrap(Assembly.GetExecutingAssembly().FullName, typeof(Loader).FullName);
            object result = 0;
            switch (method)
            {
                case "RaiseEvent":
                    {
                        result = ld.CallInternal1( method, handler, parameters);
                        break;
                    }

                case "RaiseAct":
                    {
                        result = ld.CallInternal2( method, handler, parameters);
                        break;
                    }
            }
            return result;
        }
    }
}




mardi 10 janvier 2023

what's the most efficient way to iterate over an interface{} object in Go?

e.g. Assuming the interface{} object is a struct {"a":1, "b": "test", c: &AnotherStruct{}}, and we need to iterate the object to get value of each field "a", "b", "c".

I can think of two ways:

  1. use Go reflection directly.
  2. use json.Marshal()/json.Unmarshal() to convert the object to map[string]interface{}, and then iterate over the map to do type assertions, this also calls reflection, however there might be some json library having optimizations inside which might gain better performance, e.g. https://github.com/bytedance/sonic.

I was wondering which one is more efficient and is there any other way to do it?





Avro Schema is being generated in wrong field order (alphabetical)

I have a class the I need to converto to an avro schema:

public class MonitorStateSchema {
    private MetaResponse c;
    private Header a;
    private MonitorStateEnvelope b;

    public MonitorStateSchema(MetaResponse c, Header a, MonitorStateEnvelope b) {
        this.c = c;
        this.a = a;
        this.b = b;
    }
}

I use a generic method to get the schema from it

public static <D> void getFromAvro(Class<D> schemaType) {
    Schema schema = ReflectData.get().getSchema(schemaType);

   // other stuff
}

After doing it, I got a different order in the result than the expected:

EXPECTED:

{
  "type": "record",
  "name": "MonitorSchema",
  "namespace": "mypackage.monitor",
  "fields": [
    {
      "name": "c",
      "type": {
        "type": "record",
        "name": "MetaResponse",
        "namespace": "mypackage.monitor",
        "fields": [
          {
            "name": "uuid",
            "type": "string"
          },
          {
            "name": "code",
            "type": "int"
          },
          {
            "name": "message",
            "type": "string"
          }
        ]
      }
    },
    {
      "name": "a",
      "type": {
        "type": "record",
        "name": "Header",
        "namespace": "mypackage.monitor",
        "fields": [
          {
            "name": "apiKey",
            "type": "string"
          },
          {
            "name": "signature",
            "type": "string"
          },
          {
            "name": "nonce",
            "type": "int"
          }
        ]
      }
    },
    {
      "name": "b",
      "type": {
        "type": "record",
        "name": "MonitorEnvelope",
        "fields": [
          {
            "name": "fields",
            "type": {
              "type": "array",
              "items": {
                "type": "record",
                "name": "Field",
                "fields": [
                  {
                    "name": "name",
                    "type": "string"
                  },
                  {
                    "name": "value",
                    "type": "string"
                  }
                ]
              },
              "java-class": "[Lmypackage.monitor.Field;"
            }
          }
        ]
      }
    }
  ]
}

ACTUAL RESULT:

{
  "type": "record",
  "name": "MonitorStateSchema",
  "namespace": "mypackage.monitor",
  "fields": [
    {
      "name": "a",
      "type": {
        "type": "record",
        "name": "Header",
        "namespace": "mypackage.monitor",
        "fields": [
          {
            "name": "apiKey",
            "type": "string"
          },
          {
            "name": "nonce",
            "type": "int"
          },
          {
            "name": "signature",
            "type": "string"
          }
        ]
      }
    },
    {
      "name": "b",
      "type": {
        "type": "record",
        "name": "MonitorStateEnvelope",
        "fields": [
          {
            "name": "fields",
            "type": {
              "type": "array",
              "items": {
                "type": "record",
                "name": "Field",
                "namespace": "mypackage.monitor",
                "fields": [
                  {
                    "name": "name",
                    "type": "string"
                  },
                  {
                    "name": "value",
                    "type": "string"
                  }
                ]
              },
              "java-class": "[Lmypackage.monitor.Field;"
            }
          }
        ]
      }
    },
    {
      "name": "c",
      "type": {
        "type": "record",
        "name": "MetaResponse",
        "namespace": "mypackage.monitor",
        "fields": [
          {
            "name": "code",
            "type": "int"
          },
          {
            "name": "message",
            "type": "string"
          },
          {
            "name": "uuid",
            "type": "string"
          }
        ]
      }
    }
  ]
}

Seems that it is ordering by alphabetical order on the name of the field and it is breaking the application when deserializing the byte array. Is there any reason for this to happen?





lundi 9 janvier 2023

How to convert a struct that includes a pointer member to JSON with Boost Describe

In the documentation of Boost Describe, there is an example for automatic conversion of a struct to JSON (https://www.boost.org/doc/libs/1_78_0/libs/describe/doc/html/describe.html#example_to_json). However, when adding a pointer as a member of the struct, the code example does not work. I guess that the tag_invoke function needs to be modified in order to handle the pointer.

I tried the following, based on the example:

#include <boost/describe.hpp>
#include <boost/json.hpp>
#include <boost/mp11.hpp>
#include <fstream>
#include <iostream>
#include <map>
#include <type_traits>
#include <vector>

namespace app{

template <
    class T,
    class D1 = boost::describe::describe_members<
        T, boost::describe::mod_public | boost::describe::mod_protected>, //
    class D2 =
        boost::describe::describe_members<T, boost::describe::mod_private>, //
    class En = std::enable_if_t<boost::mp11::mp_empty<D2>::value &&
                                !std::is_union<T>::value> //
    >   
void tag_invoke(boost::json::value_from_tag const &, boost::json::value &v, 
                T const &t) {
  auto &obj = v.emplace_object();

  boost::mp11::mp_for_each<D1>(
      [&](auto D) { obj[D.name] = boost::json::value_from(t.*D.pointer); }); 
}

int b = 0;

struct A {
  int *i;
};

A a{&b};

}

int main() {
  std::cout << boost::json::value_from(app::a)
            << std::endl;

  return 0;
}





"IllegalArgumentException: Can not set java.lang.Long field to null value" when given value is a primitive

I'm trying to write a Hibernate ResultTransformer to fill a class from an Object[] using field.set(). When the field is Long but the value is long it gives me the error in the title. I've confirmed the value isn't actually null, it's just a primitive. Theoretically Java should be autoboxing that, but that doesn't seem to be the case? Is there any way to do this without manually checking the value's type and wrapping it with the appropriate wrapper when needed (i.e. a big if-else chain)?

Map<String, Object> values = ...; // key will be the column name

for(Field field : cls.getFields()) {
    Column c = field.getAnnotation(Column.class);
    if(c == null) continue; // I get past this so this definitely isn't the problem.

    field.set(objectToFill, values.get(c.name()); // If field is Long but value is long, I get error in title.
    // values.get(c.name()) is working fine and returning a non-null long value.
}




How to count at runtime a number of currently existing instances of object of type X?

So I can not change object code, I have X instances of it allocated from various assemblies. I want to count how many instances there are. How to count at runtime a number of currently existing instances of object of type X using reflection or something similar not changing the object type source code?





dimanche 8 janvier 2023

Iterate model inside model and detect changes

I'm working on an Angular (front-end) C# (back-end) application. This application uses Entity Framework code first.

So I want to evaluate two models to compare two models and look for their differences. After some investigation, I found that it can be achieved using Reflection. So I have the following code:

public static List<Variance> Compare<T>(this T val1, T val2)
            {
                var variances = new List<Variance>();
                var properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
                foreach (var property in properties)
                {
               
                var v = new Variance
                    {
                        PropertyName = property.Name,
                        valA = property.GetValue(val1),
                        valB = property.GetValue(val2)
                    };

                if (v.valA == null && v.valB == null)
                    {
                        continue;
                    }
              
                    if (
                        (v.valA == null && v.valB != null)
                        ||
                        (v.valA != null && v.valB == null)
                    )
                    {
                    if(v.valA != null)
                    {
                        if (v.valA.ToString() == "0" && v.valB == null)
                        {
                            continue;
                        }
                    }
                   

                    if(v.valA == null && v.valB != null)
                    {
                        continue;
                    }

                    variances.Add(v);
                        continue;
                    }
                

                if (!v.valA.Equals(v.valB))
                    {
                        variances.Add(v);
                    }
                }
                return variances;
            }
    }

    public class Variance
    {
        public string PropertyName { get; set; }
        public object valA { get; set; }
        public object valB { get; set; }
    }

It is working, but only for root model and not their models inside the model. I.E, I'm comparing this model:

 public partial class Profile : BaseAuditModel
    {

        public string FirstName { get; set; }
        public string MiddleName { get; set; }
        public virtual ICollection<EmploymentHistory> EmploymentHistories { get; set; }
    }

The EmploymentHistories detects it has differences, but in reality, they do not have any difference; I think it is marked as a difference because the method does not know what is inside it, so my question is. How can I detect if it is a collection? and when it is a collection iterate and detect the changes as the root one

enter image description here enter image description here





samedi 7 janvier 2023

How to call constructor default lambda using Kotlin Refelction?

Trying to call lambda provided by MyClass constructor using Kotlin Reflection.

data class MyClass(
    var magic:Int=2,
    var lambdaValue: ()->String =  { //trying to call this lambda from reflection
        "Working"
    },
)
fun main(args: Array<String>) {
    val clazz=MyClass::class
    val obj=clazz.createInstance()

    val kProperty=clazz.memberProperties

    clazz.constructors.forEach{cons-> // for each construtor
        cons.parameters.forEach{ parameter-> // looping through constructor parameters
            val property=kProperty.find { it.name==parameter.name } // finding the exact property
            print(parameter.name+" : ")

            if(parameter.type.arguments.isEmpty()) // if empty Int,Float
            {
                println(property?.get(obj))
            }else{
                println(property?.call(obj)) // unable to call lambda
            }
        }
    }
}

property.call(obj) returns Any which is not invokable. Any solution?

Expected:

magic : 2
lambdaValue : Working




Scan all fields in dtos and find missing and extra fields by their Entities

I want to create a unit test that will use reflection to find all missing fields in dto that implement BaseDto by their persistence entities. This is what I did.

@Slf4j
public class EntityAuditDtoTest {
    @Test
    public void find_MissingAndExtraFieldsThatUsedInAuditDtosByEntity_ReturnMissingAndExtraFields() throws ClassNotFoundException {
        // Arrange
        ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
        scanner.addIncludeFilter(new AnnotationTypeFilter(AuditEntityType.class));

        // Find all classes annotated with @AuditEntityType in the package com.example.dto
        Set<BeanDefinition> auditDtoBeans = scanner.findCandidateComponents("com.example.dto");

        // Act
        for (BeanDefinition auditDtoBean : auditDtoBeans) {
            Class<?> auditDtoClass = Class.forName(auditDtoBean.getBeanClassName());

            // Make sure the DTO class implements BaseAuditDto
            if (!BaseAuditDto.class.isAssignableFrom(auditDtoClass)) {
                continue;
            }

            Class<?> entityClass = getEntityClassForDto(auditDtoClass);

            Field[] dtoFields = auditDtoClass.getDeclaredFields();
            Field[] entityFields = entityClass.getDeclaredFields();

            List<String> missingFields = Arrays.stream(entityFields).map(Field::getName)
                    .filter(field -> Arrays.stream(dtoFields).noneMatch(f -> f.getName().equals(field))).toList();

            if (!missingFields.isEmpty()) {
                log.error("Missing fields in DTO class: {} \nfor entity class: {} : {}", auditDtoClass.getName(),
                        entityClass.getName(), missingFields);
            }

            List<String> extraFields = Arrays.stream(dtoFields).map(Field::getName)
                    .filter(field -> Arrays.stream(entityFields).noneMatch(f -> f.getName().equals(field))).toList();

            if (!extraFields.isEmpty()) {
                log.error("Extra fields in DTO class: {} \nfor entity class: {} : {}", auditDtoClass.getName(),
                        entityClass.getName(), extraFields);
            }
        }
    }
}

But the problem is that the dto may have a field that is in the entity class, but the test will think that this is a missing field.

For example:

Dto class: ContractAudit has customerId field (customerId). And ContractEntity has public CustomerEntity customer. This is the same fields. But of course for test they are different. I don't understand how to ignore them. I also don't want to hardcode filter that skip all endings with 'id' prefix.

@Data
@AuditEntityType("Contract")
public class ContractAudit implements BaseAuditDto {
  private Long id;
  private String ref;
  private String status;
  private Long customerId;
}


@Entity
@Table(name = "contract")
@Getter
@Setter
@ToString
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class ContractEntity {
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Column(name = "id")
  @ToString.Include
  private Long id;

  @Column(name = "ref", updatable = true)
  @ToString.Include
  private String ref;

  @Column(name = "status")
  @ToString.Include
  @Enumerated(value = EnumType.STRING)
  private ContractStatusEnum status;

  @ManyToOne
  @JoinColumn(name = "customer_id")
  public CustomerEntity customer;

  @Column(name = "deleted")
  @ToString.Include
  private boolean deleted;

  @OneToMany(fetch = FetchType.LAZY)
  @JoinColumn(name = "contract_id")
  private List<ContractDocumentEntity> documents;
}

Output: Missing fields in DTO class: ContractAudit for entity class: ContractEntity : [customer, deleted, documents]

Extra fields in DTO class: ContractAudit for entity class: ContractEntity : [customerId]

I want to have missing fields: [deleted, documents]

If you have any other ideas on how to do this, I'd love to hear it. I am not asking for implementation. Suggestions only)





Dynamically replace IL code of method body at runtime

Please note that I have no advanced knowledge of code injection nor IL code treatment. In fact I have less than basic knowledge for this and I needed to research much time to write the code at the end of this post.


I'm under .NET 4.8, I've found this answer which I think it suggests that I could modify at runtime the IL code (of the method body) of a compiled method. That is what I would like to do.

In the body of a compiled method I would like to inject a Call OpCode, in this example at the very begining (as first instruction of the method body) to call another method, but I would like to be have flexibility to choose the position where to inject these new IL instructions.

The problem is that when I try to put all this in practice, and due my lack of experience in this matter, I end up getting an AccessViolationException with this error message:

Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

I think probably I'm breaking the IL Code and that is corrupting the memory and maybe it's just a matter of fixing the order of the OpCodes, or maybe it could be a memory issue in caso of that I'm not properly writing into the unmanaged memory when patching the original IL Code.

How can I fix this problem?.

Here is the code that I'm using. In this example I'm tying to modify the method with name "TestMethod" to insert an instruction in its body to call the other method with name "LoggerMethod":

Imports System.Reflection
Imports System.Reflection.Emit

Public NotInheritable Class Form1 : Inherits Form

    Public Sub TestMethod()
        Console.WriteLine("Test Method Call.")
    End Sub

    Public Sub LoggerMethod(<CallerMemberName> Optional memberName As String = "")
        Console.WriteLine($"Logger method call by '{memberName}'.")
    End Sub

    Private Sub Form1_Shown(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Shown

        Dim testMethodInfo As MethodInfo =
            GetType(Form1).GetMethod("TestMethod", BindingFlags.Instance Or BindingFlags.Public)

        Dim loggerMethodInfo As MethodInfo =
            GetType(Form1).GetMethod("LoggerMethod", BindingFlags.Instance Or BindingFlags.Public)

        ' Using a DynamicMethod is just the way I found 
        ' for using ILGenerator to generate the wanted IL code to inject. 
        Dim dynMethod As New DynamicMethod("qwerty_dyn", Nothing, Type.EmptyTypes, restrictedSkipVisibility:=True)
        Dim ilGen As ILGenerator = dynMethod.GetILGenerator(streamSize:=16)
        ilGen.Emit(OpCodes.Call, loggerMethodInfo)
        ' ilGen.EmitCall(OpCodes.Call, loggerMethodInfo, Nothing)

        ILHelper.InjectILCode(testMethodInfo, GetIlAsByteArray2(dynMethod), position:=0)
        Me.TestMethod()

        ' testMethodInfo.Invoke(Me, BindingFlags.Default, Type.DefaultBinder, Type.EmptyTypes, Thread.CurrentThread.CurrentCulture)

    End Sub

End Class
Public NotInheritable Class ILHelper

    Private Sub New()
    End Sub

    Public Shared Sub InjectILCode(method As MethodInfo, newIlCode As Byte(), position As Integer)

        Dim body As MethodBody = method.GetMethodBody()
        Dim ilOpCodes As Byte() = body.GetILAsByteArray()

        If position < 0 Then
            Throw New ArgumentException($"Position must be equals or greater than zero.")
        End If

        If position > ilOpCodes.Length Then
            Throw New IndexOutOfRangeException($"Position {position} is greater than the IL byte array length ({ilOpCodes.Length}).")
        End If

        Dim newIlOpCodes((newIlCode.Length + ilOpCodes.Length) - 1) As Byte

        ' Add new IL instructions first.
        For i As Integer = 0 To newIlCode.Length - 1
            newIlOpCodes(i) = newIlCode(i)
        Next

        ' Continue with adding the original IL instructions.
        For i As Integer = 0 To ilOpCodes.Length - 1
            newIlOpCodes(position + newIlCode.Length + i) = ilOpCodes(i)
        Next

        ' This helps to visualize the byte array differences:
        Console.WriteLine($"Old IL Bytes: {String.Join(", ", ilOpCodes)}")
        Console.WriteLine($"NeW Il Bytes: {String.Join(", ", newIlOpCodes)}")

        Dim methodHandle As RuntimeMethodHandle = method.MethodHandle

        ' Makes sure the target method gets compiled. 
        ' https://reverseengineering.stackexchange.com/a/21014
        RuntimeHelpers.PrepareMethod(methodHandle)

        Dim hGlobal As IntPtr = Marshal.AllocHGlobal(newIlOpCodes.Length)
        Marshal.Copy(newIlOpCodes, 0, hGlobal, newIlOpCodes.Length)

        Dim methodPointer As IntPtr = methodHandle.GetFunctionPointer()
        Marshal.WriteIntPtr(methodPointer, hGlobal)

        Marshal.FreeHGlobal(hGlobal)

    End Sub

End Class
Public Module DynamicMethodExtensions

    <Extension>
    Public Function GetIlAsByteArray2(dynMethod As DynamicMethod) As Byte()

        Dim ilGen As ILGenerator = dynMethod.GetILGenerator()
        Dim fiIlStream As FieldInfo

        ' https://stackoverflow.com/a/4147132/1248295
        ' Conditional for .NET 4.x because DynamicILGenerator class derived from ILGenerator.
        If Environment.Version.Major >= 4 Then
            fiIlStream = ilGen.GetType().BaseType.GetField("m_ILStream", BindingFlags.Instance Or BindingFlags.NonPublic)
        Else ' This worked on .NET 3.5
            fiIlStream = ilGen.GetType().GetField("m_ILStream", BindingFlags.Instance Or BindingFlags.NonPublic)
        End If

        Return TryCast(fiIlStream.GetValue(ilGen), Byte())

    End Function

    ' THIS IS NOT WORKING FOR ME, ArgumentException IS THROWN.
    ' --------------------------------------------------------
    '<Extension>
    'Public Function GetIlAsByteArray(dynMethod As DynamicMethod) As Byte()
    '
    '    Dim resolver As Object = GetType(DynamicMethod).GetField("m_resolver", BindingFlags.Instance Or BindingFlags.NonPublic).GetValue(dynMethod)
    '    If resolver Is Nothing Then
    '        Throw New ArgumentException("The dynamic method's IL has not been finalized.")
    '    End If
    '    Return DirectCast(resolver.GetType().GetField("m_code", BindingFlags.Instance Or BindingFlags.NonPublic).GetValue(resolver), Byte())
    '
    'End Function

End Module




vendredi 6 janvier 2023

C#- Using reflection to populate an object of with nested objects

Say I have an C#.net DataTable Object, with all the data necessary to populate the below 3 object classes (Note that Foo contains a Bar and Cas)

I am not well versed in reflection, but I am working with a system that uses reflection to turn DataTable rows into ICollection's of Foo's, and it currently isn't sophisticated enough to populate the nested Bar and Cas objects in Foo without making additional database calls.

I trying to modify the existing function to make it recursive so it can can handle the potential future of Bar and Cas getting sub objects. Any help getting this to work would be appreciated. Moving away from refection would be a major overhaul and isn't going to be entertained by the team. Thanks in advance!

public static T Reflect<T>(DataTable dt, DataRow row, T item)
{
//all the T's on initial entry into this function will be Foo

   foreach (var prop in item.GetType().GetProperties())
   {
      //if current prop is primitive, populate with value from row

      //if current prop not primitive, 
      //recursively call this function with T of the type of Prop
      if (!prop.PropertyType.IsPrimitive)
         prop.SetValue(PropType, Reflect(dt, row, PropType));
         

   }
}
Class Foo()
{
   string Field1;
   string Field2;
   Bar Obj1;
   Cas Obj2;
}
Class Bar()
{
   string Field1;
   string Field2;
}
Class Cas()
{
   string Field1;
   string Field2;
}




mercredi 4 janvier 2023

Using runtime string input to instantiate a class

I want to create an instance of a class using the name which the user has provided in the code.

I know about the Activator.CreateInstance method which has been the answer to similar questions but without an example I'm stumped.

class Program
{
    static void Main()
    {
        Program Pet = new Program();         
        string Name = Pet.GetName();
        Pet.GetSpecies(Name);            
    }

    public void GetSpecies(string name)
    {
        Console.WriteLine($"What species is {name}? We currently see: Dog/Cat/Hamster/Gerbil");
        string answer = Console.ReadLine();
        answer = answer.ToLower();

        if (answer == "dog")
        {
            Console.WriteLine("You have selected: Dog");                
            Dog name = new Dog(); //?
        }                  
    }

    public string GetName()
    {
        Console.WriteLine("And what is your pets name?");            
        string name = Console.ReadLine();
        return name;
    }
}




mardi 3 janvier 2023

How to create a list of anonymous types using a list of property names

I am trying to create a csv exporter that exports models from our database to a CSV file. As a requirement, for each export, the user is able to select what properties of the model need to be exported.

Is it possible to return an anonymous type with just the selected properties, where the properties are chosen by the user and thus not known

Example Data class:

public class Location
{
    public Location() { }

    public int Id { get; set; }
    public string Name { get; set; }
    public string City { get; set; }
    public string State { get; set; }
}

Manual example:

public IActionResult GetSelectProperties()
{    
    var locations = new List<Location>(); // Assume a filled list

    return new JsonResult(locations.Select(x => new {x.Name, x.City}));
}

The ideal (incomplete) solution

public IActionResult GetSelectProperties2()
{
    var locations = new List<Location>();

    var properties = new List<string>() { "Name", "City" };

    return new JsonResult(locations.Select(x => { < where x in properties ?> }));
}

I have tried using reflection

var property = typeof(Location).GetProperty("Name");

but don't know how to combine the PropertyInfo in the LINQ query.





How to use Reflection in order to avoid value boxing?

I am exploring Blazor's QuickGrid source code and found one interesting spot here.

On the 45th line Steve Sanderson left a TODO with a potentially better alternative solution.

I could not resist my curiosity and decided to give it a try and benchmark the solution afterwards. But, unfortunately, my knowledge in Reflection is really poor.

Could anybody help me to understand how the ideas described in the Steve's comment could be achieved?

Thanks

UPD-1: Code snippet of what I have atm

    if( typeof(TProp).GetInterface(nameof(IFormattable)) != null ) {

    Type result = typeof(Func<,>).MakeGenericType(typeof(TGridItem), typeof(TProp));
        
    _cellTextFunc = item => FormatValue(compiledPropertyExpression);
}

    // TODO: Consider using reflection to avoid having to box every value just to call IFormattable.ToString
    // For example, define a method "string Format<U>(Func<TGridItem, U> property) where U: IFormattable", and
    // then construct the closed type here with U=TProp when we know TProp implements IFormattable

    private string FormatValue<U>( Func<TGridItem, U> property ) where U : IFormattable
    {
        return null;
    }




Retrieve a Class?> type from a .class file

I have a javafx window, and when I drag .class files into it I would like to "transform" them into Class<?>

I tried with Class.forname the problem is that you have to know the package, which is not my case. And I tried to read the .class file with a buffered reader to retrieve the package inside but of course it is not possible to read a .class file.

So I need to find a way to transform any .class file regardless of its location on the computer into Class<?> in my code.

@Override
    public void handle(DragEvent event) {
        Dragboard db = event.getDragboard();
        boolean success = false;
        if (db.hasFiles()) {
            for (File file : db.getFiles()) {
                String fileName = file.getName();
                // Vérifiez si le fichier a l'extension .class
                if (fileName.endsWith(".class")) {

                    //TODO
                    
                    //GlobalView.getInstance().addClassNode(new ClassNode(new Class(  the Class<?> object    )));

                }
            }
        }
        event.setDropCompleted(success);
        event.consume();
    }




lundi 2 janvier 2023

Catch two exceptions and rethrow them [duplicate]

I want to catch two exceptions and log some stuff. Then the exception should thrown again. I get the following message: Unhandled exception type: IllegalAccessException

I tried out many constellations like using two catch blocks, check which class belong to the exception object (instanceof check) and so on. Everytime i get the mentioned above message....

List<Field> objectsList = getObjectList();
StringBuilder sb = new StringBuilder();
objectsList.forEach(a -> {
    try {
        a.setAccessible(true);
        sb.append(".....");
    } catch (IllegalArgumentException | IllegalAccessException e) {
        //Do some stuff
        throw e;
    }
});




dimanche 1 janvier 2023

Function to sort list (array/slice) fields an any struct variable passed as input

I want to write a function that takes any struct variable as input and sorts the list fields in it. The list fields can be of simple type (int/string) or complex (structs) in which case they must implement some comparable interface which has getValue function returning an int and defines its order to be used for sorting.

Example -

type comparable interface {
    getValue() int
}

type innerStruct struct {
    x int
    y string
}

func (s innerStruct) getValue() int {
    return s.x
}

type outerStruct struct {
    a []innerStruct
    b []int
}

func sortListFields(in interface{}) {
    // Implement this
}

func main() {
    val := outerStruct{
        a: []innerStruct{
            {1, "abc"},
            {3, "pqr"},
            {2, "xyz"},
        },
        b: []int{9, 7, 8},
    }

    fmt.Println(sortListFields(val))
    // Should print - {[{1 abc} {2 xyz} {3 pqr}] [7 8 9]}
}

I have been trying to implement it using reflection, but haven't been able to figure out how to sort the field, once I have determined its a slice/array.

func sortListFields(in interface{}) {
    v := reflect.ValueOf(in)
    for i := 0; i < v.NumField(); i++ {
        fk := v.Field(i).Type().Kind()
        if fk == reflect.Array || fk == reflect.Slice {
            fmt.Printf("%v field is a list\n", v.Type().Field(i).Name)
            // How to sort this field ???
        }
    }
}

I have following questions with respect to this.

  • Firstly (as clear from the post), how to implement sorting for the fields ?
  • Are there any other simpler (or may be not so simple) ways with/without reflection of achieving the same ?




What is the difference for type assertion and reflect.Type.Implements

when val := reflect.ValueOf(xx)
I found that
val.Interface().(io.Reader)
has the same effect as
val.Type().Implements(reflect.TypeOf(io.Reader).Elem()),

what is the difference between the two? Performance? which way should I use?

when I tried the following code, I didn't find any difference.

package main

import (
    "fmt"
    "io"
    "os"
    "reflect"
)

func main() {
    reader := reflect.TypeOf(new(io.Reader)).Elem()
    closer := reflect.TypeOf(new(io.Closer)).Elem()

    var f io.Reader = &os.File{}
    val := reflect.ValueOf(f)
    implementReader := val.Type().Implements(reader)
    _, assertReader := val.Interface().(io.Reader)
    fmt.Println(implementReader) // output: true
    fmt.Println(assertReader)    // output: true

    implementCloser := val.Type().Implements(closer)
    _, assertCloser := val.Interface().(io.Closer)
    fmt.Println(implementCloser) // output: true
    fmt.Println(assertCloser)    // output: true
}

go playground





How can I use reflection with varying classes?

What I'm trying to achieve here is that I want to insert data into a database from file using a CRUD class with type . I'm gonna demonstrate a simple example of the situation.

public class SubjectTester<T>where T : class
    {
        public void Create()
        {
            var db_context = new DbContext();
            //here I get file content and do stuff with it
            //here I want create an instance of T and add the data from the file
            //here I will use the Add method from my DbContext and save the changes
        }
    }
    public class DbContext 
    {
        //has some stuff
    }
    public class TestSubjectA
    {
        //some properties
        public int Id { get; set; }
        public string Name { get; set; }
    }
    public class TestSubjectB
    {
        //some properties
        public double Sum { get; set; }
    }
    public class TestSubjectC
    {
        //some properties
        public int Id { get; set; }
        public string Name { get; set; }
        public bool IsRigged { get; set; }
    }

As you can see the problem is that some tables have more columns than others and also the data types are different aswell. I'm doing this because I want to dynamically add data depending on the class that I get. Also I don't want to have a bunch of if elses to check what is the type of T... I hope I was clear in my explanation.