vendredi 30 septembre 2022

How can I statically acquire the type of an inheriting class from an inherited method?

The problem:

Given I have the following:

using System;
public class BaseClass{
        public static Type TypeOfThis => //Somehow get the type of the inheriting class?
        public static void HelloWorld() => Console.WriteLine($"Hello world, I am {TypeOfThis.Name}");
}
public class InheritingClass:BaseClass{}

How can I reference the type of the inheriting class?

GetType requires a reference, which we do not have, as we are working statically.





How to iterate through the members of a standard module

My goal is to list the procedures exposed by the compiled VBProject, as visible in the Excel Macros menu or when typing a cell formula which makes appear availble UDF. A Solution that list any member (Enum, Sub, Function, etc.) of a CodeModule or of the full VBProject would be ideal.

I am not looking for a code parsing solution.

I could find old mentions of a way to do so in VB with the VBIDE library, which ( should / used to ) expose a VBIDE.Member class (accessible via the CodeModule.Members property) with those interesting properties:

Member.Name As String
Member.Type As VBIDE.vbext_MemberType
Member.Scope As VBIDE.vbext_Scope

For a reason I don't understand, I cannot access them via VBA and the VBIDE library, there are not even listed as hidden members.

Is there a way to get them? Rubberduck (previously known as Mat's Mug heon Stack Overflow) aka Mathieu Guindon suggests it is possible though: https://rubberduckvba.wordpress.com/2016/03/24/a-reflection-on-vba-reflection/

Another idea: how to use Reflection with VBA? Again, he suggests it is possible: https://rubberduckvba.wordpress.com/2019/04/10/whats-wrong-with-vba/

Note: the Rubberduck COM Add-In that integrates with the VBE, is able to do it (using .NET as I understand it)





Geeting error when reflecting .class file from jar file which .class file is extending or implementing other class which class is present in dependenc

I have a jar file which contains only testcase.class files. I need to parse that and find all the classes defined in that jar file and need to generate one report. I tried to do it with the reflection concept in Java. Some how, when loading a class is fine, but trying to get the declared methods of it, I am getting the following error. (Note class is loaded, I am able to get the name and canonical name of the loaded class but I error at trying to get declared methods).

for (String clazz: classes) {  
            String className = clazz.replaceAll("/",  
 ".").replaceAll(".class","");  
            try {  
                URL url = file.toURI().toURL();  
                URL[] urls = new URL[]{url};  
                URLClassLoader cl = new URLClassLoader(urls);  
                Class cls = cl.loadClass(className);  
                System.out.println("##############################");  
                cls.getDeclaredMethods();
                //clazzes.add(getClassObject(cls));  
                //break;  
            } catch (MalformedURLException e) {  
                e.printStackTrace();  
            } catch (ClassNotFoundException e) {  
                e.printStackTrace();  
            }  
        }  



Exception in thread "main" java.lang.NoClassDefFoundError: javax/mail/Authenticator
    at java.base/java.lang.ClassLoader.defineClass1(Native Method)
    at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1016)
    at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:174)
    at java.base/java.net.URLClassLoader.defineClass(URLClassLoader.java:555)
    at java.base/java.net.URLClassLoader$1.run(URLClassLoader.java:458)
    at java.base/java.net.URLClassLoader$1.run(URLClassLoader.java:452)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:451)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:588)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
    at com.springboot.example.springBootExample.service.JarParserService.getTypes(JarParserService.java:99)
    at com.springboot.example.springBootExample.service.JarParserService.constructPackages(JarParserService.java:86)
    at com.springboot.example.springBootExample.service.JarParserService.getClassTypes(JarParserService.java:78)
    at com.springboot.example.springBootExample.service.JarParserService.scanJar(JarParserService.java:61)
    at com.springboot.example.springBootExample.service.JarParserService.getAllPackages(JarParserService.java:34)
    at com.springboot.example.springBootExample.service.FindClassesFromJarService.parseJar(FindClassesFromJarService.java:61)
    at com.springboot.example.springBootExample.service.FindClassesFromJarService.main(FindClassesFromJarService.java:31)
Caused by: java.lang.ClassNotFoundException: javax.mail.Authenticator
    at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:476)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:588)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
    ... 17 more

Process finished with exit code 1




jeudi 29 septembre 2022

Allow reflection from non-owned library

I'm facing a future problem that I have to solve right now and the problem is a class from a library I do not own (Jackson) that is accessing through reflection to another. To be more specific, this is the warning that I'm trying to solve:

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by com.fasterxml.jackson.module.afterburner.util.MyClassLoader (file:/Users/pedro.maria/.m2/repository/com/fasterxml/jackson/module/jackson-module-afterburner/2.13.4/jackson-module-afterburner-2.13.4.jar) to method java.lang.ClassLoader.findLoadedClass(java.lang.String)
WARNING: Please consider reporting this to the maintainers of com.fasterxml.jackson.module.afterburner.util.MyClassLoader
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release

Now, the most frustrating part is that I'm staring the solution in the face, the --add-opens flag that needs to be passed to the JVM in order for it to know that this reflection is intended. For some reason I'm not being able to figure out a couple of things which are:

  • Where should this flag be passed? (Through MAVEN_OPTS, as a Maven argument such as -DargLine, in the Dockerfile, etc...)

  • What should the --add-opens flag look like? (I've tried --add-opens java.base/java.lang=ALL-UNNAMED which doesn't make sense to me since I think I should be referencing the Jackson module which I can't find because the documentation is scattered everywhere and not helpful

These are the sources that I took a look at before coming here for help:

PS: If the answers could include an explanation of how you formulated the --add-opens flag to properly solve the warning messages I would be very thankful because I've been trying to understand this for a while now but with no success.





Java Annotation Processor handle modified source code positions

I'm writing custom annotation processor and got struggling with code elements' positions.

Imagine I have the code:

    public class DummyStepClass {

        @Step
        public void getInfo() throws Exception {
            HttpClient client = HttpClient.newBuilder().build();
            @Remember("REQUEST") HttpRequest request = HttpRequest.newBuilder()
                    .uri(new URI("https://postman-echo.com/get"))
                    .GET()
                    .build();
            @Remember("RESPONSE") HttpResponse<String> response = 
                    client.send(request, HttpResponse.BodyHandlers.ofString());
            System.out.println(response.statusCode());
            System.out.println(response.body());
        }
    }

Purpose of annotation is to save variable into context of a program flow through my steps.

Context class:

    public class Context {

        private static final HashMap<String, Object> storage = new LinkedHashMap<>();

        private Context() {}

        public static void save(String k, Object v) {
            storage.put(k, v);
        }
    }

Literally I want to achieve invoking Context.save(k, v); when annotated rather than writing it every time.

So as a result I want to have something like this:

    public class DummyStepClass {

        @Step
        public void getInfo() throws Exception {
            HttpClient client = HttpClient.newBuilder().build();
            HttpRequest request = HttpRequest.newBuilder()
                    .uri(new URI("https://postman-echo.com/get"))
                    .GET()
                    .build();
            Context.save("REQUEST", request);
            HttpResponse<String> response =
                    client.send(request, HttpResponse.BodyHandlers.ofString());
            Context.save("RESPONSE", request);
            System.out.println(response.statusCode());
            System.out.println(response.body());
    }
}

I do generate this lines of code and they appears in .class files. However this two statements are added in the end of a method.

How can I handle this?





How can I make this reflection code work for any specific case of a generic type?

I have some data coming from some system via a TcpClient.

The system is a kind of column store with it's own way of representing null values. The system supports null for any type including int, DateTime etc.

The TcpClient returns values like DateTime.MinValue in case of nulls. But the client also has a null checking utility.

I have put together some reflection code to generate types, which works fine as long as I don't have any option types. I want to adapt this code to map null values to Option<'t>.

So far, I have the following utility.

let checkNull (x:obj) =
    let elementType = x.GetType()
    let defType = typedefof<ValueOption<_>>;
    let genericType = defType.MakeGenericType elementType
    let optionCaseInfoSome, _ = FSharpValue.GetUnionFields(DateTime.Now |> ValueSome :> obj, genericType)
    let valueNone:ValueOption<DateTime> = ValueNone
    let optionCaseInfoNone, _ = FSharpValue.GetUnionFields(valueNone :> obj, genericType)
    if KdbConstants.IsNull x then
        FSharpValue.MakeUnion(optionCaseInfoNone, Array.empty)
    else
        FSharpValue.MakeUnion(optionCaseInfoSome, [|x|])

This will only work for Option<DateTime> values. How can I adapt this to work for any Option<t>`?

PS: I am aware that my utility is not efficient and much of the values can be pre-calculated, rather than being run each time the function is called. I will clean it up once I get it to work.





Proxy js object: where are defined arguments when calling a function using Reflect.get()

Trying to understand the internals of Proxy and Reflect built-in objects, I've reached - IMO - an interesting "how does this even work" point:

Let's say I want to wrap into a Proxy this object and detect when we're accessing a callable property:

const obj = {
 v: 42,
 foo(n) { return this.v + n }
} 
const pObj = new Proxy(obj, {
  get(target, prop, r) {
    if (typeof target[prop] === 'function') {
      console.log('accessing a function, arguments: ', { ...arguments })
    }
    return Reflect.get(...arguments);
  }
}) 

This code just works:

pObj.foo(1000) // « 1042

Printing this trace:

trace when calling the function

Which reads: arguments has

  • target ([0]): the object
  • prop ([1]): "foo"
  • receiver ([2]): the proxy object itself.

My question is, where is defined the function argument (1000) that is applied to foo(n)? isn't defined in arguments? is it possible to validate this argument before calling Reflect.get(...arguments)?





mercredi 28 septembre 2022

Kotlin Class Reflection Not Working in .kt File

I have a .kt Fragment file in my project and I'm trying to start a new activity with the following code:

profilePref?.setOnPreferenceClickListener {
            val profileIntent = Intent(activity, ProfileActivity::class.java)
            startActivity(profileIntent)
            true
        }

I have included both

implementation ("org.jetbrains.kotlin:kotlin-reflect:1.7.10")

in my module build.gradle and

classpath "org.jetbrains.kotlin:kotlin-android-extensions:$kotlin_version"

in my project build.gradle, but the class.java still gives me unresolved reference and I'm not really sure why, any help would be appreciated.





How to obtain extension properties by Kotlin reflection?

I have used the memberExtensionProperties() method, but result collection of the extension properties is empty. The test code is attached. What is the right procedure?

class ExtensionPropertyTest {
    class DummyClass{}
    val DummyClass.id get() = 99
    val DummyClass.name get() = "Joe"

    @Test
    fun testExtensionProperties() {
        val dummyClass = DummyClass()
        expect(dummyClass.id).toEqual(99) // OK

        val properties = DummyClass::class.memberExtensionProperties
            .stream()
            .toList()
        expect(properties).toHaveSize(2) // Fails due a zero size
    }
}




#include <rttr/registration>

struct MyStruct { MyStruct() {}; int data[3]; };

RTTR_REGISTRATION
{
    using namespace rttr;

    registration::class_<MyStruct>("MyStruct")
      .constructor<>()
      .property("data", &MyStruct::data);
}

int main() {
    return 0;
}

complied error: error C2668: 'operator new[]': ambiguous call to overloaded function





mardi 27 septembre 2022

Use java operator :: dynamically

I have the following implementation:

private SomeWritter someWritter(String someArgument) {
    SomeWritter.Builder builder = SomeWritter.builder(someArguments);
    builder = builder.addColumn("colName1", TargetClass::getArg1)
    builder = builder.addColumn("colName2", TargetClass::getArg2)
    return builder.build();
}

private Builder<T> addColumn(String colName, ToDoubleFunction<T> getter){
   //implementation goes here
}

my issue is that I need to iterate over the addColumns call, something among these lines:

private void SomeWritter(String someArgument) {
    SomeWritter.Builder builder = SomeWritter.builder(someArguments);
    for (Field field : getFilteredFieldsFromClass(TargetClass.class)) {
        builder = builder.addColumn(field.getName(), [SOMEHOW GET THE REF TO GETTER HERE])
    }
    return builder.build();
}

in order to get the refference to the getter, I tryed to do TargetClass.class.getMethod("getArg1", ...);

this works, but I have a Method, not a ToDoubleFunction.

I need to somehow get that ToDoDoubleFunction, programatically, I want to do the same that the TargetClass:: does, dinamically, not harcoded. any ideas ?





Get generic value from a generic struct using reflection

Imagine I have the following struct:

type MyGeneric[T string | int] struct {
}

I want to check whether the generic used to instantiate that struct was a string or a int when creating a new MyGeneric.

myGenericString := MyGeneric[string]{}
myGenericString.canHandle("hello") -> should return true
myGenericString.canHandle(8) -> should return false

func (mG MyGeneric[T]) canHandle(value any) bool {
    // how to get what T is the same type as value
}





vendredi 23 septembre 2022

Why I cannot change static final int field with reflection from kotlin android

I have following java class with static final int which I need to change via reflection:

class DateValidator {
   public static final int DIFF = 20;
}

And from Android Kotlin I try to change it value from 20 to 100:

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        println("@@@@DateValidator.DIFF: ${DateValidator.DIFF}")
        val clazz = DateValidator::class.java
        println("@@@clazz: $clazz")
        val field: Field = clazz.getDeclaredField("DIFF")
        println("@@@field: $field")
        println("@@@field.isAccessible: ${field.isAccessible}")
        field.isAccessible = true
        println("@@@field.isAccessible2: ${field.isAccessible}")
        val fieldAccessFlags: Field = Field::class.java.getDeclaredField("accessFlags")
        println("@@@fieldAccessFlags: $fieldAccessFlags")
        println("@@@fieldAccessFlags.isAccessible: ${fieldAccessFlags.isAccessible}")
        fieldAccessFlags.isAccessible = true
        println("@@@fieldAccessFlags.isAccessible2: ${fieldAccessFlags.isAccessible}")
        fieldAccessFlags.setInt(field, field.modifiers and Modifier.FINAL.inv())
        field.set(null, 100)
        println("@@@@DateValidator.DIFF2: ${DateValidator.DIFF}")
        field.setInt(null, 100)
        println("@@@@DateValidator.DIFF3: ${DateValidator.DIFF}")

    }

And I have following output in Logcat:

@@@@DateValidator.DIFF: 20
@@@clazz: class com.droiddevstar.changestaticprj.DateValidator
@@@field: public static final int com.droiddevstar.changestaticprj.DateValidator.DIFF
@@@field.isAccessible: false
@@@field.isAccessible2: true
@@@fieldAccessFlags: private int java.lang.reflect.Field.accessFlags
@@@fieldAccessFlags.isAccessible: false
@@@fieldAccessFlags.isAccessible2: true
@@@@DateValidator.DIFF2: 20
@@@@DateValidator.DIFF3: 20

Perhapse reflection doesn't work with primitive int?





dart: reflect methods of a class, no luck with the reflect*() functions

I'm trying to list the methods of a class, but neither reflectClass() nor reflectType() return anything useful. Has anyone done this already?





Why if I return primitive long type class in getColumnClass sorting in jtable doesn't work?

I have a problem with sorting primitive long in JTable. I have a class, this class extends AbstractTableModel and overrides method getColumnClass, here is the code of this method:

public Class<?> getColumnClass(int columnIndex) {
        return columnFields[columnIndex].getType();
}

So, this method uses reflection api for getting class type. And I notice, that, if I change in my class(which stored in this tablemodel) type from long on Long, sorting will work correct. But if I use long instead Long, jtable interpreters this value as a string and sorting it as a string. Notice: columnFields is array of fields of the stored class. What is this? How to fix it? How to make this working for any type long or Long?





jeudi 22 septembre 2022

C# What type in an assembly does not belong to a Namespace?

Console.WriteLine("Please choose a method to obtain a table:\n");

        Type[] current = Assembly.GetExecutingAssembly().GetTypes();
                    
        for(int i = 0, j = 1; i < current.Length; i++)
        {
            if (current[i].IsClass && current[i].Namespace.Contains("parser", StringComparison.InvariantCultureIgnoreCase) &&
                current[i].Name.Contains("parser", StringComparison.InvariantCultureIgnoreCase))
            {
                Console.WriteLine("{0}.{1}", j, current[i].Name);
                j++;
            }
        }

In this code the condition

current[i].Namespace

is highlighted as

Dereference of a possibly null reference.

I've checked Type metadata and found that the property returns null if the current instance has no namespace.

My question is what kind of type in an assembly could not belong to a Namespace?





System.InvalidOperationException while dynamically enumerating and retrieving .NET6 Entity Framework DbContext DbSet<...>s instances' records

The subject runtime error's location is inside the following code. Please advise how to fix this issue.

using (var ctx = new MyDbContext())
{
    foreach (var entityInfo in ctx.GetEntitiesInfo())
        System.Console.WriteLine($"{entityInfo.Index}. EntityName = {entityInfo.Name}, Records count = {entityInfo.RecordCount}");
}

public static class Extensions
{
    public readonly record struct EntityInfo (int Index, string? Name, int RecordCount);

    public static IEnumerable<EntityInfo> GetEntitiesInfo(this MyDbContext context)
    {
        var dbSetProperties = context.GetDbSetProperties();
        var dbSets = dbSetProperties.Select(x => x.GetValue(context, null)).ToList();
        var index = 0;
        foreach (IQueryable? dbSet in dbSets)
        {
            ++index;
            // Runtime Error happens on next code line on second iteration
            //   when index = 2:
            //
            // System.InvalidOperationException:
            // 'There is already an open DataReader associated with
            //  this Connection which must be closed first
            //-
            dbSet.Load();
            var items = new List<object>();
            var enumerator = dbSet?.GetEnumerator();
            while (enumerator?.MoveNext() == true)
            {
                var item = enumerator.Current;
                items.Add(item);
            }

            yield return new EntityInfo(index, dbSet?.ElementType?.ToString(), items.Count);
        }
    }
    public static IEnumerable<PropertyInfo> GetDbSetProperties(this MyDbContext context)
    {
        foreach (var property in context.GetType().GetProperties())
            if (property?.PropertyType?.FullName?
                .Contains("Microsoft.EntityFrameworkCore.DbSet`") == true)
                     yield return property;
    }
}




Java Method.getAnnotation(Class?> annotation) returns null when annotation is present on the method

So I have this annotation ...

package com.github.benchmarkr.annotation;

// IMPORTS

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Benchmark {
}

It's used to mark a method in a class as a benchmarking test. So I have this class ...

// IMPORTS ...

public class LexerBenchmark {
  @Benchmark
  public void test() {

  }
}

I run the benchmark scanner in debug mode and stop at a point in which I have this classesInPackage variable which is a list of all the discovered classes that fall within a target package. I see the one class shown above (LexerBenchmark) in that list at index 101.

So in the debugger I do classesInPackage.get(101).getDeclaredMethods() and sure enough see my one declared method.

I then do classesInPackage.get(101).getDeclaredMethods()[0].getAnnotations() and see my annotation (com.github.benchmarkr.annotation.Benchmark) in that list.

So I run classesInPackage.get(101).getDeclaredMethods()[0].getAnnotation(Benchmark.class) and I get null. It's weird but seems like it could have had something to do with the fact that the module for the Benchmark.class on the method seemed to be different than the one referenced directly (see the screenshots below).

Things get really weird when I use the same exact value from that list ...

classesInPackage
  .get(101)
  .getDeclaredMethods()[0]
  .getAnnotation(
    classesInPackage
    .get(101)
    .getDeclaredMethods()[0]
    .getAnnotations()[0]
    .getClass()
  )

and I still get null. How could that be possible?

Here are some images from my debugger... Benchmark.class LexerBenchmark.test Method LexerBenchmark.test.getAnnotations() NullResult WeirdNullResult





Any Alternative frameworks with Spring like features without using java reflection?

It seems like Java reflections are having a huge performance impact on the spring application startup based on the size of the applications. So I am looking for an alternative framework like spring without reflection. Kindly Suggest me If you know. If None, Any other alternative options in pure Java itself now or in future?





mercredi 21 septembre 2022

C# why can i manually set value but cant by setvalue(reflection)?

when i try to access a field and set value like asm.getField("name").setValue(obj,function); i get an error : 'Object of type 'System.Action`1[System.String]' cannot be converted to type 'ReflectionAndPlugins.Human+addToConsole'.'

There is my code below

using System.Reflection;

namespace ReflectionAndPlugins {

public partial class Form1 : Form
{
    delegate void rundel();
    delegate void DaddToConsole(string txt);
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        Assembly asm = Assembly.GetExecutingAssembly();

       foreach (Type item in asm.GetTypes())
        {
            if(item.Name == "Human")
            {
                object ahmet = Activator.CreateInstance(item);
                ((Human)ahmet).func = addToConsole; // WORKS
                // item.GetField("func").SetValue(ahmet, addToConsole); DOENST WORK ?
                item.GetField("name").SetValue(ahmet, "ahmet");
                object[] param = { "Ali" };
                item.GetMethod("greet").Invoke(ahmet, param);
            }
        }
    }
    void addToConsole(string txt)
    {
        textBox1.AppendText(txt);
        textBox1.AppendText(Environment.NewLine);
    }
}
public class Human
{
    public string name;
    public delegate void addToConsole(string txt);
    public addToConsole func;
    public void greet(string who)
    {
        func("Hi "+who+", im "+name+"!");
    }

}

}





mardi 20 septembre 2022

How do you check if a property has IsRequired() on an object using reflection?

I have a string property it is configured as IsRequired() using FluentAPI. How do I check if this property is required? I'm iterating through all properties of my object using reflection.





Getting MethodInfo at compile time for a non-static method

I'm working on a program that calculates expressions at runtime based on a set of inputs, then executes those remotely. This requires creating expressions dynamically that call different helper functions.

For static helper functions, compile-time safety can be guaranteed by using the following to get a MethodInfo instance:

var myMethodInfo = ((Func<int, int>) Helpers.MyStaticHelper.DoSomethingUseful).Method

Using this, if Helpers.MyStaticHelper.DoSomethingUseful were to change it's name or signature, this would result in a compile-time error. However, it only appears to work for static methods. Using a similar approach for non-static gives a CS0120 An object reference is required for the nonstatic field, method, or property 'Helpers.MyDynamicHelper.DoSomethingElse(int, int)'.

A workaround is possible by using something like this:

var myMethodInfo = typeof(Helpers.MyDynamicHelper).GetMethod("DoSomethingElse")

However this risks a runtime exception if DoSomethingElse is altered. I'm aware it's not possible to invoke the method without an instance, but these instances are needed for collecting and caching prerequisite data, so any instance created before executing the expression would be incorrect.

Is it possible to get a compile-time safe MethodInfo for the method without an instance?





Json schema to Java entity class

I am a java client developer. We have a requirement of generating java entity class from json. Although Json to pojo is possible through multiple libraries, our requirement is to Json to JPA entity class.

Can we use dynamic proxy to generate this

Json:

{

  "properties" : {
    "id" : {
      "type" : "string"
    },
    "lock" : {
      "type" : "string"
    },
    "version" : {
      "type" : "integer"
    }
  }
}

Java entity class


package com.testclient;

import java.util.Objects;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Transient;
import javax.persistence.Version;



@Entity
@Table(name = "DUMMYMODEL")
public class DummyModel implements Model<String> {
    @Id
    private String id;

    @Version
    private Long version;

    @JsonIgnore
    @Transient
    private String lock;

    public DummyModel() {
    }

    public DummyModel(String id) {
        this.id = id;
    }

    @Override
    public String getId() {
        return id;
    }

    @Override
    public Long getVersion() {
        return version;
    }

    @Override
    public String getLock() {
        return lock;
    }

    @Override
    public void setVersion(Long version) {
        this.version = version;
    }

    @Override
    public void setLock(String lock) {
        this.lock = lock;
    }

  
    @Override
    public String toString() {
        return "DummyModel [id=" + id + ", version=" + version + ", lock=" + lock + "]";
    }
}

Am aware of https://www.jsonschema2pojo.org/ which generates pojo.





dimanche 18 septembre 2022

How can I generate Jdk Dynamic Proxy class codes in JDK17?

Is there a proper way to view the .class file that JDK generated while running? Why is ProxyGenerator final in JDK17?





samedi 17 septembre 2022

Programmatically get a list of method names in a form

I would like to be able to get a list of names of all the methods in a form (similar to the list obtained by pressing Alt+M).





JS Can I somehow get instance of class by name if the classes are inside closure?

I'm working on a plugin system for mine service, and I load the plugins code from text using the new Function() construction. And I need somehow get access to the classes constructors link outside the plugin code. (for testing, unit tests)

Here is, I see a few solutions (if you know another solution, I'm open to your idea).

  1. add link to classes in the window object (global env)
  2. return the classes list as a result of loading and provide to the place where I need to use it.

The second one it too complicated for testing and required change the entire app for testing, that is not perfect. The first one creates one more global variable that is not perfect as well, but it's ok for testing environment (so for now I've chosen this solution).

The next question, how to do it reusable for any plugin (the class provider for testing env) should not depend on the specific plugin classes, but the plugin can depend on some function, and we can specify the correct plugin code structure.

I suppose that I could be done by using something like this (much simplified version):

function getClassInstanceFactoryMethod(){

   class A{
   }

   class B{
   }

   return (className, params)=>{
      return new className(...params); //need somehow choose the correct class and avoid the switch construction or manual collection in an array. 
   }
}

const buildObject = getClassInstanceFactoryMethod();
let objeA = buildObject('A');  //expected object of the A class 
let objeA = buildObject('B');  //expected object of the B class 

But the problem is avoided, enumeration of plugins class list (load it automatically).

Please any idea how to do it.





mercredi 14 septembre 2022

How can I search an IEnumerable list of objects for fields based on a text command?

I am trying to make a function that you can pass a IEnumerable of objects and a string with a dot notation command and have the function search through the objects within the list and pick out the values if they exist.

Such as Tool.Laser.x would search through the objects in the list and find The tool object with a field named Laser and return it's field named x's value. Also it should be so that it doesn't matter what structure object you pass it, it should be able to search through all of the objects and fields for the names you specify in the string passed in.

My issue is being able to traverse the fields inside each object in the list.. like to be able to iterate over them and evaluate them and find new fields to evaluate their values. I am really new to reflection, I can get the fields if I know the structure but I am unsure how to iterate through the fields and search for the name specified by the text command passed. I looked into LinQ but from what I have seen you have to know the names of the fields to do anything with it. Any help would be appreciated.





CSS/JS? How to reflect a border-radius?

border-radius does not reflect

I try to code a little rock-paper-scissors based game and used the CSS/JS-code from this youtube tutorial to create neon buttons with a snake animation around the edges of the button.

https://youtu.be/3RRgVHd2TXQ

I then softened the edges of the buttons using "border-radius: 15px" - but the reflection has still sharp corners. How can I solve this?

Also the snake-animation to shine around the edges of the button does not work :( - would be great to know why!?

Try the game: https://bamory.com/?hotlink=FARTWAR (click link to start a game-session and invite another player with the session-code appearing on top of the screen)

CODE:

html{
  text-align: center;
  }

}

body.chapter2 {
    color: yellow;
}

input {
    margin: 10px;
    height: 50px;
    width: 90%;
}

@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@200;300;400;500;600;700;800;900&display=swap');
*
{
    margin: 0;
    padding: 0;
    font-family: 'Poppins', sans-serif;
    box-sizing: border-box;
}
body
{
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
    background: #050801;
  flex-direction: column;
}
.button
{
  border-radius: 15px;
    position: relative;
    display: inline-block;
    padding: 10px 15px;
    margin: 10px 10px;
    color: #03e9f4;
    font-size: 24px;
    text-decoration: none;
    text-transform: uppercase;
    overflow: hidden;
    transition: 0.5s;
    letter-spacing: 4px;
    -webkit-box-reflect: below 1px linear-gradient(transparent, #0005);
  width: 25%;
}
.button:nth-child(1)
{
    filter: hue-rotate(290deg);
}
.button:nth-child(3)
{
    filter: hue-rotate(110deg);
}
.button:hover
{
    background: #03e9f4;
    color: #050801;
    box-shadow: 0 0 5px #03e9f4,
                0 0 25px #03e9f4,
                0 0 50px #03e9f4,
                0 0 200px #03e9f4;
}
.button span
{
    position: absolute;
    display: block;
}
.button span:nth-child(1)
{
    top: 0;
    left: 0;
    width: 25%;
    height: 2px;
    background: linear-gradient(90deg, transparent, #03e9f4);
    animation: animate1 1s linear infinite;
}
@keyframes animate1
{
    0%
    {
        left: -100%;
    }
    50%, 100%
    {
        left: 100%;
    }
}
.button span:nth-child(2)
{
    top: -100px;
    right: 0;
    width: 2px;
    height: 100%;
    background: linear-gradient(180deg, transparent, #03e9f4);
    animation: animate2 1s linear infinite;
    animation-delay: 0.25s;
}
@keyframes animate2
{
    0%
    {
        top: -100%;
    }
    50%, 100%
    {
        top: 100%;
    }
}
.button span:nth-child(3)
{
    bottom: 0;
    right: -100%;
    width: 100%;
    height: 2px;
    background: linear-gradient(270deg, transparent, #03e9f4);
    animation: animate3 1s linear infinite;
    animation-delay: 0.5s;
}
@keyframes animate3
{
    0%
    {
        right: -100%;
    }
    50%, 100%
    {
        right: 100%;
    }
}
.button span:nth-child(4)
{
    bottom: -100%;
    left: 0;
    width: 2px;
    height: 100%;
    background: linear-gradient(360deg, transparent, #03e9f4);
    animation: animate4 1s linear infinite;
    animation-delay: 0.75s;
}
@keyframes animate4
{
    0%
    {
        bottom: -100%;
    }
    50%, 100%
    {
        bottom: 100%;
    }
}

Thanks for your help! (it´s my first time using JS / stackoverflow - please forgive me if I inserted too much code or did other mistakes!)





mardi 13 septembre 2022

How do you make two interfaces reference the same object?

I would like to make two interfaces reference the same object.

package main

import (
    "fmt"
    "reflect"
)

func main(){
    var a, b any

    a = "Hi"

    b = reflect.ValueOf(&a).Elem()
    a = reflect.ValueOf(&b).Elem()

    b = "Howdy"

    fmt.Println(a)
    fmt.Println(b)
}

PRINT LOGS

Howdy
Howdy

PLAYGROUND: https://go.dev/play/p/qizVO42UaUj

This code works as intended, aside from the fact that a and b are not interfaces. So when I convert them to interfaces like so...

package main

import (
    "fmt"
    "reflect"
)

func main(){
    var a, b any

    a = "Hi"

    b = reflect.ValueOf(&a).Elem().Interface()
    a = reflect.ValueOf(&b).Elem().Interface()

    b = "Howdy"

    fmt.Println(a)
    fmt.Println(b)
}

PRINT LOGS

Hi
Howdy

PLAYGROUND: https://go.dev/play/p/jCpuepBJYdD

...the code no longer works as intended. Is there a way to convert from the reflect.Value data type to the interface data type while maintaining that the two variables reference the same object?





Getting a Method from a method reference

I have a method inside a class:

class Foo {
    fun bar()
}

And I want to pass the method bar to a third-party library method that takes a java.lang.reflect.Method argument:

   fun baz(Method method)

How do I do that? Ideally is there some function call f(Foo::bar) that takes a method reference and returns a Method?





dimanche 11 septembre 2022

Get Generic Type from a Run-Time type Parameter in Java

So I've read a lot of other questions out there, but I cannot find one with similar case as mine. Assume I have the following code:

public class TestClass
{
    public Class clazz;

    public TestClass(Object input)
    {
        this.clazz = ........ ?? // how to get String.class from "input" parameter?
    }

    public static void main(String[] args)
    {
        List<String> all = new ArrayList<>();
        new TestClass(all);
    }
}

The constructor of TestClass has 1 parameter which is an Object type. But at runtime, it receives a variable of type List, but the actual instance is an ArrayList. Inside the TestClass constructor, I want to extract the generic type of that ArrayList from input parameter. The expected result should be String.class object, which can be stored in clazz variable.





samedi 10 septembre 2022

(Java) using reflection to add elements to an arrayList from another class

I'm trying to make a mod, so I have been looking for a way to access a protected arrayList from another class. So far I have managed to use my new basic understanding of java reflection in order to do so. I have been able to find the field I am looking for but so far I have not yet been able to find a way to modify its elements because I believe that it is the casting that leads to multiple errors, any suggestions for a way to solve this:

My code (repository https://github.com/dilosir22/BTAprodject/tree/master/src/main/java/com/example/examplemod):

public class LivingEntityHelper {

   static Field monsterList;

    static {
        try{
            Field[] feilds = BiomeGenBase.class.getDeclaredFields();
            for(Field feild : feilds) {
                    if(feild.getName().equals("spawnableMonsterList")) {
                        monsterList = feild;
                    }

            }
            if(monsterList == null) throw new RuntimeException("Could not find spawnableMonsterList feild!");
            monsterList.setAccessible(true);
        }catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    @SuppressWarnings("unchecked")
    public static void addMonster(SpawnListEntry monster, Object biome){
        try {
            ((List<SpawnListEntry>) monsterList.get(biome)).add(monster);
        }catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

}

biomeGenBase contains:

    protected List<SpawnListEntry> spawnableMonsterList;

as well as multiple static instances of itself (what the biome parameter in addMonster() is meant to specify when used) this in its constructor:

        this.spawnableMonsterList = new ArrayList();

the errors recieved:

[18:57:32] [Minecraft main thread] java.lang.RuntimeException: java.lang.IllegalArgumentException: Can not set java.util.List field net.minecraft.src.BiomeGenBase.spawnableMonsterList to java.lang.Class [18:57:32] [Minecraft main thread] at com.example.examplemod.util.LivingEntityHelper.addMonster(LivingEntityHelper.java:35) [18:57:32] [Minecraft main thread] at com.example.examplemod.ExampleMod.init(ExampleMod.java:15) [18:57:32] [Minecraft main thread] at bta.ModLoader.loadMod(ModLoader.java:120) [18:57:32] [Minecraft main thread] at bta.ModLoader.init(ModLoader.java:76) [18:57:32] [Minecraft main thread] at net.minecraft.client.Minecraft.startGame(Minecraft.java:309) [18:57:32] [Minecraft main thread] at net.minecraft.client.Minecraft.run(Minecraft.java:566) [18:57:32] [Minecraft main thread] at java.base/java.lang.Thread.run(Thread.java:833) [18:57:32] [Minecraft main thread] Caused by: java.lang.IllegalArgumentException: Can not set java.util.List field net.minecraft.src.BiomeGenBase.spawnableMonsterList to java.lang.Class [18:57:32] [Minecraft main thread] at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167) [18:57:32] [Minecraft main thread] at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171) [18:57:32] [Minecraft main thread] at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:58) [18:57:32] [Minecraft main thread] at java.base/jdk.internal.reflect.UnsafeObjectFieldAccessorImpl.get(UnsafeObjectFieldAccessorImpl.java:36) [18:57:32] [Minecraft main thread] at java.base/java.lang.reflect.Field.get(Field.java:425) [18:57:32] [Minecraft main thread] at com.example.examplemod.util.LivingEntityHelper.addMonster(LivingEntityHelper.java:33) [18:57:32] [Minecraft main thread] ... 6 more





How to get a single struct with a struct array in reflect

type Foo struct {
    Bar interface{}
    Nothing string
}

type A struct {
    ...
}
type B struct {
    ...
}

var car Foo

In the program, car.Bar maybe []A or []B.

I don't know what is real 'Foo' before the program running, when I use this:

reflect.New(reflect.TypeOf(car).Field(1)) // here I can get a array []A or []B's type only

But now I have to append a new object to car.Bar. Help me, how do I append this, I can't find a function in reflect doc anymore.





vendredi 9 septembre 2022

Typescript, create a Mediator resolver for classes

I'm new with Typescript and I'm trying to create something like MediatR for C# in Typescript.

I've this scenario:

Interfaces:

export interface ICommand {}

export interface ICommandResult {}

export interface ICommandHandler<ICommand, ICommandResult> {
    execute(request: ICommand): ICommandResult;
}

implementations:

export interface ConcreteCommand extends ICommand {
    name: string;
}

export interface ConcreteResult extends ICommandResult {
    name: string;
}

export class ConcreteCommandHandler
    implements ICommandHandler<ConcreteCommand, ConcreteResult> {
    public execute(request: ConcreteCommand): ConcreteResult {
        let result: ConcreteResult = {
            name: request.name
        }

        return result;
    }
}

What I want to reach is something like this:

//pseudocode!
let command: ConcreteCommand = { 
 name: "mycommand!";
}

let handler = CommandHandlersFactory().Create<ConcreteCommand>(command);
let result = handler.execute();

But I'm stuck inside the "CommandHandlersFactory().Create()" implementation because I don't know to to resolve the right CommandHandler with the right key (type).

My idea was to have a Map<ICommand, ICommandHandler>() so I can do something like this:

//Psudocode!
_map<ICommand, ICommandHandler>() = new Map();
_map.set(ConcreteCommand, ConcreteCommandHandler);
 
Create<T>(command: ICommand) {
 let concreteCommandHandlerType = _map[command];
 return new concreteCommandHandlerType();
}

Is even possibile to do something like this in Typescript?

Thanks a lot!





jeudi 8 septembre 2022

Why does String creation using `newInstance()` method behave different when using `var` compared to using explicit type `String`?

I am learning about reflection in Java. By accident, I discovered the following, for me unexpected behavior.

Both test as written below succeed.

    class NewInstanceUsingReflection {

        @Test
        void testClassNewInstance() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
            final var input = "A string";
            final var theClass = input.getClass();
            final var constructor = theClass.getConstructor();
            final String newString = constructor.newInstance();

            assertEquals("", newString);
        }

        @Test
        void testClassNewInstanceWithVarOnly() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
            final var input = "A string";
            final var theClass = input.getClass();
            final var constructor = theClass.getConstructor();
            final var newString = constructor.newInstance();

            assertEquals("A string", newString);
        }

    }

The only difference apart from the assertion is that the newString variable type is explicit in the first test and declared as var in the second test.

I'm using java 17 and the junit5 test framework.

Why is the value of newString an empty string in the first test and the input string value in the second test?

Does it have something todo with the string-pool?

Or is something else going on?


Thanks in advance for the explanation!





get return type of generic method

I know about type-erasure, I know it shouldn't be possible and every stackoverflow-post answers with workarounds but I'm willing to use the hackiest, bytecode-manipulating, reflective functionality to make this work:

static <T> Class<T> getGenericType() {...}




mercredi 7 septembre 2022

When can AssemblyName.Version be null?

The docs show that AssemblyName.Version is nullable. So this could be null:

Assembly.GetExecutingAssembly().GetName().Version

Under what conditions could Version be null?





Issue while updating java project from JDK11 to JDK17

I have a java project using jdk11. I need to migrate the project to java 17 but integration tests have started failing. As soon as I upgraded to JDK17 I started getting below error:

java.lang.reflect.InaccessibleObjectException: Unable to make private sun.reflect.generics.repository.FieldRepository java.lang.reflect.Field.getGenericInfo() accessible: module java.base does not "opens java.lang.reflect" to unnamed module @5702b3b1

I was also getting error for java.util but that is fixed using below command line code.

I have tried adding the command line options as below but the tests are still failing

                <argLine>
                    --illegal-access=permit
                    --add-opens java.base/java.lang=ALL-UNNAMED
                    --add-opens java.base/sun.reflect=ALL-UNNAMED
                    --add-opens java.base/java.util=ALL-UNNAMED
                </argLine>

Any help is appreciated.





lundi 5 septembre 2022

CS8600 Converting null literal or possible null value to non-nullable type when using Activator.CreateInstance

I am trying to use reflection to get classes based on the interface name. But when I try to create an instance of the class based on the type using CreateInstance() I am receiving the error CS8600 Converting null literal or possible null value to non-nullable type.

    public RequestEmailNotifyBehaviour()
    {
        IEnumerable<Type> emailNotifiers = GetTypesWithInterface(Assembly.GetExecutingAssembly());
        List<IEmailNotification<IRequest>> listOfNotifiers = new List<IEmailNotification<IRequest>>();
        foreach (Type type in emailNotifiers)
        {
            listOfNotifiers.Add((IEmailNotification<IRequest>)Activator.CreateInstance(type));         
        }
    }

    private IEnumerable<Type> GetTypesWithInterface(Assembly asm)
    {
        var it = typeof(IEmailNotification<TRequest>);
        return asm.GetLoadableTypes()
            .Where(it.IsAssignableFrom)
            .Where(t => !(t.Equals(it)))
            .ToList();
    }



public static class TypeLoaderExtensions
{
    public static IEnumerable<Type> GetLoadableTypes(this Assembly assembly)
    {
        if (assembly == null) throw new ArgumentNullException("assembly");
        try
        {
            return assembly.GetTypes();
        }
        catch (ReflectionTypeLoadException e)
        {
            return (IEnumerable < Type > ) e.Types.Where(t => t != null);
        }
    }
}




dimanche 4 septembre 2022

How to fix error with java.reflect and bean creation in spring boot java

I'll first give some context before showing the error. I am developing a Rest API with Spring Boot (spring boot 2.6.6 and Java 17), in which I started getting the following error when trying to run (with IntelliJ). The complete error queue.

Error creating bean with name 'deleteAccountResource' defined in file [C:\ruta...\resources\DeleteAccountResource.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'springCommandBus' defined in file [C:\path...\SpringCommandBus.class]: Bean instantiation via constructor failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [dev.facturador.global.infrastructure.adapters.SpringCommandBus]: Constructor threw exception; nested exception is java.lang.ClassCastException: class java.lang.Class cannot be cast to class java.lang.reflect.ParameterizedType (java.lang.Class and java.lang.reflect.ParameterizedType are in module java.base of loader 'bootstrap')

what I want to fix:
class java.lang.Class cannot be cast to class java.lang.reflect.ParameterizedType (java.lang.Class and java.lang.reflect.ParameterizedType are in module java.base of loader 'bootstrap')

I understand that the problem could be in the "SpringCommandBuss" class or in the "DeleteAccountResource" class. First I go with "SpringCommandBuss" this is a class that serves as a service for my architecture to work, it is in charge of choosing the commandHandler that is going to be executed according to the command that you pass to it. On the other hand "DeleteAccountResource", this class is an endpoint (which does literally what the name of the class says).

Now I show the components that are part of the implementation of a command (they are 3 Command, CommandHandler and CommandBuss).

//The command is in charge of transporting the data as a POJO (this is an abstract implementation)
public class Command {
}

//The handler receives the command without knowing what it is and executes the action
@FunctionalInterface
public interface CommandHandler<T extends Command> {
    void handle(T command) throws Exception;
}

Now the SpringCommandBuss class

@Service
@Primary
public class SpringCommandBus implements CommandBus {
    private final Map<Class, CommandHandler> handlers;

    /**It takes care of finding all possible implementations of the command handler.*/
    public SpringCommandBus(List<CommandHandler> commandHandlerImplementations) {
        this.handlers = new HashMap<>();
        commandHandlerImplementations.forEach(commandHandler -> {
            Class<?> commandClass = getCommandClass(commandHandler);
            handlers.put(commandClass, commandHandler);
        });
    }
   /**Check if there is a command handler for the command 
    *within the implementations it found, and run the command handler if found
    */
    @Override
    public void handle(Command command) throws Exception {
        //Si no existe un Handler con este comando da error
        if (!handlers.containsKey(command.getClass())) {
            throw new Exception(String.format("No handler for %s", command.getClass().getName()));
        }
        handlers.get(command.getClass()).handle(command);
    }

    /**Find the implementation class using the java.reflection library*/
    public Class<?> getCommandClass(CommandHandler handler) {
        Type commandInterface = ((ParameterizedType) handler.getClass()
                .getGenericInterfaces()[0]).getActualTypeArguments()[0];
        return getClass(commandInterface.getTypeName());
    }

    /**Once it retrieves the controller's type name, it retrieves the controller's class*/
    public Class<?> getClass(String name) {
        try {
            return Class.forName(name);
        } catch (Exception ex) {
            return null;
        }
    }
}

On the DeleteAccountResource endpoint the commandBus is called like this:

@RestController
@RequestMapping(path = "/api/accounts")
public class DeleteAccountResource {
    private final CommandBus commandBus;

    public DeleteAccountResource(CommandBus commandBus) {
        this.commandBus = commandBus;
    }

    /**
     * @param username Username of the account you want to delete
     * @return RespomseEmtity void with code 204
     */
    @PreAuthorize("isAuthenticated()")
    @DeleteMapping("/{username}")
    public HttpEntity<Void> deleteAccount(@PathVariable @NotEmpty String username) throws Exception {

        var command = AccountDeleteCommand.Builder.getInstance()
                .username(username).build();

        commandBus.handle(command);
        return ResponseEntity.noContent().build();
    }
}

To provide more information, I also add the command handler implementation in this case. What is executed, after passing the command to the bus is this

@AllArgsConstructor
@Service
@Transactional
public class AccountDeleteCommandHandler implements CommandHandler<AccountDeleteCommand> {
    private final ChecksAccountService checkUseCase;
    private final AccountRepository repository;

    /**
     * Handle deletion of a user account
     *
     * @param command Command contains the data to delete a user account
     * @throws Exception
     */
    @Override
    public void handle(AccountDeleteCommand command) throws Exception {
        //Check that this account exists before deleting
        if (!checkUseCase.checkAccountExistsByUsername(command.getUsername())) {
            throw new ResourceNotFound("No existe una cuenta con este username");
        }

        repository.deleteByOwnerUserUsername(command.getUsername());
    }
}

As another extra fact, the command structure is part of my way of implementing the CQS (Command Query Separation) pattern. If you can think of a way to fix the bug or improve my implementation (and this improvement fixes the bug), I'd appreciate it. It may be that I am missing something and the error is somewhere else, so add the full error queue.





Hot to lookup properties with annotation in subclasses of abstract class?

I have an abstract class with 2 subclasses. I have an annotation on some of the subclasses fields.

I want to create a function which can take the abstract class as argument, iterate over all the fields of the subclasses and replace every field with the annontation with something else (empty string in the below example).

For example:

@Target(AnnotationTarget.FIELD)
@Retention(AnnotationRetention.RUNTIME)
annotation class PersonalData

abstract class SomeAbstractClass(open val name: String)

class Foo(override val name: String, @PersonalData val dateOfBirth: String): SomeAbstractClass(name)

class Bar(override val name: String, val notPersonal: String): SomeAbstractClass(name)

fun getObjWithoutPersonalData(abstractClass: SomeAbstractClass) : SomeAbstractClass {
   // todo - iterate over all fields and replace every field the has @PersonalData annotation with empty string. return the updated object
}

I know it should be done using reflection I just wasn't able to understand exactly how. Would appreciate any help :)





jeudi 1 septembre 2022

How to inspect return type of Callable

Let's say I have something like the following:

import inspect
from collections.abc import Callable  # Using Python 3.10+
from typing import get_type_hints

def foo(arg: Callable[..., int]) -> None:
    pass

type_hints = get_type_hints(foo)["arg"]
annotation = inspect.signature(foo).parameters["arg"].annotation
# How can one get the return type `int` from either of these?

I can figure out how to get to the Callable type hint. From there, how can one inspect the return type of the Callable?





C# Reflection typeof(T).GetProperty fails [closed]

I am following this book, "ASP.Net Core 6 and Angular".

The author has a IsValidProperty() method in a C# class called ApiResult.cs. This is a generic class so we can use the ApiResult class with both types of data in the application so far: City, and Country.

This is the method code:

public static bool IsValidProperty(
        string PropertyName,
        bool throwExceptionIfNotFound = true)
    {
        var prop = typeof(T).GetProperty(
            PropertyName,
            BindingFlags.IgnoreCase |
            BindingFlags.Public |
            BindingFlags.Instance);
        if (prop == null && throwExceptionIfNotFound)
            throw new NotSupportedException(
                String.Format(
                    $"ERROR: Property '{PropertyName}' does not exist.")
                );
        return prop != null;
    }

When I navigate to the Countries Edit page, type T is Country.

This is the Country Entity Framework class:

[Table("Countries")]
[Index(nameof(Name))]
[Index(nameof(IS02))]
[Index(nameof(IS03))]
public class Country
{
    
    [Key]
    [Required]
    public int Id { get; set; }
    
    public string Name { get; set; } = null!;

    [JsonPropertyName("iso2")]
    public string IS02 { get; set; } = null!;

    [JsonPropertyName("iso3")]
    public string IS03 { get; set; } = null!;
    
    public ICollection<City>? Cities { get; set; } = null!;

When the PropertyName passed to IsValidProperty() is Name, it seems to pass. But PropertyName for iso2, and iso3 are returning null and so the exception

$"ERROR: Property '{PropertyName}' does not exist.")

is thrown.

I don't know why this happens. BindingFlags.IgnoreCase is on and anyway Name passes when it is passed in as name.

Could the

[JsonPropertyName("iso2")]

attributes in the Entity class have anything to do with it?

He has those on there to match the Angular interface properties for country.

This is the form group in the Angular template to edit countries:

<form [formGroup]="form" (ngSubmit)="onSubmit()">

<!-- Name -->
<mat-form-field>
  <mat-label>Name:</mat-label>
  <input matInput formControlName="name" required
         placeholder="Type a name" />
  <mat-error *ngIf="this.form.controls['name'].errors?.['required']">
    Name is required
  </mat-error>
  <mat-error *ngIf="this.form.controls['name'].errors?.['isDupField']">
    Name already exists: please choose another.
  </mat-error>
</mat-form-field>

<!-- ISO2 -->
<mat-form-field>
  <mat-label>
    ISO 3166-1 ALPHA-2 Country code (2 letters)
  </mat-label>
  <input matInput formControlName="iso2" required
         placeholder="Insert the ISO2 Country code" />
  <mat-error *ngIf="this.form.controls['iso2'].errors?.['required']">
    ISO 3166-1 ALPHA-2 Country code is required
  </mat-error>
  <mat-error *ngIf="this.form.controls['iso2'].errors?.['pattern']">
    ISO 3166-1 ALPHA-2 Country code requirs 2 letters.
  </mat-error>
  <mat-error *ngIf="this.form.controls['iso2'].errors?.['isDupField']">
    This code already exists: please choose another.
  </mat-error>
</mat-form-field>
.
.
.

Then the TypeScript in the component sets up the form and the validators like this:

ngOnInit(): void {
this.form = this.fb.group({
  name: ['',
    Validators.required,
    this.isDupeField("name")
  ],
  iso2: ['',
    [
      Validators.required,
      Validators.pattern(/^[a-zA-Z]{2}$/)
    ],
    this.isDupeField("iso2")
  ],
  iso3: ['',
    [
      Validators.required,
      Validators.pattern(/^[a-zA-Z]{3}$/)
    ],
    this.isDupeField("iso2")
  ]
});

isDupeField is in the Countries API controller and looks like this:

[HttpPost]
    [Route("IsDupeField")]
    public bool IsDupeField(
        int countryId,
        string fieldName,
        string fieldValue)
    {
        return (ApiResult<Country>.IsValidProperty(fieldName, true))
            ? _context.Countries.Any(
                string.Format("{0} == @0 && Id != @1", fieldName),
                fieldValue,
                countryId)
            : false;
    }

So this is finally where it gets passed to the public, static, IsValidProperty() method.

Anyway "iso2" coming up from the Angular form should match the json name by case and the actual Entity property name because of the Bindings.IgnorCase.

Has anyone dealt with this before? I'm used to just building the front end in RazorPages so this is a big learning curve for me.