mardi 28 février 2023

How do I remove elements from multiple Lists that are properties of a generic object using reflection?

I have a generic object that could have mulitple Lists as properties.

How do I remove elements from those lists generically using reflection?

Let's say I have objects that are like below

public class ObjectA
{
    public List<long> listA
    public List<string> listB
}

public class ObjectB
{
    public List<int> listC
    public List<decimal> listD
}

How would I go about adding and removing elements from those lists generically?

Here's what I thought of, but it's wrong:

private bool PropertyIsGenericList(PropertyInfo property)
        {
            return property.PropertyType.IsGenericType && typeof(IList).IsAssignableFrom(property.PropertyType);
        }

private void RemoveElementsFromPropertyThatAreLists(object dto)
        {
            foreach (PropertyInfo property in dto.GetType().GetProperties())
            {
                if (dto != null && property != null && PropertyIsGenericList(property))
                {
                    RemoveElementsFromList(property, globalIndex); // Don't know what to pass to this
                }

            }
        }

protected void RemoveElementsFromList<ListType>(List<ListType>? columns, int? startingIndex = null)
        {
            startingIndex = startingIndex != null ? startingIndex.Value : globalIndex;
            if (columns != null)
            {
                for (int columnIndex = columns.Count - 1; startingIndex <= columnIndex; columnIndex--)
                {
                    columns.RemoveAt(columnIndex);
                }
            }
        }




lundi 27 février 2023

How do I get 'T from seq<'T> from a PropertyInfo array

I'm using reflection to try and create a datatable based on a record type. This works fine for a simple record type, but some of my records have sub records (also fine, just made the function recursive), or lists of sub records which is where I have my problem.

As an example, if i have the following types-

type ExampleSubType =
    {   PropertyA: string
        PropertyB: int }

type ExampleType =
    {   ID: int
        Name: string
        Example1: ExampleSubType list }

I'd like to create a data table with the following columns/types in this order-

ID: int
Name: string
PropertyA: string
PropertyB: int

I can already do this if I don't have a seq/arr/list anywhere in the types, but the ExampleSubType list part is throwing me off.

Here's the code I've got so far-


    let rec private createDataTableColumns record (propertyArr: PropertyInfo []) (dataTable: DataTable)  =
        propertyArr
        |> Seq.iteri(fun i property -> 
            let propType = property.GetType()
            let propValue = propertyArr.[i].GetValue(record)

            match FSharpType.IsRecord(propType), propValue with 
            | true, _ ->
                let subRecordType = propValue.GetType()
                let subPropertyArr = FSharpType.GetRecordFields (subRecordType)
                createDataTableColumns propValue subPropertyArr dataTable

            | false, :? seq<'T> as (_,test) -> 
                let subRecordType = test.GetType()
                let subPropertyArr = FSharpType.GetRecordFields (subRecordType)
                createDataTableColumns propValue subPropertyArr dataTable

            | _, _ ->
                dataTable.Columns.Add(property.Name, property.PropertyType) |> ignore
            )

The second match case is the issue. I can get it to match on that correctly but I'd like subRecordType to be typeof<'T>.

As it currently is, test.GetType() will return seq<'T>, not 'T and I don't know how to extract it from there.

I've also tried let subRecordType = typeof<'T>, which works elsewhere in my code, but here it will just return System.Object, not whatever type 'T is and i'm not sure why.





Using KProperty with List of objects

We're using Spring Data MongoDB with Kotlin. Kotlin comes with some nice typesafe Criteria Extensions (org.springframework.data.mongodb.core.query.TypedCriteriaExtensions).

given:

data class Foo(
  val id: String, 
  val oneBar: Bar, 
  val bars: List<Bar>)

data class Bar(val thingy: String)

You can use it to build Criteria in a typesafe manner, such as:

criterion = criterion + (Foo::id isEqualTo "id")

If you have a nested object Bar, you can use

criterion = criterion + (Foo::oneBar / Bar::thingy isEqualTo "thingy")

How do you use KProperty when you have an object Foo with a list of Bars and you want to write a Criteria based on a field of Bar

What I want to do is to filter on a property of Bar.

This doesn't work, but I want to do something like this:

criterion = criterion + (Foo::bars / <thing with list> / Bar::thingy isEqualTo "thingy")




dimanche 26 février 2023

Generic command-line argument parser with template, need implementation suggestion

I want to implement a C++ command line generic argument parser (also for fun). Existing popular argument parsers lack some functionalities.

  • gflags: Does not support vector very well.
  • getopt: C based, this is for without type.

I want a generic argument parser that can process arbitrary types, something like this:

class YourArgument {
   vector<int> your_ints;
   string my_str;
   bool help;
};
YourArgument your_arg; 
Argparse(your_arg, argv, argc); // A template

This Argparse can process something like "./run --help --my_str string --your_ints 1 2 3 run.txt".

I find something like C++17 structure binding can enable such implementation. If we are able to add some getters for a class, then we can implement it as follows.

class YourArgument {
   vector<int> your_ints;
   string my_str;
   bool help;
   auto& get(integral_constant<int, 0>) { return your_ints; }
   auto& get(integral_constant<int, 1>) { return my_str; }
   auto& get(integral_constant<int, 2>) { return help; }
   const char* getstr(int i) {
       if (i == 0) return "your_ints";
       if (i == 1) return "my_str";
       if (i == 2) return "help";
   }
};

template <typename T>
void Argparse_impl(T& your_arg, const char **argv, int &argc, int &c) {
    // Common recursive implementation
    // Skipped here
    Argparse_impl<i+1>(your_arg, argv, argc, c);
}

template <typename T>
void Argparse(T& your_arg, const char **argv, int &argc) {
    int c = 0;
    while (c < argc) Argparse_impl<0>(your_arg, argv, argc, c);
}

The parser implementation itself is just a normal recursive tricks, which is not the part that I need suggestion. My question is that is there any way to generate the boilerplate with macro?

I have tried this implementation, the code roughly looks like this (not the exact code I used). However, it drastically lengthen my compile performance. I have lots of such classes to compile, and the structs are very long.

#define MY_MACRO(...)\
    auto& get_tuple() { return forward_as_tuple(__VA_ARGS_); }\
    template<unsigned i> auto& get() { return get<i>(get_tuple()); }\
    const char* getstr() { static string strs = string(##__VA_ARGS_).split(); return strs[i]; }\




samedi 25 février 2023

Google Guava getTopLevelClassesRecursive not finding classes when running, only during test

I am using OpenJDK 17 and Guava 31.1-Jre. I am also using Spring Boot.

I have the line:

ImmutableSet<ClassPath.ClassInfo> classSet = ClassPath.from(ClassLoader.getSystemClassLoader())
                    .getTopLevelClassesRecursive(config.getFunctionPackage());

Whenever i run "mvn test", it finds the appropriate classes. But when i run it using "java -jar ...", it does not find a any classes. And i verified that "config.getFunctionPackage()" returns the same value both times.

Is a different class loader being used, or is something else going on?

thank you.





mercredi 22 février 2023

Call a method on any field of a specific GENERIC type c#

I have the exact same problem as the OP of this thread, except the type I am trying to filter is a generic type and I have no beforehand information of the used type.

Let say the type is: MyGenericType<T>. what I would like to do is:

var fields = this.GetType().GetFields(BindingFlags.NonPublic | 
                            BindingFlags.Instance).Where(x=>x.FieldType == typeof(MyGenericType<>));

However this will not work as at runtime a new type, that contains the information about the generic type, is generated.

Is there a way to circumvent this problem ?





mardi 21 février 2023

Retrieving the reference of a class instance directly from one of its member methods that's passed as a parametre in a different class' method in C#

I'm developing a project in Unity. I think code sample will explain itself.

NOTES:

  1. Module constructor shall not need any other parameter, such as "this" referring to a Container instance

  2. Module constructor only parametre must stay as IEnumerator, not Func<> etc

  3. Coroutine passed as the parameter, will not be invoked directly (for ex. StartCoroutine(...) )

  4. Code logic that's inside the Module CTOR shall not be moved into a seperate method (neither public nor extension method).

     class Module
     {
             // CTOR
             public Module(IEnumerator _someCoroutine)
             {
             // This is where I need to get the reference to the
             // instance of a Container class (not "typeof(Container)")
             // which _someCoroutine method's reference is held, 
             // directly from _someCoroutine parameter
             }
    
     }
    
     class Container : MonoBehaviour
     {
             Module module = new Module(SomeCoroutine());
    
             IEnumerator SomeCoroutine()
             {...}
     }
    




lundi 20 février 2023

Doctrine : find informations (with PHP Reflection) about a transition table generated by a ManyToMany relationship

On symfony 6 and for some reasons, I need to get the informations about all tables and fields of my database (fields names of each table, which are primary key, their type (int, text, ...) ). I can handle most of table with PHP Reflection. But in the case of transition table, I must create manually the transition table manually with the make:entity command.

However, I have several ManyToMany relationship in my database. Its boring to create foreach relationship a transition table. My questions :

  • Is there a way to force symfony to create the 'transition' entities php files and repositories when I want use a ManyToMany relationship ? (I don't find the good option with the command make:entity but I maybe miss something)
  • If no, is there another way for retrieve informations about fields (fields names, know which fields are primary key, ...) from PHP Reflection without create manually all transition tables ?

Thanks for any help :)





Get annotation java annotation from parent interface in Kotlin

I declare a java annotation.

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

I use this java annotation in kotlin interface

Problem.kt

interface IMyClass {
        @JavaAnnotation
        fun method() {}
    }

class MyClass : IMyClass{
    override fun method() {}
}

class Problem {
    @Test
    internal fun shouldFindAnnotationFromParentInterface() {
        val myClass = MyClass()
        Assertions.assertTrue(myClass::class.declaredFunctions.find { it.name == "method" }!!.annotations.isEmpty().not())
    }
}

I see that java annotation uses @Inherited. I want to find the java annotation on the Kotlin MyClass::method. I get an empty array.

Could you help me? Thanks





vendredi 17 février 2023

Dotnet Reflection: Calling Invoke on MethodInfo With 'out' Parameter from F#

I retrieve a TryParse method for a given type like this:

open System.Reflection

let stringParser<'T> =
    typeof<'T>.GetMember("TryParse")
    |> Seq.cast<MethodBase>
    |> Seq.choose (fun m ->
        let parameterTypes =
            m.GetParameters()
            |> Array.map (fun p -> (p.ParameterType, p.Attributes))
        if parameterTypes =
            [| (typeof<string>, ParameterAttributes.None)
            ;  (typeof<'T>.MakeByRefType(), ParameterAttributes.Out) |] then Some m
        else None)
    |> Seq.exactlyOne

The question now is how to provide the second parameter when invoking the method, which contains the parse result as a reference. A mutable variable [1] leads to the 'type instantiation involves a byref type' compilation error, and a ref variable [2] leads to a type mismatch during runtime (given here, e.g., for uint16):

let fromString<'T> (s: string) =
    // [1]
    //let mutable parseResult = Unchecked.defaultof<'T>
    // Using '&parseResult' gives:
    // A type instantiation involves a byref type. This is not permitted by the rules of Common IL
    
    // [2]
    //let parseResult = ref (Unchecked.defaultof<'T>)
    // Using 'parseResult' produces a runtime exception:
    // System.ArgumentException: Object of type 'Microsoft.FSharp.Core.FSharpRef`1[System.UInt16]' cannot be converted to type 'System.UInt16&'.

    // How to declare parseResult to retrieve the method result?
    let potentialResult = stringParser<'T>.Invoke(null, [|s; parseResult|])
    match potentialResult with
    | :? bool as boolResult ->
        if boolResult then Some (parseResult)
        else None
    | _ -> None




mardi 14 février 2023

trying to set a member ArrayList using reflection

I am trying to modify an object with an Arraylist of objects using reflection.

I understand that I cannot get the type of the objects in the ArrayList, but I (think) I am using an annotation to handle that part. I am setting the field accessibility.

I am declaring the list of stuff in the class using annotations.

@TableAnnotation(type = PhoneNumber.class)
protected List<PhoneNumber> phoneNumbers = new ArrayList<>();
@TableAnnotation(type = Address.class)
private List<Address> addresses= new ArrayList<>();
private List<Role> roles= new ArrayList<>();

... Later in the same class I try to set them:

public void setMemberTable(List<Table> tables, String memberName) throws IllegalAccessException {
    Class t = getClass();
    for (Field field : getClass().getDeclaredFields()) {
        if (field.getName() == memberName) {
            field.setAccessible(true);
            List array = (List)field.get(this.getClass()); <<<=========== Here is where it is throwing
            ArrayList arrayList= (ArrayList)field.get(this.getClass());
            //array.add(tables.get(0));
            System.out.println();
        }
    }
}

Here is the Annotation that seems to be working:

package com.test.database.helpers;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Documented
@Target(ElementType.FIELD)
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface TableAnnotation {
    Class< ?> type();
    boolean allowNull() default false;
}

This throws:

java.lang.IllegalArgumentException: Can not get java.util.List field com.test.database.entities.Person.phoneNumbers on java.lang.Class

I tried making the member variable public, but that had no affect. I need help to be able to set the member variables in setMemberTable().





Use non-generic method of Hashset through reflection

I want to be able to call the Hashset.ExceptWith() method using reflection but I can't make it happen.

I can't create a generic method. It seems it isn't a generic method. I also can't seem to call the method itself using invoke.

Does anyone know how to do this?

var newSet = pi.GetValue(newItem);
var existingSet = pi.GetValue(existingItem);
MethodInfo methodExcept = typeof(HashSet<>).GetMethod("ExceptWith");

//The next line throws: Void ExceptWith(System.Collections.Generic.IEnumerable`1[T]) is not a GenericMethodDefinition. 
//MakeGenericMethod may only be called on a method for which MethodBase.IsGenericMethodDefinition is true.'
MethodInfo genericExcept = methodExcept.MakeGenericMethod(pi.GetType().GetGenericTypeDefinition().UnderlyingSystemType);

//The next line throws 'Late bound operations cannot be performed on types or methods for which ContainsGenericParameters is true.'
methodIntersect.Invoke(existingSet, new[] { newSet });
//The next line is not possible since instantiation of the variable doesn't work
genericIntersect.Invoke(existingSet, new[] { newSet });




lundi 13 février 2023

How to iterate over all classes when code is executing inside an Uber JAR?

I need to find all classes that implement an interface at runtime. I was using this code to iterate over all classes:

ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
System.out.println("loading resources");
Enumeration<URL> resources = classLoader.getResources("");
Set<Class<?>> classes = new HashSet<>();
int count = 0;
while (resources.hasMoreElements()) {
count++;
...
}
System.out.printf("found %d resources\n", count);

and it worked when my application was not packaged as an Uber JAR. But when I package my application as an Uber JAR and try to run it like:

java -jar target/app.jar

There are no resources returned.

loading resources
found 0 resources

How can I fix this?

My overall problem is this: Given this pattern of execution:

java -jar app.jar

Give me all classes that implement interface X.Y.Z.





In Scala 3: Why runtime pattern matching can't work reliably on duck type using JVM reflection?

Considering the following example:

object MatchDuckType {

  trait Sup
  class Sub1() extends Sup {
    def v1: String = "a"
  }

  def example(v: Any) = {

    v match {

      case _: Sup { def v1: String } => println(1)
      case _ => println(2)
    }
  }

  def main(args: Array[String]): Unit = {
    example(Sub1())
    example(1)
  }
}

The compiler gave the following error:

MatchDuckType.scala:16:12: the type test for xxx.MatchDuckType.Sup{v1: String} cannot be checked at runtime

This statement is clearly wrong, as Sup { def v1: String } can be easily checked by Java runtime reflection (by first getting the class of the term, then getting its method signatures). Why does the warning still exist? Is it a bug in compiler?





In Java, what's the proper way of using an optional dependency without ClassNotFoundError?

I would like my projekt to switch at startup between backend libraries, with option to not shade both of them into resulting Jar, while having full compile-them visibility of both. I would also like to avoid loading backends using Class.forName.

Can you help me understand if any of these will lead to a ClassNotFoundError for unshaded library and which will not?

  1. Leaving an unused class field, of type from this library
  2. Leaving an unused method, with arguments or return from this library
  3. Referencing this library in a backend class that will only be loaded conditionally like backend = isNewBackend ? new FancyBackend() : new OldBackend()

If all of these result in error, is there an easier strategy for this?





F# - how can I convert an F# function into a System.Delegate using reflection?

Say I have a basic function, like:

let double x = x * 2

Since I know the types, I can convert it into a Func<_,_> explicitly, which can then be used as a Delegate:

let doubleFuncExplicit = Func<int, int>(double)

However, when I attempt to do this by using Activator.CreateInstance() instead of the constructor, like so:

// derive the type for Func<int, int>
let genericType = typeof<Func<obj, obj>>.GetGenericTypeDefinition()
let specificTypeDef = genericType.MakeGenericType([| typeof<int>; typeof<int> |])
// ...and instantiate it
let doubleFuncReflected =  Activator.CreateInstance(specificTypeDef, [| double |])

...I get the following exception on the last line:

System.MissingMethodException: Constructor on type 'System.Func`2[[System.Int32, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Int32, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]' not found.
   at System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture)
   at System.Activator.CreateInstance(Type type, Object[] args)
   at <StartupCode$FSI_0007>.$FSI_0007.main@() in C:\dev\2023\MoneyClock2023\src\MoneyClock\MoneyClock.Tests\Scratch.fsx:line 16
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
   at System.Reflection.MethodInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)

Am I on the right track? How can I convert an F# function into a delegate?





samedi 11 février 2023

Iterate over Java class hierarchy using functional programming

Considering this piece of Kotlin code, that collects all declared fields in superclass hierarchy, is there way to write it using functional programming?

var scanClass: Class<*>? = someClass

val fields = mutableListOf<Field>()
while (scanClass != null) {
    fields += scanClass.declaredFields
    scanClass = scanClass.superclass
}




Introspecting netstandard.dll

I'm trying to introspect types and other info within netstandard.dll

I already had downloaded the nuget package NETStandard.Library 2.0.3 it made a folder in the c drive and one of them contains netstandard.dll which is around 1.3MB and has 100 other odd dlls like mscorlib, System, System.Runtime etc.

I inspected netstandard.dll in Ildasm and found that it had a few namespaces and hundreds of types.

However when I try to load the netstandard.dll using Assembly.LoadFile it tends to load it from another location probably the GAC. And that assembly returns 0 types when calling Assembly.GetTypes

I read elsewhere on this forum that netstandard.dll is a reference type and should never be loaded. How then would be the correct way to get member information from that assembly, I also tried Assembly.ReflectionOnlyLoadFrom however it gave me a error that System.Object could not be found.

The goal is to get api information and documentation of netstandard from the assembly as well as its paired xml file.





vendredi 10 février 2023

How to access internal field 'NewLineConst' of System.Environment class (System.Private.CoreLib.dll) in .NET 7

I want to access the following field using reflection:

Class is part of:

System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e

enter image description here

I tried the following (amongst others), but the result is null:

 var fld = typeof(Environment).GetField("NewLineConst", BindingFlags.NonPublic | BindingFlags.Instance); // => null

How can I access this internal const field which is part of the partial Enviroment class?





jeudi 9 février 2023

Kotlin - reflection and type safety

I am writing a small library for programatically generating SQL queries. The goal is that the API of this library can be used like that:

myQuery.where(
    MyClass::id equal "foo",
    MyClass::age notEqual 55 
).findAll()

The signatures of both the where function, and the infix operators is under my control. Here are the relevant definitions that I have at the moment:

interface KpaFilter<BASE, FIELD>

infix fun <BASE: Any, FIELD: Any> KProperty1<BASE, FIELD>.equal(value: FIELD): KpaFilter<BASE, FIELD> { ... }

fun <BASE: Any> where(vararg filters: KpaFilter<BASE, *>?): KpaQuery<BASE>

Still, I cannot find a proper way to make this type safe. For example, I would like this to raise a compilation error, but unfortunately, it compiles:

val someFilter = MyClass::id equal 55 // id is a string

Is it possible to somehow modify the signatures of the declarations above and achieve this kind of type safety, without making the API more cumbersome than its current form?





mardi 7 février 2023

In spring, when the entity class is reflected into a bean, how to specify the calling order of the setter method?

I have encountered a rather difficult problem, Suppose there is an entity class, the code is as follows:

class Human {
    private Integer age; // age of the human
    private String describe; // description of the human based on their age

    /**
     * Setter method for the age of the human
     *
     * @param age the age of the human
     */
    public void setAge(Integer age) {
        this.age = age;
    }

    /**
     * Setter method for the description of the human
     * The description is determined based on their age
     *
     * @param gender the gender of the human
     */
    public void setDescribe(String gender) {
        String describe = "";
        if (this.age < 30) {
            describe = "young " + gender;
        } else if ( this.age <= 55 && this.age >= 30) {
            describe = "middle-aged " + gender;
        } else {
            describe = "old " + gender;
        }
        this.describe = describe;
    }
}

As shown in the code (just an example, the attribute or class may be arbitrary), if I use spring and use spring to generate beans, I must ensure that method setAge is called first. How can I ensure this?

If there is a table in the database that stores age and gender, how can I ensure that setAge is called first when I use jpa, mybatis or other libraries to reflect entities?

I tried to search, but I didn't find the answer. The following are the keywords I searched and some related answers, but it doesn't seem to solve my doubts:

Spring init bean, how to ensure that a setter method is executed first

Spring reflection entity class, how to ensure that a setter method is executed first

spring call setter after other setter

When jpa reflects entity classes setter methods call order

Spring setter method order

Spring - why initialization is called after setter method





Cannot Compile C# Script via CodeAnalysis: Which assembly am I missing?

The following program attempts to compile and execute a script of C#. However, I keep getting the output:

CS0103: The name 'Queryable' does not exist in the current context

CS1061: 'int[]' does not contain a definition for 'AsQueryable' and no accessible extension method 'AsQueryable' accepting a first argument of type 'int[]' could be found (are you missing a using directive or an assembly reference?)

Which assembly am I missing in refPaths? I assumed [System.Linq] would be all I need, which I then added through [typeof(Enumerable).GetTypeInfo().Assembly.Location].

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Loader;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Emit;

namespace CompileScript
{
    class Program
    {
        static async Task Main(string[] args)
        {
            string script = @"using System;
                              using System.Linq;

                              namespace Test { class Program {
                              public static void Main() {
                                   Console.WriteLine(""Testing a script..."");
                                   int[] arr = new int[] { 1, 2, 3};
                                   double avg = Queryable.Average(arr.AsQueryable());
                                   Console.WriteLine(""Average = "" + avg);}}}";

             var refPaths = new[] {
                   typeof(object).GetTypeInfo().Assembly.Location,
                   typeof(Console).GetTypeInfo().Assembly.Location,
                   typeof(Enumerable).GetTypeInfo().Assembly.Location,
                   Path.Combine(Path.GetDirectoryName
                   (typeof(System.Runtime.GCSettings).
                   GetTypeInfo().Assembly.Location), "System.Runtime.dll"),
             };
             SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(script);

             string assemblyName = Path.GetRandomFileName();

             MetadataReference[] references = refPaths.Select(r => MetadataReference.
             CreateFromFile(r)).ToArray();

             CSharpCompilation compilation = CSharpCompilation.Create(
                  assemblyName,
                  syntaxTrees: new[] { syntaxTree },
                  references: references,
                  options: new CSharpCompilationOptions
                  (OutputKind.DynamicallyLinkedLibrary));

            using var ms = new MemoryStream();
            EmitResult result = compilation.Emit(ms);

            if (!result.Success)
            {
                   IEnumerable<Diagnostic> failures =
                        result.Diagnostics.Where(diagnostic =>
                        diagnostic.IsWarningAsError ||
                        diagnostic.Severity == DiagnosticSeverity.Error);

                   foreach (Diagnostic diagnostic in failures)
                   {
                      Console.WriteLine("\t{0}: {1}", diagnostic.Id,
                                                      diagnostic.GetMessage());
                   }
             }
             else
             {
                  ms.Seek(0, SeekOrigin.Begin);

                  Assembly assembly = AssemblyLoadContext.Default.LoadFromStream(ms);
                  var type = assembly.GetType("Test.Program");
                  var instance = assembly.CreateInstance("Test.Program");
                  MethodInfo? methodInfo = type.GetMethod("Main");
                  methodInfo.Invoke(instance, null);
              }
          }
       }
   }




Why does get(view) for a ListenerInfo return null?

I am currently trying to get the OnTouchListener for a View via reflection to exchange the Listener with my custom OnTouchListener which I want to use to track touch events. My method works perfectly fine for the OnClickListener, but somehow doesn't work for the OnTouchListener.

My function looks like this:

private fun getOnTouchListener(view: View): View.OnTouchListener? {
        var retrievedListener: View.OnTouchListener? = null
        try {
            val listenerField = Class.forName("android.view.View").getDeclaredField("mListenerInfo")
            val listenerInfo: Any?
            listenerField.isAccessible = true
            listenerInfo = listenerField.get(view)
            val touchListenerField = Class.forName("android.view.View\$ListenerInfo").getDeclaredField("mOnTouchListener")
            listenerInfo?.let {
                retrievedListener = touchListenerField.get(listenerInfo) as View.OnTouchListener
            }
        } catch (ex: NoSuchFieldException) {
        } catch (ex: IllegalAccessException) {
        } catch (ex: ClassNotFoundException) {
        }
        return retrievedListener
}
listenerField.get(view)

returns null. The same approach worked perfectly fine for views with OnClickListeners.

I have seen other answers to similar questions, where this approach worked (Get OnTouchListener object from View by reflection). Yet, it doesn't work for me.

Does someone know how what to do in order to get the listenerInfo?





dimanche 5 février 2023

F# ASP.NET Core Minimal Web API - Why does the generated endpoint ignore parameter names when not supplied a lambda?

I created a .NET core web API from the standard F# template and added these lines:

let add x y = x + y

app.MapGet("addUgly", new Func<_,_,_>(add))

app.MapGet("addPretty", new Func<_,_,_>(fun x y -> add x y))

When I access the addPretty endpoint, I can supply parameters with the desired names: https://localhost:7129/addPretty?x=1&y=2

However, in order to access the addUgly endpoint, I must supply these parameters: https://localhost:7129/addUgly?delegateArg0=3&delegateArg1=4

Is there a way to have the generated endpoint use the desired parameter names without using a lambda? (or other constructs that involve unnecessary boilerplate, like creating a controller)?

I checked whether add and (fun x y -> add x y) had differently structured type definitions, but they both have Invoke methods with parameters named x and y, so I don't know why those names get lost in one case but not the other.





vendredi 3 février 2023

Return Row with schema defined at runtime in Spark UDF

I've dulled my sword on this one, some help would be greatly appreciated!

Background

I am building an ETL pipeline that takes GNMI Protobuf update messages off of a Kafka queue and eventually breaks them out into a bunch of delta tables based on the prefix and parameters of the paths to values (e.g. DataBricks runtime).

Without going into the gory details, each prefix corresponds roughly to a schema for a table, with the caveat that the paths can change (usually new subtrees) upstream, so the schema is not fixed. This is similar to a nested JSON structure .

I first break out the updates by prefix, so all of the updates have roughly the same schema. I defined some transformations so that when the schema does not match exactly, I can coerce them into a common schema.

I'm running into trouble when I try to create a struct column with the common schema.

Attempt 1

I first tried just returning an Array[Any] from my udf, and providing a schema in the UDF definition (I know this is deprecated):

  def mapToRow(deserialized: Map[String, ParsedValueV2]): Array[Any] = {
    def getValue(key: String): Any = {
        deserialized.get(key) match {
            case Some(value) => value.asType(columns(key))
            case None => None
        }
    }
    
    columns.keys.toArray.map(getValue).toArray
  }
  
  spark.conf.set("spark.sql.legacy.allowUntypedScalaUDF", "true")
  def mapToStructUdf = F.udf(mapToRow _, account.sparkSchemas(prefix))

This snippet creates an Array object with the typed values that I need. Unfortunately when I try to use the UDF, I get this error:

java.lang.ClassCastException: org.apache.spark.sql.catalyst.expressions.GenericRowWithSchema cannot be cast to $line8760b7c10da04d2489451bb90ca42c6535.$read$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$ParsedValueV2

I'm not sure what's not matching, but I did notice that the type of the values are Java types, not scala, so perhaps that is related?

Attempt 2

Maybe I can use the Typed UDF interface after all? Can I create a case class at runtime for each schema, and then use that as the return value from my udf?

I've tried to get this to work using various stuff I found like this:

import scala.reflect.runtime.universe
import scala.tools.reflect.ToolBox
val tb = universe.runtimeMirror(getClass.getClassLoader).mkToolBox()
val test = tb.eval(tb.parse("object Test; Test"))

but I can't even get an instance of test, and can't figure out how to use it as the return value of a UDF. I presume I need to use a generic type somehow, but my scala-fu is too weak to figure this one out.

Finally, the question

Can some help me figure out which approach to take, and how to proceed with that approach?

Thanks in advance for your help!!!





Is there a generic type that contains any Object class and a List

I'm trying to initialize a class with Reflection and a Map (This due a more complex requirement, I just isolated the example)

public class ParentDto {
    private String field1;
    private BigDecimal field2;
    private List<AClass> listField3;
}

I created a map to set values for the first 2 fields with a generic value Map

public static final Map<String, Object> INITIALIZER = Map.ofEntries(
    Map.entry("field1", "String"),
    Map.entry("field2", new BigDecimal("23.43")

However, if i try to do the same for the list it will fail. It makes sense since Object is not a Base Class for List. My question is: Is there any way I can add

Map.entry("listField3", List.of("e1","e2"))

into my static map? A superclass that have in common both Objects and List





jeudi 2 février 2023

How to upcast `byref<'t>` to `byref

I try to call JsonConverter<'t>.Read using reflection

static member ConvertRead (readInfo: MethodInfo, converter: JsonConverter, reader: byref<Utf8JsonReader>, typeToConvert: Type, options: JsonSerializerOptions) =
    readInfo.Invoke(converter, [| box reader; box typeToConvert; box options |])

and get FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL





Setting a field enum value with reflection

I am looping through a super classes fields and trying to set values but I am not able to do so with non primitive types. Things such as boolean, int, and double all seem to work find but when I try to use an enum object along with the plain .set() method I get a java.lang.IllegalArgumentException saying I can't cast my OffenceType field to null value even though I printed out my value first and it was not null.

       for (Field field : check.getSuperclass().getFields()) { 
               if(field.getType().equals(Integer.class)) { // This works fine
                    boolean accessible = field.isAccessible();
                    field.setAccessible(true);
                    if(field.getName().equals("violations")) field.setInt(field, getIntegerFromConfig(cfg, violationsString));
                    field.setAccessible(accessible);
                }
                else if(field.getType().equals(Check.OffenceType.class)) {
                    OffenceType offence = OffenceType.valueOf(cfg.getString(offenceString));
                    System.out.println("Type:" + offence);
                    boolean accessible = field.isAccessible();
                    field.setAccessible(true);
                    if(field.getName().equals("offence")) {
                        field.set(field, offence);
                    }
                    field.setAccessible(accessible);
                }
       }

The error is coming from the field.set(field, offence); line also the field it is trying to access is labeled as public OffenceType offence;

The following is the stack trace

[13:19:24 WARN]: java.lang.IllegalArgumentException: Can not set me.HowDoISolveThis.check.Check$OffenceType field me.HowDoISolveThis.check.offence to null value
[13:19:24 WARN]:        at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
[13:19:24 WARN]:        at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
[13:19:24 WARN]:        at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:58)
[13:19:24 WARN]:        at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:75)
[13:19:24 WARN]:        at java.lang.reflect.Field.set(Field.java:764)
[13:19:24 WARN]:        at me.HowDoISolveThis.config.Config.updateConfig(Config.java:125)```




EF Core, how can I query my DbContext when I only have a string variable containing a type?

I have two string variables entityName and entityId. I also have a DbContext with many data sets. I need to query the context using the type contained in entityName and I know that its value will match the name of the type of one of those data sets at this point. Here is my current approach (issue at the end):

var type = Type.GetType(entityName);
if (type == null) throw new Exception("Cannot find Type" + entityName);
var entity = await context.Set<type>().FindAsync(entityId);

The issue is that the compiler tells me I cannot use a Type variable type as a Type itself. Which makes sense, but I'm not sure where to go from here. I have also tried context.Set(type) which also give me compiler errors.





mercredi 1 février 2023

Mapping API result to class, should I use reflection and is this a case of DataAdapter design pattern?

It is my first time using an API and I am not entirely sure about the good practices regarding it. I am using a third party API that returns me a class 'A' in C#, that is not quite compatible with my DTO class 'MyA'. I obviously have to map it to my entity, but I don't know what the best way to do it is. I have read of the Data Adapter pattern and from what I understand, it has the purpose to act as a bridge between two incompatible interfaces. Those classes share some properties, but differ in more important ones, so I wonder if this pattern is what I am looking for.

I believe I could create a base class that uses reflection to map the matching properties for the generic case, and build on top of that for the different properties. I have however heard that reflections should be avoided, so another approach would be to manually map even the shared properties. This would probably be easier to do now, but it is not maintainable at all, involves some avoidable logic repetition, and overall contradicts good design practices.

Would my situation be considered a case usage of DataAdapter? From the definitions I read, I think yes, however the posts I found were predominantly about using different data sources (XML,JSON,CSV), not just classes in the same language with some properties that differ?