What are Java Resources
Java resources are data files that are packaged with Java applications and libraries. These
resources are loaded at runtime either Class.getResource(String name)
, which returns a
java.net.URL
, or Class.getResourceAsStream(String name)
, which returns a java.io.InputStream
.
The getResourceAsStream()
method is normally used when a resource is expected to be available,
since it throws an IOException
if it isn't. The getResource()
method returns null if the
resource isn't present, so it's useful to test for optional resources.
Resource Names and Paths
J2ObjC locates resources by looking in the application's main bundle ([NSBundle mainBundle]
),
using the resource's relative or absolute path:
Relative Paths
The preferred method of specifying resource paths is by using relative paths. Relative paths
do not start with a forward slash ('/'). When reading a resource with a relative path, the
class's package name is modified, changing the periods ('.') in the package name to
forward slashes ('/'), then the relative path specified in the Class.getResource(String name)
or Class.getResourceAsStream(String name)
method call is appended to the package path.
For example, if an app has a foo.bar.Mumble
class, the base path for all resources relative
to classes in that package is /foo/bar
. When Mumble.class.getResource("oops/error.jpg")
is invoked, oops/error.jpg
is appended to the package's path, so its full resource path is
/foo/bar/oops/error.jpg
.
Absolute Paths
A resource can also be accessed using an absolute path by starting the resource's name with
a forward slash ('/'). Package names are ignored, so J2ObjC locates absolute paths in the
application's main bundle using the paths exactly as specified in the
Class.getResource(String name)
or Class.getResourceAsStream(String name)
references in
the application's Java sources. In the above example,
Mumble.class.getResource("/oops/error.jpg")
has a full resource
path of /oops/error.jpg
, ignoring the foo.bar
package name.
Adding Resources to an iOS App
To add resource files to an iOS app in Xcode, open the build target's Build Phases tab. Then:
- Click the + icon (under the General tab) and select New Copy Files Phase.
- Select "Resources" as the Destination (not Java Resources).
- Specify the directory for the resource(s).
- Select + and add the file(s) to its list.
Regardless of whether relative or absolute resource paths are used, each resource directory requires a separate Copy Files build phase in an Xcode build.
Example
The JreEmulation project has a "JRE JUnit Tests" app that runs that library's unit tests. Select that target's Build Phases to see several Copy Files phases, one each for every relative path used by its resources. Here, ClassTest.java loads the same resource using first an absolute path, and then a relative path. The test's resource is included using this Copy Files build phase: