mercredi 2 mars 2022

Create Collection of type Class

Im trying to write a function that given a class it will build an object of that type (using reflection). Its working so far but im having trouble with Collections as members.

public static <T> T object(Class<T> type) throws NoSuchMethodException, ClassNotFoundException, InvocationTargetException, InstantiationException, IllegalAccessException {

            T object = getNullInstanceOf(type);

            List<Field> fields = Arrays.asList(object.getClass().getDeclaredFields());

            for (Field f : fields) {
                f.setAccessible(true);
                if (Modifier.isFinal(f.getModifiers())) {
                    continue;
                }
                try {
                    Object fieldValue = f.get(object);
                    if (f.getType().equals(CharSequence.class) || f.getType().equals(String.class)) {
                        f.set(object, f.getName());
                    } else if (f.getType().equals(Integer.TYPE)) {
                        f.set(object, 1);
                    } else if (f.getType().equals(Double.TYPE)) {
                        f.set(object, 2.0);
                    } else if (f.getType().equals(Long.TYPE)) {
                        f.set(object, 3L);
                    } else if (isClassCollection(f.getType())) {
                        f.set(object,
                                ((Collection) getNullInstanceOf(f.getType())) // this throws a "No Such Method Exists" Exception
                                    .add(object(f.getGenericType().getClass()))); 
                    } else if (!(f.getType().equals(type))) {
                        f.set(object, object(f.getType()));
                    } else {
                        return null;
                    }
                } catch (Exception e) {
                    System.err.println("Could not access:" + f.getName());
                    continue;
                }
            }
            return object;
        }

        public static boolean isClassCollection(Class<?> c) {
            return Collection.class.isAssignableFrom(c)
                    || Map.class.isAssignableFrom(c);
        }

        private static <T> T getNullInstanceOf(Class<T> type) throws InvocationTargetException, InstantiationException,
                IllegalAccessException, NoSuchMethodException, ClassNotFoundException {
            Class<?> clazz = Class.forName(type.getName());
            Constructor<?> ctor = clazz.getConstructor();
            return (T) ctor.newInstance();
        }
    }

The issue im having is that when I try to create an instance of the collection, whether it be a set, list, or map, those classes are abstract. Is there a way to just pick a random implementation or do I have to hardcode a concrete subclass for every abstract class?





mardi 1 mars 2022

How to check if slice interface elements have the same dynamic type?

I have the following structs and they follow this structure:

A is the interface, and B, C, D are all types with interface A.

I have a slice of variables args all with type with interface A, each of which can be B, C, D type specifically.

I'd like to write a for loop to judge if all variables in the slice fall into the same dynamic type.

I wrote the following code:

var existingTyp A
for i, d := range args {
 switch typ := d.(type) {
   case *B, *C, *D:
    if existingTyp == nil {
        existingTyp = typ
    } else {
        if typ != existingTyp {
            panic("error!")
        }
   }
}

How to revise the code to achieve what I want?





ObjectC-Why can't I get the properties correctly using the class_copyPropertyList function?

  • macOS 11.5.2
  • Xcode 13.2.1
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
#import <iostream>

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Class clazz = NSClassFromString(@"NSString");
        uint32_t count = 0;
        objc_property_t* properties = class_copyPropertyList(clazz, &count);
        for (uint32_t i = 0; i < count; i++){
            const char* name = property_getName(properties[i]);
            std::cout << name << std::endl;
        }
        free(properties);
    }
    return 0;
}

I will take some snippets of the output:

hash
superclass
description
debugDescription
hash
superclass
description
debugDescription
vertexID
sha224
NS_isSourceOver
hash
superclass
description
debugDescription
...

From the output, we can find that attributes such as hash, description, superclass, etc. will appear repeatedly several times, while some attributes (such as UTF8String) do not appear in the result list. How should I get the list of properties correctly? I would appreciate it.





lundi 28 février 2022

Scala reflection: compile akka actor with protobuf

I am trying to compile an Actor with DynamicMessage with Scala Reflection Toolbox

The actor code looks like

import scala.reflect.runtime.universe
import scala.tools.reflect.ToolBox
val toolbox = universe.runtimeMirror(getClass.getClassLoader).mkToolBox()
    val actorCode =
  """
    |import akka.actor._
    |import com.google.protobuf._
    |class SimpleActor extends Actor {
    |override def receive: Receive = {
    | case dynamicMessage: DynamicMessage => println("Dynamic message received!")
    | case _  => println("Whatever!")  // the default, catch-all
    |  }
    |}
    |object SimpleActor {
    |def props() : Props = Props(new SimpleActor())
    |}
    |
    |
    |return SimpleActor.props()
    |""".stripMargin
val tree = toolbox.parse(actorCode)
toolbox.compile(tree)().asInstanceOf[Props]

I get the error

reflective compilation has failed:

illegal cyclic reference involving type T
scala.tools.reflect.ToolBoxError: reflective compilation has failed:

illegal cyclic reference involving type T

If I run the code outside of the Toolbox it compiles and works fine. The error is given from the line

case dynamicMessage: DynamicMessage => println("Dynamic message received!")

Anyone knows the nature of this error and how to fix it?





How can I get a type of collection? [duplicate]

Here is the way how I can get a type:

String.class

How can I get a type of collection:

 List<String>




How to get property value of object which is in object array from another class

I want to get property value of an object which is in object array from another class. I tried to use reflection, but I had to do something wrong...

My code:

  //Map.cs

    //in BoardTiles i keep objects of classes which have property "Name" and I want to get it.

    public class Map
        {
            public int Rows { get; private set; }
            private int Cols { get; set; }
            public Object[,] BoardTiles { get; private set; }
            private Floor Floor { get; set; }
            private PlayerTile PlayerTile { get; set; }
            private Sword OldSword { get; set; }
    
    
    
            public Map()
            {
                this.Rows = 10;
                this.Cols = 40;
                this.BoardTiles = new Object[Rows, Cols];
                this.Floor = new Floor();
                this.PlayerTile = new PlayerTile();
                this.OldSword = new Sword("oldSword", 5);
    
            }
//Sword.cs 
//this is what the sword class looks like, object of this class is stored in BoardTiles 

{
    public class Sword : Tile
    {
        public override string Type { get; set; }
        public string Name { get; set; }
        public int Dmg { get; set; }

        

        public Sword(string name, int dmg)
        {
            this.Type = "sword";
            this.Name = name;
            this.Dmg = dmg; 
        }
    }
}

//Program.cs
 case ConsoleKey.Spacebar:
            Console.Clear();

            map.getItem(playerPositionX, playerPositionY);
/*            map.movefill(playerPositionX, playerPositionY);
*/            map.printBoard();
            Console.Write(map.BoardTiles[playerPositionX, playerPositionY]);
            **//Place where i need value of property of object from array of objects** 
            break;

    }
}

I'm doing a dungeon crawler and when the player steps over a tile with an item he can pick the item, so the situation is - player is on the item tile which is an index in an array of objects and I want to know the name of this object. 





ClassNotFoundException and NoClassDefFoundError trying to inspect Spring Boot jar file with java.lang.reflect

I am trying to build a tool that can inspect a specified Spring Boot application packaged as a jar. I am able to list the contents of the jar, and I am able to load and inspect some classes, but others, most importantly our own classes -- those that make up the actual application code -- I cannot inspect and get a ClassNotFoundException when trying to load them. Many, but not all, of those classes are located in BOOT-INF/classes and I have tried both with and without that path in the URLs provided, and with and without that as part of the class name. I also get many NoClassDefFoundError exceptions. If I expand the jar file, the "missing" classes are located where expected under BOOT-INF/classes/

I am not trying to run the application. That works fine with ./gradlew bootrun and I am not trying to create a custom launcher or anything like that, which is all I'm able to find for sample code. Even the SO suggestions are all related to issues running and deploying Spring Boot applications. I'm sure the causes are similar or related, but I don't know how to bridge the gap.

All I want to do is extract all the parameters that have the @Value annotation and report the values of those annotations, for both our code and any dependencies. Ultimately I want to be able to validate our yaml configurations and report on missing configuration values that are missing from those files.

Manifest (lightly redacted):

Manifest-Version: 1.0
Spring-Boot-Classpath-Index: BOOT-INF/classpath.idx
Spring-Boot-Layers-Index: BOOT-INF/layers.idx
Start-Class: com.redacted.redacted.redacted.redacted.redactedApp
 lication
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Spring-Boot-Version: 2.5.8
Specification-Version: 1.0.0
Main-Class: org.springframework.boot.loader.JarLauncher

My class loader is created like this:

final URL url = jarFile.getUrl();
final URLClassLoader urlClassLoader = LaunchedURLClassLoader.newInstance(new URL[] {
    new URL(url.toString() + "BOOT-INF/classes!/"),
    url,
});

I get the class name and try to load (exception handling code not shown):

String name = jarEntry.getName();
int endIndex = name.lastIndexOf(".class");

String className = name.substring(0, endIndex)
        .replace('/', '.').replace("BOOT-INF.classes.", "");

Class<?> loadedClass = urlClassLoader.loadClass(className);

How can I fix the problem loading these classes, or, alternatively, is there another way to extract all parameters with the @Value annotation, for all code and dependencies?