سؤال

I am loading a jar file at runtime using urlclassloader. Jar file and the classes are getting successfully loaded. I have a class with a method that return an Object X. Using the object X, i have to call Setter methods on the X.

How do I call the setter methods on the X?

I have the object X returned by invoking the method.

X = my.invoke(inst, obj);
  1. Do I need to create an instance again by calling newInstance() method on X class?
  2. To call the methods of Object X, do I have to call method.invoke() each and every time ? Assume X object has 5 methods, find the method and invoke the method using Method.invoke.

Your suggestions will be really helpful.

   File f1 = new File("/home/egkadas/CR364/lib/xxx.jar");
   URL urls [] = new URL[1];
   urls[0] = f1.toURL(); 
    
   URLClassLoader urlClass = URLClassLoader.newInstance(urls);
   Class c1 = urlClass.loadClass("com.xxxx.example.poc.Container");
   Container  inst = (Container)c1.newInstance();
    
   if(inst == null){
        System.out.println("Object is null");
   }else{
     Method my = c1.getMethod("getAttribute",null);
      Object[] obj = new Object[0];
 com.XXXXX.example.poc.Container.Attributes att =(com.XXXXX.example.poc.Container.Attributes)my.invoke(inst, obj);
      System.out.println(att);

   

Code in the jar :

public class Container {
    
    public String id;
    
    public Container(){
        
    }
    
    public Container(String id){
        this.id=id;
    }

    public void setId(String id){
        this.id=id;
    }
    public Attributes getAttribute(){
        return new Attributes("check","12lb","15lb",100);
    }
    
    public List<Attributes> getAttributes(){
        List<Attributes> ats = new ArrayList<Attributes>();
        
        return ats;
    }
    
    public static class Attributes {
        public String name;
        public String weight;
        public String height;
        public int capacity;
        
        public Attributes(String name,String weight,String height,int capacity){
            this.name=name;
            this.weight=weight;
            this.height=height;
            this.capacity=capacity;
        }
    
        public Attributes(){
            
        }
        public String toString(){
            return this.name+" "+this.weight+"  "+this.height+" "+this.capacity;
        }
        
        public void setName(String name){
            this.name=name;
        }
        public void setWeight(String weight){
            this.weight =weight;            
        }
        public void setHeight(String height){
            this.height=height;
        }
        
        public void setCapacity(int cap){
            this.capacity=cap;
        }
    }
}
هل كانت مفيدة؟

المحلول

Do I need to create an instance again by calling newInstance() method on X class?

No, given your explanations, you already have an object X. You don't need to create a new one of whatever type it is.

To call the methods of Object X, Do i have to call method.invoke() each and every time ? Assume X object has 5 methods, find the method and invoke the method using Method.invoke.

Reflection is a run time thing. You don't know the declared (or static) types to work with. You're basically only working with the Object interface/contract. As such, you need to do everything through the reflection utilities. If you want to call a method of an object, you need to retrieve the corresponding Method object and call its invoke(..) method with the correct arguments.

نصائح أخرى

That depends on which classloader defines the X class. If it is the parent classloader, you can simply cast your return value:

X x = (X) my.invoke(inst, obj);

and then use it like any other java object.

If X is defined by your custom classloader, it gets more complicated, as the definition of X is not visible to classes loaded by the parent class loader. Therefore, these classes can not refer to the methods and fields of X in their source code. The usual workaround is to have an interface (let's call it Y) in the parent class loader that is implemented by X in the custom class loader. Since the methods are declared in Y, they are accessible from the parent class loader, even if calling them executes the implementation in class X.

If you can't do that either, you can still invoke these methods using reflection.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top