Path: csiph.com!x330-a1.tempe.blueboxinc.net!usenet.pasdenom.info!aioe.org!.POSTED!not-for-mail From: Novice Newsgroups: comp.lang.java.programmer Subject: Re: Resource confusion Date: Sun, 29 Jan 2012 05:40:02 +0000 (UTC) Organization: Your Company Lines: 109 Message-ID: References: NNTP-Posting-Host: /kSec8Zpu/mSG50nCPQbWQ.user.speranza.aioe.org X-Complaints-To: abuse@aioe.org User-Agent: Xnews/5.04.25 X-Antivirus-Status: Clean X-Notice: Filtered by postfilter v. 0.8.2 X-Antivirus: avast! (VPS 120128-0, 2012-01-28), Outbound message Xref: x330-a1.tempe.blueboxinc.net comp.lang.java.programmer:11629 Arved Sandstrom wrote in news:UeYUq.127$V94.98@newsfe21.iad: > On 12-01-28 01:47 PM, Novice wrote: > [ SNIP ] > >> String phraseListStartPoint = this.userPrefs.get >> (PHRASE_LIST_STARTPOINT_KEY, PHRASE_LIST_STARTPOINT_VALUE); >> URL phraseListURL = >> this.getClass().getResource(phraseListStartPoint); > [ ... ] >> >> File startPoint = null; >> if (decodedFileName != null) startPoint = new File(decodedFileName); >> else startPoint = new File(System.getProperty("user.home")); >> >> /* Launch the file chooser, open the file, read it..... */ >> ====================================================================== >> === >> >> >> This code inevitably reveals that phraseListURL is null, even though >> the value of PHRASE_LIST_STARTPOINT_VALUE is a path found on my file >> system such as C:\Games\PhraseLists. >> >> Clearly, this.getClass().getResource(phraseListStartPoint) is failing >> to work as I would like. >> >> I've tried reading the API on the getResource() method of the Class >> class but I'm not following it. I know nothing about class loaders or >> which one is the right one to use when. I'm not even sure I should be >> using an approach like this to access a file that is in the file >> system. > [ SNIP ] > > If you're going to use .getResource(), the String "name" that you > supply is actually a '/'-separated path name that identifies something > on a classloader classpath. You have a number of classloaders involved > every time you run your app; fact is that your phrase-list file (even > if you had a '/'-separated path spec for it) very likely isn't on the > classpath for any of those classloaders. > > It doesn't sound to me like you need either the getResource() or > getResourceAsStream() approaches (which are available through > ClassLoader or delegated from Class); you might be better off saving > and using file URLs. > > The exact form of a file URL varies across systems but they all have > the file: scheme. On a UNIX system > > URL phraseListUrl = new URL("file:///home/me/Games/PhraseLists"); > > would work, but off the top of my head on a Windows box it's something > like > > URL phraseListUrl = new URL("file:///C:/Games/PhraseLists"); > > This is just informational, because your app doesn't have to construct > these things, just save them. Your user does the heavy lifting by > selecting the location with a file chooser; that gives you a File > object. You can save out the result with > > userSelectedFile.toURI().toURL().toString() Thanks, Arved, that was VERY helpful. First, I tried just hard-coding the path with the "file:/" (only needed one forward slash, not all three, although I've seen three used on other occasions) and that worked fine. Then I tried your trick with adding the .toURI().toURL() (I found I didn't need the final toString()) and that also worked very well. I haven't tried it outside of Eclipse yet but if it works as well from Java Web Start and on an OS other than Windows, I should be golden. > > To return to getResource() or getResourceAsStream(), and classloaders: > the situation is more complicated in Java application server > environments [1], and for this reason context classloaders were made > available as (imperfect) solutions. But you are not in that scenario. > > I'll also add that *if* it made sense for you to have a file resource > on the classpath, and you were using getResource() or > getResourceAsStream(), it doesn't make sense for you to pose the > question "which classloader should I use?" That's not *your* decision > to make, per se - you can influence that choice by where you place the > resource, but you don't directly select a classloader (again, unless > you were in a server environment and using a context classloader). > In all honesty, I have never seriously looked at classloaders and have no real idea why there are all various different ones and when I should be trying to use one programmatically. I basically had troubles reading a file from my file system some time ago, googled, and found a post with an example indicating that toClass().toResource() was a good idea. (A specific mention of classLoader may have been in there too.) I never really understood the issue properly but that code got me out of trouble for the original situation and I've imitated it several times without really understanding it. Learning more about these classloaders is on my To Do list; maybe I need to move it up the list ;-) > AHS > > 1. As anyone can attest who has spent quality hours wrestling with a > situation where instance 1 of class X hasn't the same class as > instance 2 of class X...for various reasons. Thanks again Arved! I think I'm out of trouble now.... -- Novice