home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 21 / IOPROG_21.ISO / SOFT / JDK / JD117DOC.ZIP / jdk1.1.7A / docs / guide / misc / resources.html < prev   
Encoding:
C/C++ Source or Header  |  1998-04-15  |  17.3 KB  |  480 lines

  1. <html>
  2. <head>
  3. <title>Accessing Resources</title>
  4. </head>
  5.  
  6. <BODY BGCOLOR="#FFFFFF" TEXT=#000000 LINK=#0000ff VLINK=#000077 ALINK=#ff0000>
  7. <CENTER><P ALIGN=LEFT>
  8. <IMG SRC="../../images/smi.logo.gif" ALT=" Sun Microsystems, Inc " BORDER=0>
  9. </P></CENTER>
  10.  
  11.  
  12. <font size=-1><a href="../../index.html">JDK Contents</a></font>
  13. <HR SIZE=3 NOSHADE>
  14. <!-- +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
  15. <center>
  16.      <H1>Accessing Resources in a Location-Independent Manner</H1>
  17. </center>
  18.  
  19. <H2>Motivation</H2>
  20.  
  21. Applets, Beans, Applications, and Libraries often have resource files associated with them. These Applets, Beans, and so on, want to use these files  in a way that is independent of where these Applets, et al., are located. 
  22.  
  23. <P> Existing code in JDK1.0.x uses two types of mechanisms.  The first
  24. mechanism is used in applets. <EM>Applet.getCodeBase()</EM> returns a
  25. URL to the base of the code for the applet.  This base can be
  26. extended with a "relative path" to point to the desired resource, which
  27. can then be loaded (for example using
  28. <EM>Applet.getAudioClip(url)</EM>).
  29. The second mechanism is used by applications.  Applications use
  30. "well known locations" (such as <EM>System.getProperty("user.home")</EM>
  31. or <EM>System.getProperty("java.home"))</EM>.  They add "/lib/<resource>" to the location and then open that file.
  32.  
  33. <P> Until now, JDK1.0.x has not had a mechanism to locate resources that are
  34. independent of the code.  That is, JDK1.0.x. has not had the means to locate resources for an applet loaded from the net using
  35. multiple http connects, or for an applet loaded using JAR files, or for a Bean
  36. loaded or a Bean installed in the CLASSPATH, or for a "library" installed in
  37. the CLASSPATH, and so on.  The APIs described here provide such a mechanism.
  38.  
  39. <P> The I18N APIs use this API as a primitive operation to locate
  40. <EM>ResourceBundle</EM>s.  See the latest I18N documentation for details.
  41.  
  42. <H2>Resources, names, and contexts</H2>
  43.  
  44. <P>A resource is identified by a String.  This String, while possibly empty, is a <B>/</B>-separated sequence of substrings, each a valid Java<font size="-2"><sup>TM</sup></font> 
  45. Identifier, followed by a name of the form "<shortName>" or
  46. "<shortName>.<extension>".  Both "shortName" and
  47. "extension" are composed of valid Java Letters and Numbers (section
  48. 3.8 in JLS).  If the optional sequence exists, it is separated from
  49. the "shortName" by a <B>/</B>.
  50.  
  51. <P>The name of a resource is independent of the Java implementation;
  52. in particular, the <B>/</B> is always used as a separator.
  53. However, the Java implementation controls the details of how the
  54. contents of the resource are mapped into a file, database, or other
  55. object containing the actual resource.
  56.  
  57. <P>The interpretation of a resource name is relative to a ClassLoader
  58. instance.  Methods implemented by the ClassLoader do this interpretation.
  59.  
  60. <H2>System Resources</H2>
  61.  
  62. <P>A system resource is similar to a system class (section 20.14.5 of
  63. the JLS).  A system resource is a resource that is either built-in to the system, or it is kept by the host implementation in, for example, a local
  64. file system.  System resources are accessed through special
  65. methods (<EM>getSystemResource</EM> and
  66. <EM>getSystemResourceAsStream</EM>) that consult the base
  67. host implementation.
  68.  
  69. <P>For example, in a particular implementation, locating a system
  70. resource may involve searching the entries in the CLASSPATH. 
  71. Each directory, zip file, or jar file entry in the CLASSPATH is searched for the resource file, and, if found, either an InputStream, or its name,
  72. is returned.
  73. If not found, null is returned.  Note that a resource may be found in
  74. a different entry in the CLASSPATH than where the class file was loaded.
  75.  
  76. <H2>Non-System Resources</H2>
  77.  
  78. The implementation of <EM>getResource</EM> on a given <EM>ClassLoader</EM>
  79. will depend on the details of the ClassLoader.  For example AppletClassLoader
  80. will:
  81.  
  82. <UL>
  83. <LI>First try to locate the resource as a system resource; then, if not found,
  84.  
  85. <LI>Search through the resources in ARCHIVES (JAR files) already
  86. loaded in this CODEBASE; then, if not found,
  87.  
  88. <LI>Use CODEBASE and attempt to locate the resource (which may involve
  89. contacting a remote site).
  90. </UL>
  91.  
  92. <P> All ClassLoaders will search for a resource first as a system 
  93. resource, in a manner analogous to searcing for class files.  This 
  94. search rule permits overwriting locally any resource.  Clients should 
  95. choose a resource name that will be unique (using the company or package 
  96. name as a prefix, for instance).
  97.  
  98. <H2>Resource Names</H2>
  99.  
  100. <P> A common convention for the name of a resource used by a class is
  101. to use the fully qualified name of the package of the class, convert
  102. all "." to "/", and add a resource name of the form "<Name>.<ext>".
  103. To support this, and to simplify handling the details of system
  104. classes (for which <EM>getClassLoader</EM> returns <B>null</B>),
  105. the class Class provides two convenience methods that call the
  106. appropriate methods in <EM>ClassLoader</EM>.
  107.  
  108. <P> The resource name given to a Class method may have an initial
  109. starting "/" that identifies it as an "absolute" name.
  110. Resource names that do not start with a "/" are "relative".
  111.  
  112. <P>Absolute names are stripped of their starting "/" and are passed,
  113. without any further modification, to the appropriate ClassLoader
  114. method to locate the resource.
  115. Relative names are modified according to the convention described
  116. previously and then are passed to a ClassLoader method.
  117.  
  118. <H2>Manipulating Resources</H2>
  119.  
  120. <P> The method <EM>getResource()</EM> returns a URL for the resource.
  121. The URL (and its representation) is implementation and JVM-instance 
  122. specific (the URL obtained in one JVM instance may not work in 
  123. another) and may vary depending on the implementation details (it may 
  124. also change between JDK1.1 and JDK1.1.1).
  125. Its protocol is (usually) specific to the ClassLoader loading the resource.
  126. If the resource does not exist, a null will be returned; if the resource 
  127. is not visible due to security considerations, a null will also be 
  128. returned.
  129.  
  130. <P> If the client code wants to read the contents of the resource
  131. as an InputStream, it can apply the <EM>openStream()</EM> method on
  132. the url.  This is common enough to justify adding
  133. <EM>getResourceAsStream()</EM> to Class and ClassLoader. 
  134. <em>getResourceAsStream()</em> is semantically identical to 
  135. <em>getResource().openStream()</em>, except that IO exceptions are 
  136. caught and returned as a null <em>InputStream</em>.
  137.  
  138. <P> The client code code can also request the contents of the
  139. resource as an object by applying the <EM>getContent()</EM> method
  140. on the url.  This is useful when the resource contains the data
  141. for an image, for instance. Note that in this case, the result is 
  142. an <em>awt.image.ImageProducer</em> object, not an <em>Image</em> object.
  143.  
  144. <H2>API Additions to Class</H2>
  145.  
  146. <P>Specifically, the class <EM>Class</EM> methods are of the following
  147. form:
  148.  
  149. <PRE>
  150. <CODE>
  151. class Class {
  152.  
  153.     /**
  154.      * Find a resource with a given name.  Will return null if no
  155.      * resource with this name is found.  The rules for searching a
  156.      * resources associated with a given class are implemented by the
  157.      * ClassLoader of the class.
  158.      *
  159.      * The Class methods delegate to ClassLoader methods, after applying
  160.      * a naming convention: if the resource name starts with "/", it is used
  161.      * as is.  Otherwise, the name of the package is prepended, after
  162.      * converting "." to "/".
  163.      *
  164.      * @see java.lang.ClassLoader
  165.      */
  166.     public InputStream getResourceAsStream(String name) {
  167.     name = resolveName(name);
  168.     ClassLoader cl = getClassLoader();
  169.     if (cl==null) {
  170.         // A system class.
  171.         return ClassLoader.getSystemResourceAsStream(name);
  172.     }
  173.     return cl.getResourceAsStream(name);
  174.     }
  175.  
  176.     public java.net.URL getResource(String name) {
  177.     name = resolveName(name);
  178.     ClassLoader cl = getClassLoader();
  179.     if (cl==null) {
  180.         // A system class.
  181.         return ClassLoader.getSystemResource(name);
  182.     }
  183.     return cl.getResource(name);
  184.     }
  185.  
  186.     /**
  187.      * Add a package name prefix if the name is not absolute
  188.      * Remove leading "/" if name is absolute
  189.      */
  190.     private String resolveName(String name) {
  191.     if (name == null) {
  192.         return name;
  193.     }
  194.     if (!name.startsWith("/")) {
  195.         Class c = this;
  196.         while (c.isArray()) {
  197.         c = c.getComponentType();
  198.         }
  199.         String baseName = c.getName();
  200.         int index = baseName.lastIndexOf('.');
  201.         if (index != -1) {
  202.         name = baseName.substring(0, index).replace('.', '/')
  203.             +"/"+name;
  204.         }
  205.     } else {
  206.         name = name.substring(1);
  207.     }
  208.     return name;
  209.     }
  210.  
  211.  
  212. </CODE>
  213. </PRE>
  214.  
  215. <P> Note that it is possible, albeit somewhat uncommon, to have two
  216. classes in two diffent packages sharing the same resource.
  217.  
  218. <H2>API Additions to ClassLoader</H2>
  219.  
  220. <P> We provide two sets of methods to access a resource. One set returns
  221. an InputStream on the resource.  The other set returns a URL. 
  222. The methods that return an 
  223. InputStream are somewhat easier to use and will
  224. satisfy many needs, while the methods that return URLs provide
  225. access to more complex information, such as an Image and an AudioClip.
  226.  
  227. <P>Resources are managed through ClassLoaders in a manner analogous
  228. to classes.  A ClassLoader controls how to map the name of
  229. a resource to its content.  ClassLoader also provides methods for
  230. accessing <EM>system resources</EM>, analogous to the <EM>system
  231. classes</EM> (and which have no ClassLoader in JDK1.0.x and JDK1.1).
  232. Class Class provides some convenience methods that delegate functionality
  233. to the appropriate ClassLoader methods.
  234.  
  235. <P>Many Java programs will access these methods indirectly through the
  236. I18N APIs.  Others will access it through methods in class Class.
  237. A few will directly invoke the ClassLoader methods.
  238.  
  239. <P>The methods in ClassLoader use the given String as the name of the
  240. resource without applying any absolute/relative transformation
  241. (cf. the methods in Class).
  242. The name should not have a leading "/".
  243.  
  244. <PRE>
  245. <CODE>
  246. class ClassLoader {
  247.  
  248.     /**
  249.      * A resource is some data (images, audio, text, etc) that wants to be
  250.      * accessed by some class code in a way that is independent of the
  251.      * location of the code.  Resources are found with cooperation of the
  252.      * class loaders, since they are the only ones who know where the class
  253.      * actually came from. <p>
  254.      *
  255.      * System resources are those that are handled by the host implemenation
  256.      * directly.  For example, they may be located in the CLASSPATH.<p>
  257.      *
  258.      * The name of a resource is a "/"-separated sequence of identifiers.
  259.      * The class Class provides convenience methods for accessing resources;
  260.      * the methods implement a convention where the package name is prefixed
  261.      * to the short name of the resource.<p>
  262.      * 
  263.      * Resources can be accessed as an InputStream, or as a URL.
  264.      *
  265.      * @see    Class
  266.      */
  267.  
  268.     /**
  269.      * Get an InputStream on a given resource..  Will return null if no
  270.      * resource with this name is found. <p>
  271.      *
  272.      * The resource name may be any system resource (e.g. follows CLASSPATH order)
  273.      * @param    name    the name of the resource, to be used as is.
  274.      * @return        an InputStream on the resource, or null if not found.
  275.      */
  276.  
  277.     public static final InputStream getSystemResourceAsStream(String name) {
  278.     ... this is equivalent to getSystemResource() call plus a openStream()
  279.     }
  280.  
  281.     /**
  282.      * Find a resource with a given name.  The return is a URL to the resource
  283.      * Doing a getContent() on the URL may return an ImageProducer, an AudioClip, or
  284.      * an InputStream.<p>
  285.      *
  286.      * The resource name may be any system resource (e.g. follows CLASSPATH order)
  287.      * @param    name    the name of the resource, to be used as is.
  288.      * @return        the URL on the resource, or null if not found.
  289.      */
  290.     public static final java.net.URL getSystemResource(String name) {
  291.     ...
  292.     }
  293.  
  294.     /**
  295.      */
  296.  
  297.     /**
  298.      * Get an InputStream on a given resource.  Will return null if no
  299.      * resource with this name is found. <p>
  300.      *
  301.      * The class loader can choose what to do to locate the resource.
  302.      * @param    name    the name of the resource, to be used as is.
  303.      * @return        an InputStream on the resource, or null if not found.
  304.      */
  305.     public InputStream getResourceAsStream(String name) {
  306.     return null;
  307.     }
  308.  
  309.     /**
  310.      * Find a resource with a given name.  The return is a URL to the resource.
  311.      * Doing a getContent() on the URL may return an ImageProducer, an AudioClip,
  312.      * or an InputStream.<p>
  313.      *
  314.      * The class loader can choose what to do to locate the resource.
  315.      * @param    name    the name of the resource, to be used as is.
  316.      * @return        an InputStream on the resource, or null if not found.
  317.      */
  318.     public java.net.URL getResource(String name) {
  319.     return null;
  320.     }
  321.  
  322.     }
  323. </CODE>
  324. </PRE>
  325.  
  326. <H2>Client code</H2>
  327.  
  328. <P>Below are two examples of client code.  The first example uses "absolute
  329. resource" names and traditional mechanisms to get a class Class
  330. object:
  331.  
  332. <PRE>
  333. <CODE>
  334. package pkg;
  335.  
  336. import java.io.IOException;
  337. import java.io.InputStream;
  338. import java.io.PrintStream;
  339.  
  340. class Test {
  341.  
  342.     private static final String absName = "/pkg/mumble.baf";
  343.  
  344.     public static void test1() {
  345.     Class c=null;
  346.     try {
  347.         c = Class.forName("pkg.Test");
  348.     } catch (Exception ex) {
  349.         // This should not happen.
  350.     }
  351.     InputStream s = c.getResourceAsStream(absName);
  352.     // do something with it.
  353.     }
  354.  
  355.     public void test2() {
  356.     InputStream s = this.getClass().getResourceAsStream(absName);
  357.     // do something with it.
  358.     }
  359.  
  360. </CODE>
  361. </PRE>
  362.  
  363. <P>The second example uses "relative resource" names and the new
  364. mechanism, available from the compiler through the -experimental flag,
  365. to get a class Class object:
  366.  
  367. <PRE>
  368. <CODE>
  369. package pkg;
  370.  
  371. import java.io.IOException;
  372. import java.io.InputStream;
  373. import java.io.PrintStream;
  374.  
  375. class Test {
  376.  
  377.     private static final String relName = "mumble.baf";
  378.  
  379.     public static void test1() {
  380.     InputStream s = Test.class.getResourceAsStream(relName);
  381.     // do something with it.
  382.     }
  383.  
  384.     public void test2() {
  385.     InputStream s = Test.class.getResourceAsStream(relName);
  386.     // do something with it.
  387.     }
  388.  
  389. </CODE>
  390. </PRE>
  391.  
  392. <h2>Security Details</h2>
  393.  
  394. Since <em>getResource()</em> provides access to information, it must have well
  395. defined and well founded security rules that at the same time support
  396. the intended use of this mechanism.  Below we describe the exact
  397. details, as specified and implemented in releases starting at version 
  398. 1.1.5 of the Java Development Kit.  The semantics are described only for 
  399. <em>ClassLoader.getResource</em> 
  400. and <em>ClassLoader.getSystemResource()</em> and extend to the 
  401. <em>AsStream</em> methods as defined in the previous section.
  402. <p>
  403. If security considerations do not allow a resource to be visible in
  404. some security context, the <em>getResource()</em> method will fail (will 
  405. return null) as if the resource was not present at all, this addresses
  406. existence attacks.
  407. <p>
  408. All classloaders will not provide access to the contents of a
  409. .class file.  This is for both security and performance issues.
  410. Whether it is possible to obtain a URL into a .class file depends
  411. on the specifics, as shown below.
  412. <p>
  413. There are no specified security issues or restrictions regarding
  414. resources that are found by a non-system class loader.
  415. <em>AppletClassLoader</em> provides access to information that is loaded from
  416. some source location, either individually, or in a group through a JAR
  417. file; thus <em>AppletClassLoader</em> should apply the same 
  418. <em>checkConnect()</em> rules when dealing with URLs through 
  419. <em>getResource()</em>.
  420. <p>
  421. The system Class Loader provides access to information in the
  422. CLASSPATH.  A CLASSPATH may have directories and/or JAR files.  Since
  423. a JAR file is created intentionally, we ascribe a different
  424. significance to it than in a directory where things may end up in a
  425. more casual manner.  In particular, we are more strict on getting
  426. information out of a directory than out from a JAR file.
  427. <p>
  428. If the resource is in a Directory:
  429.   <ul>
  430.    <li><em>getResource()</em> invocations will use 
  431.     <em>File.exists()</em> to determine whether
  432.     to make the corresponding file visible to the user.  Recall that 
  433.     <em>File.exists()</em> uses the 
  434.     <em>checkRead()</em> method in the security manager.
  435.  
  436.    <li>the same applies to <em>getResourceAsStream()</em>.
  437.   </ul>
  438. <p>
  439. If the resource is in a JAR file:
  440.   <ul>
  441.    <li><em>getResource()</em> invocations will succeed for all files, 
  442.     regardless of whether the invocation is done from within a System or 
  443.     a non-System class.
  444.  
  445.    <li><em>getResourceAsStream()</em> invocations will succeed for non 
  446.      .class resources, and so will for <em>getContent()</em> on corresponding 
  447.      URLs.
  448.   </ul>
  449.  
  450.  
  451. <H2>Related Topics & Known Bugs</H2>
  452.  
  453. <P> The <EM>getResource</EM> interface does not provide
  454. specific support for locating localized resources.
  455. Localized resources are supported by the
  456. <A HREF="../intl/index.html">internationalization facilities</A>.
  457.  
  458. <P> Bugs in getResource are filed under the
  459. <A HREF="http://java.sun.com/products/jdk/1.1/knownbugs/classes_java.html">
  460. classes_java</A> subcategory.
  461. <p>
  462.  
  463. <!-- +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
  464. <HR SIZE=3 NOSHADE>
  465.  
  466. <IMG SRC="../../images/JAVA.85.GIF" ALIGN=RIGHT>
  467.  
  468. <FONT SIZE=-2>
  469. <A HREF="../../relnotes/SMICopyright.html">Copyright ©</A> 1996 Sun Microsystems, Inc., 2550 Garcia Ave., Mtn. View, CA 94043-1100 USA. All rights reserved.
  470. <br><br>
  471. <FONT SIZE=-1>
  472. Please send comments to: Eduardo Pelegrí-Llopart
  473. (<A HREF="mailto:pelegri@eng.sun.com">pelegri@eng.sun.com</A>).
  474. Last update November 29th, 1994.
  475. </FONT>
  476.  
  477. </BODY>
  478. </HTML>
  479.  
  480.