Solved

Classes of Package

Posted on 2001-06-21
25
356 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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
Sorry,

stupid browsers let me submit the comment twice
0
 
LVL 3

Expert Comment

by:falter
Comment Utility
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
Comment Utility
nope.
0
 
LVL 3

Expert Comment

by:falter
Comment Utility
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
Comment Utility
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
Comment Utility
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
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 7

Expert Comment

by:Sasha_Mapa
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
bazarny, i had posted for you a dummy question : dummy for bazarny
0
 
LVL 7

Expert Comment

by:Sasha_Mapa
Comment Utility
Thanks for the points (and the grade)...

Sasha Maryanovsky.
0

Featured Post

What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

Join & Write a Comment

Suggested Solutions

For beginner Java programmers or at least those new to the Eclipse IDE, the following tutorial will show some (four) ways in which you can import your Java projects to your Eclipse workbench. Introduction While learning Java can be done with…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
Video by: Michael
Viewers learn about how to reduce the potential repetitiveness of coding in main by developing methods to perform specific tasks for their program. Additionally, objects are introduced for the purpose of learning how to call methods in Java. Define …
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.

762 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

11 Experts available now in Live!

Get 1:1 Help Now