• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • paul wheaton
  • Liutauras Vilda
  • Ron McLeod
Sheriffs:
  • Jeanne Boyarsky
  • Devaka Cooray
  • Paul Clapham
Saloon Keepers:
  • Scott Selikoff
  • Tim Holloway
  • Piet Souris
  • Mikalai Zaikin
  • Frits Walraven
Bartenders:
  • Stephan van Hulst
  • Carey Brown

Strange things showing up in Reflection

 
Ranch Hand
Posts: 65
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'm writing an application that uses the java.lang.reflect set of objects to analyze a Java program. For some of the files I've looked at, I find static methods being reported with names (returned from a <Method>.getName() call) that are "Access$0", "Access$1", etc. These methods all have no arguements, and return various kinds of objects.
For example, in one program, there is a static method that retuns a java.util.Hashtable. When I look at the source, there are only three lines that refer to a Hashtable.
1) import java.util.Hashtable;
2) private static Hashtable buttons;
3) buttons = new Hashtable( n );
Also, the methods are not flagged as private, public, or protected, just the no-name state for use within a package.
Does anyone know anything about what is going on here?
Dave Patterson
[email protected]
 
Ranch Hand
Posts: 1873
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
hi David,
can you post a code snippet here? i tried with a simple class and it returns me method names properly for static methods in the class...
'$' sign in Access$0 and Access$1 you get indiciates you might be having some INNER classes or something...i don't know...it would be really helpful if you can post a snippet of your code so that i can also try running similar code and see if we get the same output...
btw, here is the code i wrote and the output i get,

output
------
9:method1:void
9:method2:void

regards
maulin
 
David Patterson
Ranch Hand
Posts: 65
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks for the response. My code is long and involved, but I'll show a subset of it. I've run this application on over 30 files, and have seen the problem only in two cases.
I first go through the declared methods and create a TreeMap, with the method name and parameter types as the key, and the method object as the contents of the TreeMap.
int mods;
Vector output = new Vector( 200 );
StringBuffer sb = new StringBuffer( 50 );
Class target = Class.forName( className );
try
{
Method[] methods=target.getDeclaredMethods();
for ( int i = 0; i < methods.length; i++ )
{
Method thisMethod = methods[ i ];
sbtemp.setLength( 0 );
sbtemp.append( thisMethod.getName() );
parms = thisMethod.getParameterTypes();
sbtemp.append( "(" )
.append( describeParms( parms ) )
.append( ")" );
sortedMethods.put( sbtemp.toString(), thisMethod );
} // end of for
When the problem occurs, the value of the StringBuffer is always
access$0():<some class>
The class name is always something that is used in the source class's contents, it is not some off-the-wall class.
I'm fairly comfortable that this part of my code works, and think it is something special that is being done.
Still puzzled,
Dave Patterson
[email protected]
 
Maulin Vasavada
Ranch Hand
Posts: 1873
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
hi David
sorry if i sound dumb but i'm not able to understand your problem. you say that access$0 etc is the class names you have in the code, right? then what is the problem?
i 'm sort of simple guy. i would understand more clearly if i am given,
1. this is what is expected,
2. this is what is obtained
i wish i was exprienced enough to understand ur problem easier way and faster...
regards
maulin
 
Wanderer
Posts: 18671
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Well, it's hard to tell based on what's been shown so far. But if the classes you're looking at contain nested classes, there are a number of ways these sorts of things show up. Some are discussed in the all-but-forgotten Inner Classes Specification (yeah, you've got to download the whole doc since Sun has archived this now). Find the section on "How do inner classes affect the organization of the Java Virtual Machine?" and you get the following:


How do inner classes affect the organization of the Java Virtual Machine?
There are no changes to the class file format as processed by the Java Virtual Machine, or to the standard class libraries. The new features are implemented by the compiler. The organization of the resulting bytecodes is specified with enough precision that all 1.1-conforming compilers will produce binary compatible class files.
A single file of Java source code can compile to many class files. Although this is not a new phenomenon, the power of the inner class notation means that the programmer can end up creating a larger number of class files with relatively less code. In addition, adapter classes tend to be very simple, with few methods. This means that a Java program which uses many inner classes will compile to many small class files. Packaging technologies for such classes process them reasonably efficiently. For example, the class file for the example class FixedStack.Enumeration occupies about three quarters of a kilobyte, of which about 40% is directly required to implement its code. This ratio is likely to improve over time as file formats are tuned. The memory usage patterns in the virtual machine are comparable.
Class name transformations
Names of nested classes are transformed as necessary by the compiler to avoid conflicts with identical names in other scopes. Names are encoded to the virtual machine by taking their source form, qualified with dots, and changing each dot `.' after a class name into a dollar sign `$'. (Mechanical translators are allowed to use dollar signs in Java.)
When a class name is private or local to a block, it is globally inaccessible. A compiler may opt to code such an inaccessible name by using an accessible enclosing class name as a prefix, followed by a `$' separator and a locally unique decimal number. Anonymous classes must be encoded this way.
So, an inner class pkg.Foo.Bar gets a run-time name of pkg.Foo$Bar, or perhaps something like pkg.Foo$23, if Bar is a private member or local class. Implementations must conform to the format of names, even globally inaccessible ones, so that debuggers and similar tools can recognize them.
Any class file which defines or uses a transformed name also contains an attribute (as supported by the 1.0 file format) recording the transformation. These attributes are ignorable by the virtual machine and by 1.0 compilers. The format of this attribute is described in the section on binary compatibility.
Names of generated variables and methods
As we have seen previously, if an inner class uses a variable from an enclosing scope, the name expression will be transformed, into a reference either to a field of an enclosing instance, or to a field of the current instance which provides the value of a final local variable. A reference to an enclosing instance, in turn, is transformed into a reference to a field in a more accessible current instance. These techniques require that the compiler synthesize hidden fields in inner classes.
There is one more category of compiler-generated members. A private member m of a class C may be used by another class D, if one class encloses the other, or if they are enclosed by a common class. Since the virtual machine does not know about this sort of grouping, the compiler creates a local protocol of access methods in C to allow D to read, write, or call the member m. These methods have names of the form access$0, access$1, etc. They are never public. Access methods are unique in that they may be added to enclosing classes, not just inner classes.
All generated variables and methods are declared in a class file attribute, so that the 1.1 compilers can prevent programs from referring to them directly.
Security implications
If an inner class C requires access to a private member m of an enclosing class T, the inserted access method for m opens up T to illegal access by any class K in the same package. There at present are no known security problems with such access methods, since it is difficult to misuse a method with package scope. The compiler can be instructed to emit warnings when it creates access methods, to monitor the creation of possible loopholes.
If a class N is a protected member of another class C, then N's class file defines it as a public class. A class file attribute correctly records the protection mode bits. This attribute is ignored by the current virtual machine, which therefore will allow access to N by any class, and not just to subclasses of C. The compiler, of course, will correctly diagnose such errors, because it looks at the attribute. This is not a security hole, since malicious users can easily create subclasses of C and so gain access to N, protected or not.
Likewise, if a class is a private member of another class, its class file defines it as having package scope, and an attribute declares the true access protection, so that 1.1 compilers can prevent inadvertant access, even within the package.


You may also want to check out this thread, which discusses a similar sort of thing which as far as I can tell was not covered in the inner classes spec. You can also use javap to disassemble the class files of these classes, and learn just what they're really doing.
[ January 07, 2003: Message edited by: Jim Yingst ]
 
David Patterson
Ranch Hand
Posts: 65
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks to all. I think Jim's post had the answer. I'll explore a few things that come to mind and see if I can change the results. Bottom line, it looks like my code to snoop in a class file is working, the strange stuff it is finding should be there. Now to explore the strange stuff.
Dave Patterson
[email protected]
 
Well don't expect me to do the dishes! This ad has been cleaned for your convenience:
Smokeless wood heat with a rocket mass heater
https://woodheat.net
reply
    Bookmark Topic Watch Topic
  • New Topic