Solved

Classes of Package

Posted on 2001-06-21
25
359 Views
Last Modified: 2013-11-23
Let say I have a package name, for example "java.util". Or I have a valid Package object that coresponds to the package.

All I want is to get Classes of that Package, for example as Class[] or any other way.

If you believe that is not acievable, is the a way to get all Classes currenly loaded into VM.
0
Comment
Question by:chochomhaloimed
  • 6
  • 5
  • 5
  • +3
25 Comments
 

Expert Comment

by:Nachiap
ID: 6217214
I think you have to write your own customised class loader
you have to over write loadClass() method..
0
 
LVL 3

Expert Comment

by:exorcist
ID: 6217705
Hi,

you might not even know what classes are loadable. As long as classes arent loaded, the VM doesnt know if they exist or not. This depends on where your ClassLoader gets its class files from. Imagine a ClassLoader that makes a network broadcast to check if any computer on the network has this class.

So you will have to write your own ClassLoader to achieve this.

Concering "java.util", there is a little difference. Classes can only be in the java package if they actually in the CLASSATH. They cannot be loaded anywhere else. (Try to make your own class in java.util and place it in the CLASSPATH and then try to access it from an applet via network. First will work, second will not). So the amount of classes in java.util is constant.

the Java Exorcist
0
 
LVL 7

Expert Comment

by:Sasha_Mapa
ID: 6218145
Umm, exorcist, I'm not 100% sure, but I think you're wrong - I don't think the java.* classes get any special treatment from any actual code.

Sasha Maryanovsky.
0
 
LVL 3

Expert Comment

by:exorcist
ID: 6218298
Hi Sasha,

ok, I was wrong. But just a little bit.
the java.* classes DO get a special treatment. Try following program:

package java.util;

public class ClassTest{

    public static void main(String args[]) {

     System.out.println("working");
    }
}

It will compile just fine, but when started a SecurityException will be thrown (Prohibited package name).

That was the part i was right about.

What I was wrong about, was the part when I said that putting it in the CLASSPATH would help. It doesn't.

So you aren't allowed to declare classes in package java.* no matter what ClassLoader you use.

As for javax.* I am not sure if there are any rules. But this program worked when put in package javax.util

already got a job?
0
 
LVL 3

Expert Comment

by:falter
ID: 6218301
Sasha,

the point is not the package java.* or sun.* the difference comes from different class loaders.
In one case the "filesytem"-classloader is used in the other cas a "Network"-Classloader.
As I know the URLClassloader used in applets has
build in security restrictions, normally you cannot
load classes from packages starting with java. or sun.
over the network for obvious reasons.
Todo this you need to implement a SecurtityManager and
have to sign your applet and the user has to grant the needed rights to the applet.
I'm not sure what happens, if you use URLClassLoader from outside of the sandbox.

cheers
jf
0
 
LVL 3

Expert Comment

by:falter
ID: 6218302
Sasha,

the point is not the package java.* or sun.* the difference comes from different class loaders.
In one case the "filesytem"-classloader is used in the other cas a "Network"-Classloader.
As I know the URLClassloader used in applets has
build in security restrictions, normally you cannot
load classes from packages starting with java. or sun.
over the network for obvious reasons.
Todo this you need to implement a SecurtityManager and
have to sign your applet and the user has to grant the needed rights to the applet.
I'm not sure what happens, if you use URLClassLoader from outside of the sandbox.

cheers
jf
0
 
LVL 3

Expert Comment

by:falter
ID: 6218306
Sorry,

stupid browsers let me submit the comment twice
0
 
LVL 3

Expert Comment

by:falter
ID: 6218324
Sasha,

isn't it possible to setup something in a policy file
to allow the use of restricted package names ?
0
 
LVL 3

Expert Comment

by:exorcist
ID: 6218344
nope.
0
 
LVL 3

Expert Comment

by:falter
ID: 6218350
Sasha,

isn't it possible to setup something in a policy file
to allow the use of restricted package names ?
0
 
LVL 3

Expert Comment

by:exorcist
ID: 6218454
I think this is hard-coded.
The program I posted above runs as an application and not applet. So I already have the least possible security, i.e. I am actually allowed everything that is allowable. Try it and you will see that it throws a SecurityException no matter what permissions you allow in the policy file.
0
 

Author Comment

by:chochomhaloimed
ID: 6218930
Ok, the thinking is going wrong direction.

I do not care to customize java.util. I brought it as example, I should have bring as example com.my.bla

I do not care about classes that are not loaded. The assumption is, that Package I am intersted about is loaded.

Or, if it easier task, how to get all classes loaded into VM (from classpath, perhaps)
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 7

Expert Comment

by:Sasha_Mapa
ID: 6219852
chochomhaloimed , like nachiap said, if you use your own classloader, all the classes will be loaded through it, which will allow you to monitor them.

Exorcist, I still think you're wrong, I'll try it tomorrow.
It could be that what you are seeing is something Sun put in their JVM, but I don't think it's a general restriction on JVMs, because there are many vendors that implement their own core classes, independently from Sun.

Falter, you are correct... the permissions aren't given by class names, but by the class loaders. As for your question, like I said, I think you can just load java.* classes without any problem... The thing is that when you're loading an applet, you have no control over the classpath or bootclasspath, so the default core classes will always be loaded since the bootstrap (null) classloader finds them. Anyway, I'll do some testing tomorrow to check this...

Sasha Maryanovsky.
0
 

Author Comment

by:chochomhaloimed
ID: 6219860
Sasha, show me exactly what methods, and how(code) I should extend from ClassLoader to get what I want. And you will get your 300 with an A, if this will prove working.
0
 
LVL 7

Expert Comment

by:Igor Bazarny
ID: 6220230
chochomhaloimed,

I believe that ClassLoader modification is not necessary. For standalone application you need to check entries found in system properties "java.class.path" and "sun.boot.class.path" (if I'm not mistaken) and look for .class files there which map to your package. There is no generic solution--class loader may take classes wherever it likes from, and that sources may even not support listings. Imagine classes loaded from 'blind' ftp or http location--location where directory listing is prohibited. There will be no way to find list of classes in such (hardly possible) situation.

As for java/javax namespace extensions--yes, it's security issue. I didn't look into this precise problem, but I had problems loading classes from javax namespace and security adjustments solved the problem. Probably, some twaking of package 'sealed' state is necessary.

Regards,
Igor Bazarny,
Brainbench MVP for Java 1
www.brainbench.com 
0
 
LVL 7

Accepted Solution

by:
Sasha_Mapa earned 300 total points
ID: 6220274
Here's a generic wrapper class which you can use to execute some application with a custom classloader.

import java.lang.reflect.*;
import java.io.*;

public class Wrapper{

 public static void main(String [] args) throws Exception{
   MyCustomClassLoader loader = new MyCustomClassLoader();
   Class appClass = loader.loadClass(args[0],true);
   String [] realArgs = new String[args.length-1];
   System.arraycopy(args,1,realArgs,0,realArgs.length);
   Method mainMethod = appClass.getMethod("main",new Class[]{String [].class});
   mainMethod.invoke(null,new Object[]{realArgs});
 }

}


class MyCustomClassLoader extends ClassLoader{


 private byte [] loadClassData(String name) throws IOException{
   System.out.println(name.replace('.',File.separatorChar)+".class");
   InputStream in = new FileInputStream(name.replace('.',File.separatorChar)+".class");
   ByteArrayOutputStream buf = new ByteArrayOutputStream();
   int b;
   while ((b=in.read())!=-1){
     buf.write(b);
   }
   return buf.toByteArray();
 }


public synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException{
   byte data [];
   try{
     data = loadClassData(name);
   } catch (IOException e){
       return findSystemClass(name);
     }
   Class c = defineClass(data, 0, data.length);
   if (resolve)
     resolveClass(c);
   return c;
 }

}



public class Application{

  static{
    System.out.println("Class Application loaded with "+Application.class.getClassLoader()+" classloader");
}

  public static void main(String [] args){
    System.out.println("Main invoked");
  }

}

Sasha Maryanovsky.

0
 
LVL 7

Expert Comment

by:Igor Bazarny
ID: 6220363
And here is a way to list classes loadable by default classloader:


import java.util.*;
import java.util.zip.*;
import java.io.*;

public class ListClasses{
    public static void main(String[] args){
        if( args.length == 0 ){
            System.out.println("Package name expected");
            return;
        }
        String pkg = args[0];
        ListClasses lister = new ListClasses(pkg);
        lister.list("sun.boot.class.path");
        lister.list("java.class.path");
    }

    private Hashtable listed = new Hashtable();
    private String packageName;

    ListClasses(String pkg){
        packageName = pkg;
    }

    void list(String propertyName){
        String path = System.getProperty(propertyName);
        if(path == null){
            System.out.println(propertyName);
            return;
        }
        for( StringTokenizer entryEnum = new StringTokenizer(path,File.pathSeparator);
             entryEnum.hasMoreTokens();   )
        {
             listEntry(entryEnum.nextToken());
        }
    }

    void listEntry(String entryName){
        File entryFile = new File(entryName);
        if( !entryFile.exists() ){
            return;
        }
        if( entryFile.isDirectory() ){
            listDirectory(entryFile);
        }
        else{
            listArchive(entryFile);
        }
    }

    void listDirectory(File root){
        String relativePath = packageName.replace('.', File.separatorChar);
        File packageDir = new File(root, relativePath);
        if( !packageDir.exists() || !packageDir.isDirectory() ){
            return;
        }
        String[] files=packageDir.list();
        for( int i=0; i<files.length; ++i){
            if( files[i].endsWith(".class")
                && !(new File(packageDir,files[i]).isDirectory()))
            {
                String className
                   = files[i].substring(0,files[i].length()-".class".length());
                if(listed.get(className) == null){
                    System.out.println(className);
                    listed.put(className,className);
                }
            }
        }
    }

    void listArchive(File archive){
        try{
            ZipFile zipFile = new ZipFile(archive);
            String relPath = packageName.replace('.','/')+"/";
            int pathLen = relPath.length();
            for( Enumeration entryEnum = zipFile.entries();
                 entryEnum.hasMoreElements(); )
            {
                ZipEntry entry = (ZipEntry)entryEnum.nextElement();
                String entryName = entry.getName();
                if( entryName.startsWith(relPath)
                    && entryName.length() > pathLen
                    && entryName.indexOf("/",pathLen) < 0
                    && entryName.endsWith(".class") )
                {
                    String className
                       = entryName.substring(pathLen,entryName.length()-".class".length());
                    if(listed.get(className) == null){
                        System.out.println(className);
                        listed.put(className,className);
                    }
                }
            }
        }
        catch(IOException ignored){
        }
    }
}
0
 
LVL 7

Expert Comment

by:Sasha_Mapa
ID: 6220563
Note that bazarny's suggestion lists all the class files loadable by the bootstrap classloader (on a Sun JVM) and my suggestion allows keeping record of the classes that were actually loaded by the JVM - not sure which you want...

Sasha Maryanovsky.
0
 
LVL 7

Expert Comment

by:Sasha_Mapa
ID: 6221180
Ok, trying to load a java.util.SomeClass class in JDK1.1 works fine. In 1.2, it throws a SecurityException if run the usual way - if run using "java -Xbootclasspath/p:. Test" then also runs fine. I suspect this is because of the "sealing packages" functionality added in JDK1.2 - it's possible to package a JAR file in such a manner that any children classloaders of the classloader that loaded that jar aren't allowed to define classes in any of the packages defined by classes in that jar. Since this is exactly the case with rt.jar, you can't load a java.* class the usual way, but if you prepend (or even append, what matters is that the bootstrap classloader is asked to load it) its location to the bootclasspath, then it works fine.

Sasha Maryanovsky.
0
 
LVL 7

Expert Comment

by:Igor Bazarny
ID: 6224786
Hi,

Isn't security issues are offtopic for this question?
When we ran into similar problem with classes from javax.<something> package (we got NoClassDefFoundError though), I where able to load that class:
- from bootclasspath without security modifications
- from .jar in jre/lib/ext dir without security modifications
- from classpath with AllPermission granted to anyone.
And we dicided to use -bootclasspath to load those classes.

Regards,
Igor Bazarny

PS. chochomhaloimed, are you satisfied with answers? Do you
need some more information? Or you can grant points?
0
 

Author Comment

by:chochomhaloimed
ID: 6224819
I was away plus the server was down, so I just got the chance to review the answers. I will act shortly
0
 

Author Comment

by:chochomhaloimed
ID: 6229490
Both solutions have its advantages and disadvantages, and both are legitamate answers for my question. Do you know if it is possible to accept two comments as an answer?
0
 
LVL 7

Expert Comment

by:Igor Bazarny
ID: 6229600
Hi,

> Do you know if it is possible to accept two comments as an answer?
For one question-no.
Typically it's done by submitting dummy question for one of experts and awarding points to another. You can't decrease points yourself to 'split' amout though. Contact EE support--they help to resolve such situations.
0
 

Author Comment

by:chochomhaloimed
ID: 6229627
bazarny, i had posted for you a dummy question : dummy for bazarny
0
 
LVL 7

Expert Comment

by:Sasha_Mapa
ID: 6230333
Thanks for the points (and the grade)...

Sasha Maryanovsky.
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Responding to Java JComponent extended classes's resize event 4 50
Base1 Encode/Decode 3 67
oracle 11g 23 47
arguments to jar 5 10
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
This theoretical tutorial explains exceptions, reasons for exceptions, different categories of exception and exception hierarchy.
This tutorial will introduce the viewer to VisualVM for the Java platform application. This video explains an example program and covers the Overview, Monitor, and Heap Dump tabs.

919 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

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now