vendredi 2 mars 2018

Java Reflection: obtain a Array class from an object class

Supposing I have MyObject class, i need a generic array from a generic type.

MyObject object;
MyObject array[] = (MyObject) genericFunction(data,object.getClass()) ;


public Object[] genericFunction(Object someData, Class<?> objectClass) ;

There is a way to get MyObject[].class from MyObject.class via reflection? Actually I call my method as

MyObject array[] = (MyObject[]) genericFunction(data,MyObject[].class, MyObject.class()) 

and I would remove this sort of redundancy





How to get static properties from static class using reflection

I've got a static class with static getters.

public static class Cars
{
   public static KeyValuePair<Guid, string> Acura
   {
       get { return new KeyValuePair<Guid, string>(new Guid("MMMMMMMM-509B-477A-ADB1-5CD014B41001"), "Acura"); }
   }
   public static KeyValuePair<Guid, string> AlfaRomeo
   {
      get { return new KeyValuePair<Guid, string>(new Guid("MMMMMMMM-509B-477A-ADB1-5CD014B41002"), "Alfa Romeo"); }
   }
   // etc.
}

I need to retrieve all the static properties from this static class and do something with each KeyValuePair. But the following throws a System.FormatException at runtime saying that it could not find recognizable digits

Type type = typeof(Cars);
foreach(var manufacturer in type.GetProperties())
{
    if(manufacturer.PropertyType == typeof(KeyValuePair<Guid, string>))
    {
        var v = manufacturer.GetValue(null, null); //this does not work
        // How to get the KeyValuePair<Guid, string>? 
    }
}

How to get each KeyValuePair?





jeudi 1 mars 2018

Invoking methods containing Hibernate transaction on external JAR/CLASS using reflection (Java EE)

Good day! I'm having problem making hibernate work on a external jar which is loaded thru reflection on my EJB. As of now I've tried three options but none of these works and just gives me error.

Here are a snippet of codes I've tried. I also added comment to which line the error occurs in each option.

OPTION 1. PASSING SESSION FROM EJB TO EXTERNAL JAR THRU HashMap/Map

My Session Bean Class

public Object processRequest(Map parameters) {
    String runnerClass = (String) parameters.get("runnerClass");
    String value = (String) parameters.get("value");
    String jarPath = "csys.runner.jar";
    Object returnObj = null;
    try {
        parameters.put("sessionEjb", getSession());
        File f = new File(jarPath);
        URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{f.toURL()},
                System.class.getClassLoader());
        Class c = urlClassLoader.loadClass(runnerClass);
        Method m = c.getMethod("performService", new Class[]{String.class, Map.class});
        returnObj = m.invoke(c.newInstance(), new Object[]{value, parameters});
    } catch (MalformedURLException | ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
        Logger.getLogger(CSysSessionBean.class.getName()).log(Level.SEVERE, null, ex);
        throw new RuntimeException(ex);
    }
    return returnObj;
}

External JAR Method

public Object performService(String value, Map<Object, Object> parameters) {
    this.session = (Session) parameters.get("sessionEjb");  // ERROR IN THIS PART ClassCastException
    return null;

it gives me this error.

java.lang.ClassCastException: org.hibernate.internal.SessionImpl cannot be cast to org.hibernate.Session

OPTION 2. PASSING SESSION FROM EJB TO EXTERNAL JAR VIA METHOD's PARAMETERS My Session Bean Class

public Object processRequest(Map parameters) {
    String runnerClass = (String) parameters.get("runnerClass");
    String value = (String) parameters.get("value");
    String jarPath = "csys.runner.jar";
    Object returnObj = null;
    try {
        File f = new File(jarPath);
        URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{f.toURL()},
                System.class.getClassLoader());
        Class c = urlClassLoader.loadClass(runnerClass);
        Method m = c.getMethod("performService", new Class[]{String.class, Map.class, org.hibernate.Session.class}); //ERROR IN THIS PART NoSuchMethodException
        returnObj = m.invoke(c.newInstance(), new Object[]{value, parameters, getSession()});
    } catch (MalformedURLException | ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
        Logger.getLogger(CSysSessionBean.class.getName()).log(Level.SEVERE, null, ex);
        throw new RuntimeException(ex);
    }
    return returnObj;
}

External JAR Method

public Object performService(String value, Map<Object, Object> parameters, org.hibernate.Session session) {
    this.session = session;  
    return null;
}

now it throws me this error.

java.lang.NoSuchMethodException: csys.server.main.runner.ProjectRunner.performService(java.lang.String, java.util.Map, org.hibernate.Session)

OPTION 3. CREATING SESSION IN EXTERNAL JAR

My Session Bean Class

public Object processRequest(Map parameters) {
    String runnerClass = (String) parameters.get("runnerClass");
    String value = (String) parameters.get("value");
    String jarPath = "csys.runner.jar";
    String configPath = "D:/config/hibernate.cfg.xml";
    Object returnObj = null;
    try {
        File f = new File(jarPath);
        URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{f.toURL()},
                System.class.getClassLoader());
        Class c = urlClassLoader.loadClass(runnerClass);
        Method m = c.getMethod("performService", new Class[]{String.class, Map.class, String.class}); 
        returnObj = m.invoke(c.newInstance(), new Object[]{value, parameters, configPath});
    } catch (MalformedURLException | ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
        Logger.getLogger(CSysSessionBean.class.getName()).log(Level.SEVERE, null, ex);
        throw new RuntimeException(ex);
    }
    return returnObj;
}

External JAR Method

public Object performService(String value, Map<Object, Object> parameters, String configPath) {
    Configuration configuration = new Configuration();
    configuration.configure(new File(configpath)); //ERROR IN THIS PART, COULD NOT PARSE CONFIGURATION
    SessionFactory sessionFactory = configuration.buildSessionFactory();
    this.session = sessionFactory.openSession();  
    return null;
} 

now it throws me another error.

org.hibernate.HibernateException: Could not parse configuration: D:\config\hibernate.cfg.xml
at org.hibernate.cfg.Configuration.doConfigure(Configuration.java:2163)
at org.hibernate.cfg.Configuration.configure(Configuration.java:2133)
Caused by: org.dom4j.DocumentException: org.dom4j.DocumentFactory cannot be cast to org.dom4j.DocumentFactory Nested exception: org.dom4j.DocumentFactory cannot be cast to org.dom4j.DocumentFactory

Note that executing hibernate transactions in my EJB project is working well, it's just executing from external jar gives me error.





Create Instance of Object by Classname in C++

i'm looking for a solution of my actual problem. Lets say, i have something like a header file named Module with some virtual methods and i have some specific implementations Module1, Module2, ..., ModuleN based on Module.

I dont really know which one of these modules i will create an instance when i start the program, the user decides with an program argument -module ModuleK which one he wants to start. So, how can i create an instance of my ModuleK only with the class name? I need something like javas classloader, is there something like that in c++ ? I saw some solutions where i regist those objects :

Instantiate class from name?

and i would like do it more dynamic, not hard-coded. The user "repl" already described how could it work, but is there another option?





Is there a way to identify my custom assemblies when scanning all assemblies using c#?

I have an application with multiple projects. Of course, each project create it's own dll. Then we can use AppDomain.CurrentDomain.GetAssemblies().ToList() to get all assemblies to use reflection for many reasons.

The AppDomain.CurrentDomain.GetAssemblies() is going to scan every assembly that exists including the standard assumblies like Microsoft's or packages we pull using Nuget of other dependency management tools. What if I want to only scan only my projects dll not the others?

Is there a way to give my projects a shared type then look for that shared type? Unfortunately my projects don't have a common name schema to scan the name for something that starts-with or ends-with here.





Java generic parameter as exact subclass?

Assuming we have a method like this:

public void foo(Class<? extends ClassBar> x) {
    ...
}

By modifying the generic expression;

< ? extends ClassBar >

Is it possible to ensure that ClassBar.class can't be passed in but anything extends ClassBar directly or indirectly be passed in WITHOUT throwing an exception on the runtime?





How can we get List

I am using T4 Template to generate c# class. I need to generate shadow class from another class Class1. In the Calss1, I have TypeAttribute which can tell what is the type of Proeprty in the Class1. By using reflection I am getting the Type specified in the TypeAttribute.

I am not getting any standard way to get the Type for the Generics in unmangled format.

I need List<String> from System.Collections.Generic.List`1[System.String].

I am using T4Toolbox for T4Template.

Is T4Toolbox is providing any such feature to deal with generics while generating c# code?

Thank you.