views:

158

answers:

4

Is java.lang.Class the same as the actual .class file? i.e. is the content equivalent?

I want to send the .class over socket, and was wondering if instead of trying to find and load the actual .class file, if I could just transmit the java.lang.Class instead?

Elaboration (read if you want more info)

Suppose I have a Java class called SomeObj. When this file is compiled, a file called SomeObj.class will be generated.

We also know that if I have SomeObj as a type, we could get its java.lang.Class type by doing:

Class someObjClss = SomeObj.class;

We know java.lang.Class implements Serializable, thus it can be transmitted.

So is java.lang.Class basically the object representation of the actual .class file?

UPDATE:

Assuming I have transmitted the .class file over to another host, do I just use the defineClass() method to construct the class back?

Link here

UPDATE2:

This code does returns null InputStream. How is that possible?

Class clazz = String.class;

String className = clazz.getName(); System.out.println(className);
URL url = clazz.getResource(className);
if( url != null )
{
  String pathName = url.getPath(); System.out.println(className);
}

InputStream inputStream = clazz.getResourceAsStream(className);
if(inputStream != null )
{
  System.out.println(inputStream.available());
}
+3  A: 

No. java.lang.Class is a java class. It has its own .class file :-) An instance of java.lang.Class is used to represent class of your object allowing you to perform certain operations (e.g. use reflection API) on it.

Serialization has nothing to do with .class file at all - it's object state that gets serialized. If you were to serialize Class<MyObject> and send that over the wire to a JVM which does not have MyObject.class, it still wouldn't know what MyObject is.

Why do you need to manually send .class over the wire to begin with? There are remote class loaders to deal with this.

ChssPly76
I'm doing code mobility. I need to use Reflection on the other end to dynamically load the class.
ShaChris23
You'll need to send over the actual .class then and load it on the other end. You may want to look through this: http://java.sun.com/developer/technicalArticles/Networking/classloaders/
ChssPly76
thanks for the article. I actually just need to load the .class file. Is there an easy way to simply find the .class file from my application?
ShaChris23
Assuming you have the `java.lang.Class` instance for your object (e.g. `Class clazz = MyObject.class`), you can read the actual .class file via `clazz.getResourceAsStream(clazz.getName())`
ChssPly76
@ChssPly76: thanks for your quick answer. One last question I have is suppose I transmitted the Stream (file) over socket to another host. What is the "opposite" method of getResourceAsStream() so that I could use the class in the other host?
ShaChris23
Is this the answer? http://java.sun.com/j2se/1.4.2/docs/api/java/lang/ClassLoader.html. Basically use defineClass() method.
ShaChris23
Yes, that's the one you want. ClassLoader is abstract, you need to use URLClassLoader instead. Unless doing it over your own socket (and protocol?) is critical for you I'd actually recommend you to look at RmiClassLoader that would do all of the above for you.
ChssPly76
What about the case if I run an application on LAN? i.e. just 2 computers, one holds the dynamic class, and the other one requesting for that class. Is there some API that just allows me to connect like server/client (i.e. specifying hostname/IP address and port number?)
ShaChris23
RMI (http://java.sun.com/javase/technologies/core/basic/rmi/index.jsp). Here's a tutorial: http://java.sun.com/docs/books/tutorial/rmi/index.htmlAside from that, if you really want to use it **only** for class loading and don't need the actual RPC, you can expose your classes on one machine (over HTTP or any other supported protocol) and use URLClassLoader on the other.
ChssPly76
@ChssPly76, actually the clazz.getResourceAsStream() that you mentioned above returns null. See my question update for the code I tried that returned null.
ShaChris23
@ChssPly76, I got the working solution from here: http://stackoverflow.com/questions/1780731/java-how-come-this-returns-null
ShaChris23
My bad. The above should have been `clazz.getResourceAsStream(clazz.getSimpleName() + ".class")` - that is, you want to load the .class file from package of the `clazz`; `getSimpleName()` returns just the name of the class without the package and you need to append ".class" extension to it. No need to mess with context class loader or replacing "." with file separator.
ChssPly76
A: 

Take a look at RMI (Remote Method Invocation).

TofuBeer
+1  A: 

A java.lang.Class instance is related to a corresponding ".class" file, but they are by no means equivalent.

The java.lang.Class instance encodes the type signature for a ".class" file, but not a lot more. So, though a java.lang.Class can be serialized, doing so does not provide you with enough to allow an instance of the corresponding class to be instantiated at the other end. If you want to do that, you should be sending the ".class" file.

Stephen C
+1  A: 

I think the OP is trying to identify a file on the classpath in which the class file exists. See http://asolntsev.blogspot.com/2008/03/how-to-find-which-jar-file-contains.html

ykaganovich