Search code examples
javajerseyjavax.ws.rs

Jersey: how to access the global application object?


I'm creating a REST web application with Java, Tomcat and Jersey. I'm using annotations (no web.xml!) I ended up using this application configuration:

package com.my_own.server;

import java.util.Properties;
import javax.ws.rs.ApplicationPath;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.my_own.db.PostgreSQLDb;

@ApplicationPath("/api")
public class Application extends javax.ws.rs.core.Application {
    private static Logger logger = LogManager.getLogger(Application.class);
    public static Application application = null;

    public final Properties properties;
    public final PostgreSQLDb adminDb;

    public Application() throws Exception {
        logger.debug("Loading properties from ",
                    getClass().getClassLoader().getResource("config.properties"));
        properties = new Properties();
        properties.load(getClass().getClassLoader().getResourceAsStream("config.properties"));
        adminDb = new PostgreSQLDb(properties, "admin");
        application = this; // Setting the global application object here
    }

}

Here is my problem. There is a single global application objects for the web container. I'm saving it into a static field, from the application constructor. I need to access it from other classes later (it holds the global configuration, a global database connection factory, and probably other things.)

Am I doing this right? I suspect that there must be a better way: save a reference to the application when annotations are processed. But I'm not sure how. Can I be sure that the Application's constructor will be called exactly once, and the Application.application reference can be accessed later, from any REST call?


Solution

  • Let me share my opinion: you can use of course a well-known Singleton pattern to store a "global" static object, however, it's really an antipattern these days.

    If it's not a homework or something then storing global "static" objects is always a bad idea design-wise. If you want to know why there are many sources that answer this question, like this discussion for example

    So I suggest considering using a Dependency Injection container instead, There are many really good containers out there: Spring, Guice to name a few.

    These containers can store these objects as beans and if your "pieces" of functionality are also managed by these containers, you'll be able to "inject" application beans right into the controller.

    It effectively solves all the issues introduced by singleton pattern.