home *** CD-ROM | disk | FTP | other *** search
/ Internet News 1999 October / INEWS_10_CD.ISO / pc / jdk / jdk1.2.2 / docs / guide / misc / resources.html < prev    next >
Encoding:
C/C++ Source or Header  |  1999-09-19  |  17.7 KB  |  515 lines

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