It is a common issue, I am asked about every now and then, how to pass the user data to a user application? The user needs to change the code behavior depending on the configuration data. This is where the @Context Configuration comes in handy.
In the following text, I try to describe the possible methods to pass the user’s property to the Configuration object so that it is available when it is injected.
Hardcode in the Application/ResourceContext
This is the simplest way, just set the property just like:
new ResourceConfig().property("NAME","VALUE")
Using web.xml Initial Parameters
For classic war bundled applications, the properties can be defined in the web.xml:
<servlet>
<init-param>
<param-name>NAME</param-name>
<param-value>VALUE</param-value>
</init-param>
</servlet>
Using the AutoDiscoverable
Jersey comes with AutoDiscoverable SPI, which allows for being detected by a JDK’s ServiceLoader when anywhere on a classpath. Such AutoDiscoverable is then used as if it were a part of the application. The advantage is that the application itself does not need to be rebuilt, only the AutoDiscoverable with the properties.
The org.glassfish.jersey.internal.spi.AutoDiscoverable service needs to be added to META-INF/services, and it needs to point to the AutoDiscoverable implementation:
public class MyAutoDiscoverable implements AutoDiscoverable {
@Override
public void configure(FeatureContext context) {
context.property("NAME", "VALUE");
}
}
Using the System Properties
Quite often, the administrators come and ask to configure Jersey application, mainly to use any of the CommonProperties property, but they do not want to recompile their Jersey application, nor the AutoDiscoverable. Since Jersey 2.29 it is possible to turn on the ability to convert the System properties into Configuration properties. That can be done by using the System property, too:
java -Djersey.config.allowSystemPropertiesProvider=true -DNAME=VALUE
Note that with the security manager turned on, write access permission is required to execute System.getProperties(). With insufficient permissions, the warning message is logged (with Level.FINER) and only CommonProperties, ClientProperties, and ServerProperties properties are used, as the property names are known and System.getProperty(name) method can be used, which does not require the write access permission.
Using Microprofile Config
Microprofile platform became very popular lately and Microprofile Config Specification is a recommended way in the Jakarta EE world to configure the specifications under the Jakarta EE umbrella.
Jersey 2.29 comes with support for Microprofile Config implementation such as Helidon or SmallRye. To configure the Jersey application, the microprofile-config.properties file needs to be created in the META-INF folder. The required properties are then simply set in the microprofile-config.properties:
NAME=VALUE
Then Jersey Microprofile Config extension needs to be added:
<dependency>
<groupId>org.glassfish.jersey.ext.microprofile</groupId>
<artifactId>jersey-mp-config</artifactId>
<version>2.40</scope>
</dependency>
And the Microprofile Config implementation, such as Helidon:
<dependency>
<groupId>io.helidon.microprofile.config</groupId>
<artifactId>helidon-microprofile-config</artifactId>
<version>${helidon.version}</version>
</dependency>
Or SmallRye:
<dependency>
<groupId>io.smallrye</groupId>
<artifactId>smallrye-config</artifactId>
<version>1.3.6</version>
</dependency>
or any other suitable Microprofile Config implementation.
Other Methods
There are other methods that are variants of the described methods, or they are less straightforward and significantly more complicated. However, if you have any other favorite method that was not discussed, I’d love to hear about it in the comments.