Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
Solved

Using Introspection in Java

Posted on 2001-07-31
9
598 Views
Last Modified: 2012-06-27
Hi!

I'm developing some java application in conjunction with other parties.
One of them send me a class "package" that I have to integrate with ours using introspection. The problem is that I don't quite understand how.
Can someone explain to me, as simplified as possible, what is introspection and how to use it for integration. I know that has something to do with JavaBeans.
Also can someone point to me some good documentation about this issue.
Thanks,
0
Comment
Question by:jmsr
  • 6
  • 3
9 Comments
 
LVL 4

Expert Comment

by:sdussinger
ID: 6339016
Basically, introspection (or reflection as its called in the Java world) is the ability to inspect the fields and methods of a class at runtime. For example, one could load a class into the JVM, determine the names and argument lists for methods within that class, and call them. Without any previous knowledge of the class's contents.

A couple of good starting articles on reflection:
http://www.javaworld.com/javaworld/jw-08-1997/jw-08-indepth.html
http://www.javaworld.com/javaworld/jw-09-1997/jw-09-indepth.html

A few more of interest:
http://developer.java.sun.com/developer/technicalArticles/ALT/Reflection/
http://java.sun.com/products/jdk/1.1/docs/guide/reflection/

My guess is that your initial task will be to load the class and write some reflection code which will dump the methods and fields of the class you wish to integrate. From there, you can determine what parameters are needed to call the methods, and can integrate those calls into your existing code.

HTH.

--Steve
0
 
LVL 4

Expert Comment

by:sdussinger
ID: 6339031
Some code might be in order here:

First, we load a class and print out its public fields, member methods, and constructors:

public void dumpInfo (String className) throws ClassNotFoundException, SecurityException
{
  Class c = Class.forName (className);

  System.out.println ("Public Fields:");

  Field f[] = c.getDeclaredFields ();

  for (int i = 0; i < f.length; i++)
    System.out.println (f[i].toString ());

  System.out.println ("");
  System.out.println ("Public Constructors:");

  Constructor cons[] = c.getDeclaredConstructors ();

  for (int j = 0; j < cons.length; j++)
    System.out.println (cons[j].toString ());

  System.out.println ("");
  System.out.println ("Public Methods:");

  Method m[] = c.getDeclaredMethods ();

  for (int k = 0; k < m.length; k++)
    System.out.println (m[k].toString ());
}

--Steve
0
 
LVL 4

Expert Comment

by:sdussinger
ID: 6339041
Once you have a listing of the possible fields, methods, and constructors. You need to be able to do something with them.  Here we call a method on a class which we've loaded.

public void callMethod () throws ClassNotFoundException, SecurityException
{
  Class c = Class.forName ("pkg.myClass");

  try
  {
    // Find a method called "methodToCall" Which takes 1 single string as a parameter.
    // If the method with the correct arg list is not found, then throw a NoSuchMethodException
    Method m = c.getMethod ("methodToCall", new Object [] { String.getClass () } );

    // Got the correct method, so create an arg list with the
    // string Hello in it, and call the method. If the
    // method returns a value it will be in val.
    Object val = m.invoke (new Object [] { new String ("Hello") } );
  }
  catch (NoSuchMethodException nsme)
  {
    nsme.printStackTrace ();
  }
}

--Steve
0
Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

 
LVL 4

Accepted Solution

by:
sdussinger earned 300 total points
ID: 6339053
Oops. The last one should read like this. THat's what happens when you're in a hurry :-).

public void callMethod () throws ClassNotFoundException, SecurityException
{
 Class c = Class.forName ("pkg.myClass");

 try
 {
   // Find a method called "methodToCall" Which takes 1 single string as a parameter.
   // If the method with the correct arg list is not found, then throw a NoSuchMethodException
   Method m = c.getMethod ("methodToCall", new Object [] { String.getClass () } );

   // Create an instance of myClass to call the method on...
   // This assumes that myClass has a default constructor.
   Object aMyClass = c.newInstance ();

   // Got the correct method, so create an arg list with the
   // string Hello in it, and call the method. If the
   // method returns a value it will be in val.
   Object val = m.invoke (aMyClass, new Object [] { new String ("Hello") } );
 }
 catch (NoSuchMethodException nsme)
 {
   nsme.printStackTrace ();
 }
}

Sorry for the confusion.

--Steve
0
 

Author Comment

by:jmsr
ID: 6355369
Sorry for not get back to you, sdussinger, but I've been very busy.
Ok. So I now know how to introspect a class. Thanks a lot, I will give you the answer points. I actually made some tests an I could get fields and methods from a given Class. I just allways need to know in advance the names of the fields and methods. Right?

But now I have another problem concerning this. Now I need to "construct" this class and load it in RunTime so I can use it within my application. The thing is: I'm getting all that information by using rmi from a, let's say, class description catallogue. I have the class description the fields, the methods, the parameters their type and return type. All this in alias form (Srings). Now I have to build a class with this information and then load it to my environment.

Any suggestions in how would I be able to achieve this?

I was taking a look to ClassLoader but this uses a stream of bytes as input and that's not what I have.

Please give me some hints on this or from where should I start.
Thanks a lot. Regards.

Jo?o
0
 
LVL 4

Expert Comment

by:sdussinger
ID: 6355847
1) You don't need to know the names of the fields or methods in advance. You can look up the names of fields and methods using the code I posted earlier. All you need to do is load the class (using Class.forName()) and call getFields, getMethods, or getConstructors to find the names. After that, you can access them.

2) Are you talking about actually dynamically creating the bytecode for classes at runtime? Or do you already have a class and just want to load it?

--Steve
0
 

Author Comment

by:jmsr
ID: 6355903
Yap. Actually I'm talking about creating the bytecode for the classes and then load them. That's what is making this quite dificult.
The only thing I've got is classes (that I have to introspect) with the descriptions of the classes I really need. A bunch of Strings with the name, fields, methods, parameter and types.
No I need to create the class, probably compile it, and then load it. Pretty scary! At least for me! :-(
If you can help me with this, please do. If not please just explain me how to load the classes in RunTime and I will try to figure out the first part.
Thanks,

Joao
0
 

Author Comment

by:jmsr
ID: 6356291
Yap. Actually I'm talking about creating the bytecode for the classes and then load them. That's what is making this quite dificult.
The only thing I've got is classes (that I have to introspect) with the descriptions of the classes I really need. A bunch of Strings with the name, fields, methods, parameter and types.
No I need to create the class, probably compile it, and then load it. Pretty scary! At least for me! :-(
If you can help me with this, please do. If not please just explain me how to load the classes in RunTime and I will try to figure out the first part.
Thanks,

Joao
0
 
LVL 4

Expert Comment

by:sdussinger
ID: 6358081
Ok, let's start with the easier of the two: loading the class file once you've created it.

Assuming that the .class files are in a directory on your local machine called "dynamicClasses", you could write a function like this to load them:

import java.net.URLClassLoader;

Class loadClass (String className)
{
  URLClassLoader cl = null;

  try
  {
    cl = URLClassLoader.newInstance (new URL []
                                           {
                                             new URL ("file:/dynamicClasses"),
                                           } );

      Class c = urlcl.loadClass (className);

      return (c);
    }
    catch (Exception e)
    {
      e.printStackTrace ();
    }
  }

  return (null);
}

This will handle loading a class from the location you specified. Notice that the URLClassLoader constructor takes an array of URLS, so you can contruct an array of locations for the loader to try to find your class.

Now for the hard part, generating bytecodes:

Are you going to be generating source code and then building the bytecodes from that or do you want to build bytecodes from scratch (effectively builing your own bytecode assembler)?

If you have the source code (or can generate it) for a Java class, you can call the Sun compiler directly from inside your program.

The following code will do that for you:

public class CompTest
{

  public static void main (String args[])
  {
    sun.tools.javac.Main compiler = new sun.tools.javac.Main (System.out, "javac");

    String params[] = new String[] { "test.java" };

    if (compiler.compile (params) == true)
      System.out.println ("Compile succeeded");
    else
      System.out.println ("Compile failed");
  }

}

This will compile the file test.java and create a class file called test.class. You can load the test.class file using the URLClassLoader code above.

If, pn the other hand, you want to generate the actuall byte codes yourself, take a look at the IBM alphaWorks JIKES Bytecode library. The url is: http://alphaworks.ibm.com/aw.nsf/techmain/jikesbt

Hope this helps...

--Steve
0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

An old method to applying the Singleton pattern in your Java code is to check if a static instance, defined in the same class that needs to be instantiated once and only once, is null and then create a new instance; otherwise, the pre-existing insta…
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
Viewers learn about the scanner class in this video and are introduced to receiving user input for their programs. Additionally, objects, conditional statements, and loops are used to help reinforce the concepts. Introduce Scanner class: Importing…
Viewers will learn about if statements in Java and their use The if statement: The condition required to create an if statement: Variations of if statements: An example using if statements:

808 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question