chochomhaloimed
asked on
Classes of Package
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.
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.
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
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
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.
Sasha Maryanovsky.
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("workin g");
}
}
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?
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("workin
}
}
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?
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
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
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
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
Sorry,
stupid browsers let me submit the comment twice
stupid browsers let me submit the comment twice
Sasha,
isn't it possible to setup something in a policy file
to allow the use of restricted package names ?
isn't it possible to setup something in a policy file
to allow the use of restricted package names ?
nope.
Sasha,
isn't it possible to setup something in a policy file
to allow the use of restricted package names ?
isn't it possible to setup something in a policy file
to allow the use of restricted package names ?
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.
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.
ASKER
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)
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)
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.
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.
ASKER
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.
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
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
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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("Packag e name expected");
return;
}
String pkg = args[0];
ListClasses lister = new ListClasses(pkg);
lister.list("sun.boot.clas s.path");
lister.list("java.class.pa th");
}
private Hashtable listed = new Hashtable();
private String packageName;
ListClasses(String pkg){
packageName = pkg;
}
void list(String propertyName){
String path = System.getProperty(propert yName);
if(path == null){
System.out.println(propert yName);
return;
}
for( StringTokenizer entryEnum = new StringTokenizer(path,File. pathSepara tor);
entryEnum.hasMoreTokens(); )
{
listEntry(entryEnum.nextTo ken());
}
}
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]). isDirector y()))
{
String className
= files[i].substring(0,files [i].length ()-".class ".length() );
if(listed.get(className) == null){
System.out.println(classNa me);
listed.put(className,class Name);
}
}
}
}
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.nextEl ement();
String entryName = entry.getName();
if( entryName.startsWith(relPa th)
&& entryName.length() > pathLen
&& entryName.indexOf("/",path Len) < 0
&& entryName.endsWith(".class ") )
{
String className
= entryName.substring(pathLe n,entryNam e.length() -".class". length());
if(listed.get(className) == null){
System.out.println(classNa me);
listed.put(className,class Name);
}
}
}
}
catch(IOException ignored){
}
}
}
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("Packag
return;
}
String pkg = args[0];
ListClasses lister = new ListClasses(pkg);
lister.list("sun.boot.clas
lister.list("java.class.pa
}
private Hashtable listed = new Hashtable();
private String packageName;
ListClasses(String pkg){
packageName = pkg;
}
void list(String propertyName){
String path = System.getProperty(propert
if(path == null){
System.out.println(propert
return;
}
for( StringTokenizer entryEnum = new StringTokenizer(path,File.
entryEnum.hasMoreTokens();
{
listEntry(entryEnum.nextTo
}
}
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]).
{
String className
= files[i].substring(0,files
if(listed.get(className) == null){
System.out.println(classNa
listed.put(className,class
}
}
}
}
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.nextEl
String entryName = entry.getName();
if( entryName.startsWith(relPa
&& entryName.length() > pathLen
&& entryName.indexOf("/",path
&& entryName.endsWith(".class
{
String className
= entryName.substring(pathLe
if(listed.get(className) == null){
System.out.println(classNa
listed.put(className,class
}
}
}
}
catch(IOException ignored){
}
}
}
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.
Sasha Maryanovsky.
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.
Sasha Maryanovsky.
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?
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?
ASKER
I was away plus the server was down, so I just got the chance to review the answers. I will act shortly
ASKER
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?
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.
> 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.
ASKER
bazarny, i had posted for you a dummy question : dummy for bazarny
Thanks for the points (and the grade)...
Sasha Maryanovsky.
Sasha Maryanovsky.
you have to over write loadClass() method..