Here are some common classloading best practices that we have been following and hope useful to many.
- Declare dependencies. Make dependencies explicit. Hidden or unknown dependencies will be left behind when you move your application to another environment. Specify the dependencies in the Manifest Class-Path entry of EJB-JAR or WAR file on the libraries packaged in the same application.
- Group dependencies. Ensure that all dependencies are visible at the same level or above. If you must move a library, make sure all dependencies are still visible.
- Minimize visibility. Dependency libraries should be placed at the lowest visibility level that satisfies all dependencies.
- Share libraries. Avoid duplicating libraries. Duplication of libraries may make debugging classloading issues a nightmare. Share classes across a set of applications by using the configuration facilities provided by your application server. For example, use the <library> tag in the global application.xml file in OC4J to share classes across all applications.
- Keep configurations portable. Choose configuration options in the following order:
- Standard J2EE options
- Options that can be expressed within your EAR file
- Server-level options
- J2SE extension options
- Use the correct loader. If you call Class.forName(), always explicitly pass the loader returned by Thread.currentThread().getContextClassLoader. If you are loading a properties file, use Thread.currentThread().getContextClassLoader().getResourceAsStream().
- Avoid hardcoding of a specific parser in your application. Use JAXP API to access the underlying XML/XSL parsers in a vendor-neutral way instead of hard coding a specific XML parser in your application.
- Avoid hot redeployment. Hot deployment depends upon classloaders and hot (re)depployment may introduce classloading errors. Avoid hot deployment if there is to much dependencies between applications and external libraries.