accessing dirs above ClassLoader's dir

Hello.
How can I cleanly access dirs if they are above ClassLoader directory? For example:
working directory:
-classes
-org.something.Class
-models
-textures
-…

With getClassLoader().getResource() I can only get to “classes” directory, not in working directory. Putting working directory in classpath at runtime is not desired.
Thank you.

With File/FileInputStream… well, don’t do that.

-dist
–org
—something
----Class
–models
–textures
–…

or

-dist
–org
—something
----Class
–media
—models
—textures
—…

The advantage is that you can use webstart if you like.

Also depending on your situation you might try looking at:
System.getProperty(“java.class.path”)

Note this may return multiple paths, so you’ll have to parse those paths according to File.PATH_SEPARATOR or something similar.

Whether you’re interested in this depends a lot on what your situation is… (are you making a webstart app or a desktop application, for example? Do you even have permissions to spelunk around the file system?) Also I’m not sure what you mean by “cleanly accessing” the directories.

it’s not actually for me, but my friend is developing java projects and he uses this approach (to have class files in directory classes, which is top most dir that ClassLoader gets) and resources in another directories, not under classes. So he can’t use getResource() to get resources :slight_smile:
by cleanly I meant with no very complicated solutions, hackery or platform dependand stuff.

there is no clean way to archieve what he asks. either the directory layout has to be changed or the startup script has to make sure, that the root-directory of the project is the current working directory. then you can simple open a file with e.g. new FileInputStream(“models/lara.m3d”).

Using some specific directory layout for distribution just because you think it’s nicer…

Seriously… why?

If it’s in jars you have like game.jar, models.jar, music.jar… and if only the game is in a jar, you’ll have that single jar at the root and the other dirs next to it. Disabling the webstart option (which is truly great for beta-ing) just because you think some other layout is sexier is completely retarded. It’s like using wav instead of ogg, because you can type “wav” using the left hand only.

Maybe he isn’t aware that the dev and dist layouts don’t need to be identical?

I must say I agree it’s nicer… why? Becouse then all your packeges and classes don’t interfear with other directories. Like if you have:

-org
–something
—Class …
–sometthing2
–somethng2
-net
–something3
–something4
-info…
–blabla…
…a bunch of packages
-models
-textures

…so you see it’s logical to have all classes in directory named classes. This way models and textures dir don’t belong here… it’s like they are part of packages. This is only for development of course, later you’ll pack everything in a jar It doesn’t matter much. I don’t use this personally, but then again I never worked on bigger projects.
One more thing he is right about, why does java had to limit our choices anyway? Not best strategy…

Becouse then all your packeges and classes don’t interfear with other directories.

They don’t either way.

One more thing he is right about, why does java had to limit our choices anyway?

It doesn’t. If you want to access your stuff through the classpath the stuff needs to be in the classpath (obviously). That’s all.

the point is those directories don’t logically belong there, they are not packeges

and you are right, but they could have made classpath more friendly to support this (don’t ask me how exactly, I’m sure there is a simple way it could be done)

Don’t know if this was targeted at my reply. If so, I was misunderstood :wink:

IMHO resources are tied to the application anyway, so the directory structure should be:

-org
-yourorg
-appname
-resources
-models
-textures
MainClass

this way everything is allways in the apps classpath and no interferance with the default package as well.

I agree. since the classpath consists of multiple locations it’s simply impossible to resolve a directory “besides” your classes directory. If you want to work with files you still can usinf File and FileInputStream, but you are back to all the problems they have (working directory constraints, relative/absolute pathes, security concerns with webstart deployment etc.)

You can find the complete classpath with getClasspath() from the new MXBeans available statically and then switch within the path with “;” chars-array to get one available directory if you don’t want to add your own in the classpath.
then simply copy the lib files in them while you’re loading your app-stuff and eventually delete them on exit. It is then affordable to loadLibrary with the System once the files have been copied in. Maybe you’ll be asked to set the permissions on for each library you load, i.e. RuntimePermission loadLibrary yourLib .

I do like that for each one of my applications:( btw they use JAI+JIIO bin and natives depending the os.name system property)
See: getYourFiles FileArray[] --> check the classpath String for writable dir --> copy the fileArray[] one-by-one --> loadLibrary(myLib)
and check before to set up your j2 permissions with policytool though this will be logged in the console if it is needed to.

::slight_smile:

I agree, I work like this also, but I am dissapointed of lack of other solutions, like static approach we talk about here. Static means resources aren’t tied to the app itself.

Sorry, but I really don’t get it. There are plenty of options:

  • Use separate jars/directories and add them to the classpath
  • Use separate jars/directories and create a URLClassloader yourself at runtime
  • Use direct file access taking the current working directory into account (startup-script, lnk-file etc.)
  • Traverse the classpath and find the media directories yourself (hackish)

what’s missing?

again, it’s for development time, so jars are excluded. Adding directories to classpath every time you make one is also excluded. Soulution I was thinking of is programatical, if that is right word for it.
Direct access with streams seems to be only adequate solution (imho).

Well, add the upper dir to the cp and you’re done.

Yeah that would be nice!
I’ve tried to do that, but how do you do that exactly? So here’s the dir tree:

project
-classes
–something
—PathExample.class
-data
–data.dat

package something;
public class PathExample {
	public static void main(String args[]) {
		new PathExample();
	}	
	
	public PathExample() {
		java.net.URL data = this.getClass().getClassLoader().getResource("data/data.dat");
		System.out.println(data);
	}
}

so I’m in project directory. I’ve tried to use “java -cp . classes/something.PathExample” but got NoClassDefFoundError… (wrong name: something/PathExample).
I’m totally new here, never tried something like this. Can anyone tell me how to access resources in classpath? I know that getResource() starts in dir where packages are, but what for directories added to classpath?

You could either start from “project” and add “classes” to the cp. Or if you start from “classes” you would have to add “…/” (I think) to the cp. I would go for the former.

java -cp .;classes something.PathExample

data.dat would be accessed with “/data/data.dat”.

thank you, that works

but what about uniqueness? Is it up to me to preserve it? For example if I add 2 directories that contain same file by name, which one will be fetched?

I would really just use maven.