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