You may just have to brute force it if you continue down this road. To my knowledge the default class loader will not even load a class into the JVM unless it is referenced somehow. Which means, some of your classes will be basically invisible unless you know their fully qualified class name to load them.
You may just have to brute force it if you continue down this road. To my knowledge the default class loader will not even load a class into the JVM unless it is referenced somehow. Which means, some of your classes will be basically invisible unless you know their fully qualified class name to load them.
You may want to reconsider your requirements. As it would be far easier to load a set of Translators that you have been given the class names for.
I am considering moving some of this off to a config file that would require explicit names, or at least the name of the package containing the translator classes. Its a better approach, I just want to make sure the the other option can't be implemented cleanly first. – jdc0589 Feb 17 at 0:14 @jdc0589 There are solutions for jars and local files, but AFAIK not a generic one for any kind of classloader.
– biziclop 9 Feb at 0:18 care to elaborate? I am only concerned with local files and local jars – jdc0589 Feb 17 at 3:45 Changed the format of my input files to require explicit definition of translator classes. Definitely the best option.
– jdc0589 Feb 26 at 1:24.
This may fit the bill. If not, you ought to be able to look through their source to get an idea of what will work for you. code.google.com/p/reflections.
– jdc0589 Feb 17 at 0:42 I just saw a reference to it earlier in the day and then stumbled on your question so thought I would pass it along. I've never used it, but thought if nothing else, you could look through the source and see what they are doing. – digitaljoel Feb 17 at 16:00.
In principle this can't work for arbitrary classloaders, as they may use any way imaginable to actually load the classes, and not have any "directory listening" function at all. A classloader might even generate classes (i.e. The bytecode for the classes) on the fly whenever a loadClass comes, and imagine a TransableClassloader where each such automatically defined class would implement your interface - your program would never end.
That said, for an URLClassloader you can use getURLs(), and for the jar: and file: URL you can use the JarFile or File api to get the list of filenames (and thus Classnames) to try. As you have the root of your package hierarchy given in the URL, finding the right package name is not difficult, too. (If you need more details, say it.) Edit: For the package names, they correspond to the directory names inside of your hierarchy.
So, when you have a base URL which corresponds to (say) dir/classes, and find a class-file named dir/classes/com/company/gui/SimpleTranslator. Class, it corresponds to class com.company.gui. SimpleTranslator.
So, remove the base prefix and replace / by . (and cut of the . Class).
(In a JarFile you don't have to cut a prefix off. ) Actually, if you use a recursive method to traverse your File hierarchy, you can build up your package-name with the same method, simply by appending Strings (give them as a parameter to the next recursive Invocation): public void searchClassesInDir(File dir, String packagePrefix) { if(dir.isDirectory()) { String prefix = packagePrefix + dir.getName() + "."; for(File f : dir.listFiles()) { searchClasses(f, prefix); } } else { String fileName = dir.getName(); if(! fileName. EndsWith(".
Class")) return; String className = packagePrefix + fileName. Substring(0, fileName.length()-". Class".length()); // now do the rest of your processing } } searchClasses(new File(url.toURI()), "").
I think this is the path I will take. I know how to do everything aside from determining package names. The only method I can think of is to just get the path of the class entry in the jar file, replace the file separators with a '.' and chop the '.
Class' off the end. There another way? – jdc0589 Feb 17 at 0:59 I added an example here.
But chopping off the '. Class' and converting '/' to '.' works too. – PaÅlo Ebermann Feb 17 at 1:16 You can also add your filter to the listFiles() call, but make sure it catches subdirectories, too (or in a second loop).
For a jar file this works similar, I think, you just need to traverse the JarEntrys (and don't need recursion, instead the replacement). – PaÅlo Ebermann Feb 17 at 1:21.
Instead of trying to search for these yourself, you should instead take a look at using Java's Service Provider Interface (SPI) and the newly public (as of Java 6) ServiceLoader class. SPI is a pretty much a standard way to do what you are describing in Java. This article does a nice job summing up how to use SPI, and also discusses how to use it for runtime discovery of new implementation providers.
Sounds awesome, will take a look asap. Thanks – jdc0589 Feb 17 at 2:59 A little confused here. Maybe I just havent found it yet..but it seems like this only returns the default implementations defined in my META-INF/services/org.jextend.
Transable file? At least thats all I can get it to do now, even though I constructed the ServiceLoader with class loader argument that has access to other implementations. – jdc0589 Feb 17 at 3:35 Found this text in the link you posted:"Also, the current ServiceLoader class can't tell your application when new providers are available at runtime."
Whats the deal? – jdc0589 Feb 17 at 3:42 There could be multiple META-INF/services/org.jextend. Transable files in different root directories or jar files found by your classloader(s).
There is also a tool to help you create those files during build: code.google. Com/p/spi/wiki/GettingStarted – hd42 Feb 17 at 6:34 The deal with not discovering new providers during runtime is that the ServiceLoader will look for and parse the service description files during startup, so when you put a new file and service implementation class in your classpath while your program is running, it won't be picked up right away but only after you restart your program. – hd42 Feb 17 at 6:37.
Since Class c = cl. LoadClass(name); Class method getInterfaces() returns an array of classes Check each class name for match to translator class name.
That is not really the issue. Thanks though – jdc0589 Feb 17 at 0:42.
Just go in the jar file and check all entries.
I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.