Dev/classLoading/reading

From CubeiaWiki

Jump to: navigation, search

Contents

Reading from the Class Path

As Firebase contains a custom class loader hierarchy, it is sometimes problematic to figure out where to put things that you want to read from the class path. This article will attempt to clarify the issue.

Default Locations

The system class path is setup by the script located in "bin/gameserver.sh" and apart from all the necesarry JAR:s it adds the following two directories to the system class path:

  • /conf
  • /bin

From that follows that if you place files in those directories they should be available from all class loaders. But beware, if you run Firebase in a container such as Maven or Eclipse the system class loader might not be setup correctly, more about that below.

The above two directories are global, and available to the entire server. You can of course package files with your artifacts. For example, if you build a game with Maven you can place files in "src/main/resources/" to have it appear in the game JAR file as expected. From within the game you can then read it like so:

getClass().getClassLoader().getResourceAsStream("my.file");

Note that we're using the class loader from the instance class, this ensure that you get the game class loader and nothing else. Another option is to place files in "src/main/resources/firebase". Such files will end up in the GAR itself. However, as the GAR is not on the class path in Firebase you would have to use a resource locator to read the file. This locator read directly from the root of the artifact, and you can get hold of it via the Game Context.

Beware the System Class Loader

If you're running inside a container, such as Maven or Eclipse, using the system class loader to read resources may not work, as the system is most likely to be the container's class path, and not Firebase. In other words, be careful with this...

ClassLoader.getSystemResource("my.file");

... as it may return, say, the system class loader you used to launch Maven which will not know about the Firebase files or directories. Instead, make it a habit to load from the instance class:

getClass().getClassLoader().getResourceAsStream("my.file");

Doing this gives you a broader search spectrum, the file may be located in the GAR file, or it may be in the system class loader, or even somewhere in between, you will find it irregardless.

When Running in Maven

Apart from the above issue with the system class loader, the only difference when running in Maven, ie. using mvn firebase:run, is that the root directory of the Firebase instance is also included in the class path:

  • /

If you want to include files from the build, you can use the overlay system. You do this by configuring the Firebase plugin like so:

<!-- enable copy of overlay files -->
<overlaysEnabled>true</overlaysEnabled>

<!-- copy overlay files from this directory to the firebase root -->
<overlaySourceDirectory>${basedir}/src/test/resources/firebase</overlaySourceDirectory>

Using the above, files from "src/test/resources/firebase" will be copied into the Firebase root directory when the plugin starts. So if you want to use it, and have configured it as above, files from the following three locations would be available on the class path when you're running in maven:

  • src/test/resources/firebase
  • src/test/resources/firebase/conf
  • src/test/resources/firebase/bin
Personal tools