hii every one
I m using Applets
i ve three classes ie three applets
and I need some members(variables) of one class into another class
when i m trying to access variables from one class to another class by creating of object of
called class in to calling class then it doesnt give wright output
it access those variables but gives null or zero values
I think that this isn't possible.
Won't each applet be loaded by a different classloader? Won't this mean that the class namespaces will be kept separate by the JVM?
If that is the case, you will either have 3 versions of each class in existence (with no sharing of state ...) or the classloader will fail because it cannot find the other 2 classes when loading the first of the applets.
Related
How does Java ensure internally that only one instance of an ENUM would exist per JVM? Is it created when application boots up and from that point on when multiple threads access it, it will just return the object created at startup?
Or does it implement some kind of double synchronization similar to the singleton pattern so that even if multiple threads access it, only one istance will be created?
as you can read in this answer enum instances are static class fields and so are initialized as part of class loading when you 1st access the class.
classloading is synchronized internally so that ensures enum instances are singletons (singletons within the same classloader, that is. if you have the same enum loaded by multiple loaders you will get multiple instances)
Enum instances are created at class loading time. If the same enum gets loaded by more than one classloader (when classloading games are being played by, for example, a web app container), you will have multiple incompatible instances in memory.
I'm having a strange problem that I can't figure out that popped up when trying to pluginize my program. An additional problem is that I'm not able to create a simple test case, because every time I try it works. There must be some complication I'm missing. But I'll try to describe the situation as clearly as possible, in case it sounds familiar to anyone.
I have a base class called Seed which is part of the main application and loaded by the system classloader. I have a plugin which contains a class Road which is a subclass of Seed. It is loaded at runtime from a separate jar file. The class Road references the field Seed.garden, which is defined as:
protected final Garden garden;
Note that I don't get compilation errors. I also don't get runtime errors when the plugin jar is included on the system classpath. Only when my main application loads the plugin using a new classloader (that has the system classloader as its parent) do I get the error. The error is:
java.lang.IllegalAccessError: tried to access field package.Seed.garden from class package.Road$4
It must have something to do with the fact that the subclass has been loaded by a different class loader than the superclass, but I can't find any official reason why that shouldn't work. Also, like I said, when I try to reproduce the problem with a simple test case (that includes the separate jars, loading the subclass with a different classloader, etc.), I don't get the error.
It also doesn't seem likely that I'm violating the access rules since it works when the classes are loaded by the same classloader, and I don't get compilation errors.
I'm out of ideas! Does anyone recognise this problem, or have some pointers for me for directions in which to look? Help!
OK, so with the help of axtavt and other respondents I figured out what the problem is. The other answers helped, but they didn't get it exactly right, which is why I'm answering my own question. The problem turned out to be the concept of "runtime packages", defined in the Java Virtual Machine specification as follows:
5.3 Creation and Loading
...
At run time, a class or interface is determined not by its name alone, but by a pair: its fully qualified name and its defining class loader. Each such class or interface belongs to a single runtime package. The runtime package of a class or interface is determined by the package name and defining class loader of the class or interface.
...
5.4.4 Access Control
...
A field or method R is accessible to a class or interface D if and only if any of the following conditions is true: ...
R is protected and is declared in a class C, and D is either a subclass of C or C itself.
R is either protected or package private (that is, neither public nor protected nor private), and is declared by a class in the same runtime package as D.
The first clause explains why Road is allowed to access Seed.garden, since Road is a subclass of Seed, and the second clause explains why Road$4 is not allowed to access it, despite being in the same package as Road, since it is not in the same runtime package, having been loaded by a different class loader. The restriction is not actually a Java language restriction, it is a Java VM restriction.
So the conclusion for my situation is that the exception occurs due to a legitimate restriction of the Java VM, and I'm going to have to work around it, probably by making the fields public, which is not a problem in this case since they are final, and not secret, or perhaps by exporting Seed.garden to Road$4 via Road, which does have access.
Thank you everyone for your suggestions and answers!
Sounds like you have a class identity crisis, having two different class loaders loading the same class in the class hierarchy or similar. Read up some on the java class loaders. Here is a good one for introduction, for "class identity crisis" see figure 2: http://www.ibm.com/developerworks/java/library/j-dyn0429/
I should add that Road$4 is an anonymous inner class of Road...
Someone else thought this was a bug as well back in 1998:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4116802
An inner class has no greater access to members of another class than
a top-level class, except for those members that are declared within
an enclosing, enclosed, or sibling class. It is a common misconception
that an inner class has unrestricted access to inherited members of
its enclosing classes. This is not true.
I would probably research that fact a bit more though because this was reported originally against Java 1.2, but I seem to remember from my reading that this is true today as well.
EDIT:
I confirmed this to be true:
http://docs.oracle.com/javase/tutorial/java/javaOO/summarynested.html
The scope for an anonymous inner class is only the point where it is defined. So it will not have access to inherited members, even if the outer class does.
This is permission error, so it depends on the framework you use to run your runtime.
Just to clarify this is indeed this, make the parent member public, and then try to run. In case everything is ok, then restore your code, and according to the runtime you use we need to configure the correct security access.
We do have a cache (Map) with objects of Class TestClass. Another classloader initializes/loads TestClass at runtime again, so below code will threw a ClassCastException:
TestClass obj1 = (TestClass)map.get("key"); // throws a ClassCastException
ClassCastException when casting to the same class
Alright, I do understand this issue up to this point.
So, I was trying to find background information why is TestClass.class not equals TestClass.class. I assume that the different classloader set a different id to the ReferenceType? Anyone able to explain the background to me?
Best page I've found:
http://www.objectsource.com/j2eechapters/Ch21-ClassLoaders_and_J2EE.htm
Yes, your research points to the right direction: the same class definition loaded by different class loaders is seen as two distinct classes by the JVM. Thus casting between them fails with ClassCastException.
I think the difference is simply because there are two distinct class token objects in play. It has to be like this, since the classes loaded by the different loaders may in fact be different versions of the same class. It is known that the class token for every class is unique (within the same classloader realm, that is). It would open up a can of worms if the JVM started to compare class tokens by their various attributes, rather than by physical equality (==).
What you experienced is the reason why custom class loaders exist. They allow to load different class with the same name in one JVM. The identity of a class in a JVM is given by the tuple consisting of the class name and the class loader. In the language Java a class is identified just by fully qualified name.
Anyone able to explain the background to me?
As Péter Török already explained they are considered different when loaded from different classloaders.
The background is that an application server should be able to support different versions of an application e.g. different versions of the same libraries included in your ear-files.
There is no mystery. Runtime equality of types is defined in the Java Language Specification as follows:
"At run time, several reference types with the same binary name may be loaded simultaneously by different class loaders. These types may or may not represent the same type declaration. Even if two such types do represent the same type declaration, they are considered distinct."
JLS 4.3.4 - When reference types are the same. (2nd paragraph)
I am developing a Java Program, I have 2 different classes that need to share variables with each other. So for this purpose I created a third class, which contains these shared variables. Basically, first class has its own flag in this third class, and second class has its own flag in this third class. And I add "extend ThirdClass" to other classes' definition, of course.
My problem is when I change the value of first class' flag in the first class' main method, second class is not able to see this change. Namely, it sees the flag with inital value.
I think this is about static variables. But I do not know the solution.
Actually, I have two servers and multi clients. I am trying to simulate differenet situations of these servers for my distributed systems course. Each server has its own data table that is synchronized with other. By simulation, I mean server may be down or up, and when client try to reach down server I need to direct it to other server. So, between clients and servers I need to send information.
How can I share variables between two classes, and easily modify these variables by any class without loss of previous modifications ?
Thank you.
EDIT -- this answer is for a previous version of the question, that does not include anything about clients and multiple servers. This answer is about sharing data between instances of classes.
There are many ways to do something like this. If I understood your approach outlined in the first paragraph, you dont want class1 and class2 to extend class3. You want them to both have a reference to the same instance of class3. If they share a reference to the same object, then changing values on that object will be reflected in both classes. If they extend class3, like you said you tried, then both class1 and class2 will have the properties of class3, but they wont be sharing any data. If class 3 had a property
Object value;
then instances of class1 and class2 would have separate references to separate instances of 'value'.
You need to undertand the relationship between a class, and object instance, and what extending a class means.
Note that this is not really a good way to share information between objects in a real program. You can run into all sorts of concurrency issues. The same is true for a solution that used a global mechanism implemented using static fields.
To do this with static fields do something like:
class SharedData {
public static Object shared1;
}
and then in your class1 and class2 instances you can access
SharedData.shared1
for either set or get.
But I would not do anything like this in any sort of professional context.
You could solve this using statics if it makes sense. When a member is declared static for a class, everyone accessing that member refers to the same instance of that variable, but that doesn't really sound like what you're looking for.
If you want some data to be shared by two classes, you can put the data in a third class and when you create an instance of that third class, be sure the other two classes simply have access to it.
Could you outline what you're trying to accomplish?
That is when you have any jar file attached to you your class path. then as far as i know any class from the jar is loaded for the first time when,
when you create any object of that type. or
If you are accessing any static member or method of that class. or
when you load that by using Class.forName() method.
So are there any other ways of loading a class for the first time?
This may be helpful:
5.3 Creation and Loading on the The JavaTM Virtual Machine Specification
I think this pretty much covers it, though of course, class loading is "transitive".
If you are loading a class that references X (e.g., as a return value, as an instantiation, etc.), then X will have to be loaded.
I'm not sure if the loader is allowed to delay the actual load until the reference is really needed.
Also, whenever ClassLoader.loadClass(className) is called.