Skip to content
Advertisement

Overwrite properties in java library

I have a Lib-A that has a dependency on com.atlassian.oai:swagger-request-validator-core. This dependency has a properties file messages.properties.

I have an App-A that has a dependency on Lib-A. If I place the messages.properties file in App-A, I am able to overwrite the properties, but if I place it in Lib-A, it doesn’t overwrite. How do I overwrite the properties from Lib-A?

There seems to be no way of changing the path as well: https://bitbucket.org/atlassian/swagger-request-validator/src/master/swagger-request-validator-core/src/main/java/com/atlassian/oai/validator/report/MessageResolver.java#lines-26

Advertisement

Answer

Easy peasy:

  1. demo/pom.xml:

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId>com.example</groupId>
      <artifactId>demo</artifactId>
      <version>0.0.1-SNAPSHOT</version>  
      <dependencies>
        <dependency>
          <groupId>org.slf4j</groupId>
          <artifactId>slf4j-simple</artifactId>
          <version>1.7.32</version>
        </dependency>
        <dependency>
          <groupId>com.atlassian.oai</groupId>
          <artifactId>swagger-request-validator-core</artifactId>
          <version>2.22.0</version>
        </dependency>
      </dependencies>
    </project>
    
  2. demo/src/main/resources/swagger/validation/messages.properties (case sensitive):

    validation.request.path.missing=FOO '%s'. # an existing key from ...
    # ...swagger-validator with custom message (and complying parameters)
    
  3. demo/src/main/java/com/example/demo/Main.java:

    package com.example.demo;
    
    import com.atlassian.oai.validator.report.MessageResolver;
    import com.atlassian.oai.validator.report.ValidationReport.Message;
    import org.slf4j.Logger;
    import static org.slf4j.LoggerFactory.getLogger;
    
    public class Main {
    
      private static final Logger log = getLogger(Main.class);
      public static void main(String[] args) {
        MessageResolver mr = new MessageResolver();
        Message m = mr.get("validation.request.path.missing", "bar");
        log.info("got message: {}", m == null ? null : m.getMessage());
      }
    }
    
  4. (with these 3 files only, Execute) In your terminal (or in an IDE):

    >cd demo
    >mvn clean process-classes exec:java -Dexec.mainClass="com.example.demo.Main"
    
  5. Output:

    [INFO] ...
    [INFO] --- exec-maven-plugin:3.0.0:java (default-cli) @ spring-data-demo ---
    [com.example.demo.Main.main()] INFO com.example.demo.Main - got message: FOO 'bar'.
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD SUCCESS
    [INFO] ------------------------------------------------------------------------
    [INFO] Total time:  4.775 s
    [INFO] Finished at: 2021-11-11T17:33:39+01:00
    [INFO] ------------------------------------------------------------------------
    

If we delete/rename/move our messages.properties, we get (the original) No API path found that matches request 'bar'.

I.e. by only placing the file in the correct location (classpath:/swagger/validation/messages.properties), we could change the message(s) of a (default) MessageResolver.


Edit1:

I think this will “always work”, since the files in your bin/target folder will have precedence over “resources in jars”, but it depends on classpath/-loader/execution details. But under these conditions any (default) MessageResolver created in “your jvm”, will prefer that/your messages.properties


If you do so, ensure all keys are available in your messages.properties (+ match parameter count(&semantics)), since when trying this:

// message key not present in (our!) swagger/validation/messages.properties
log.info("got other message: {}", 
  mr.get("validation.request.operation.notAllowed", "foo", "bar")
);

,we get ;(;(:

[com.example.demo.Main.main()] INFO com.example.demo.Main - got other message: null

Edit2:

Instead of (effectively)overwriting/replacing the (default) “resource bundle”, you can also have all of the “inheritance and fallback magic”, by addding language, country, platform specific messages (but still falling back to the default ones.)

exemplary folder structure:

demo
--src
----main
------resources
--------swagger
----------validation
------------messages_en_GB.properties
------------messages_en_US.properties
------------messages_en.properties
------------messages_de.properties
------------...
       

See also:


Edit3:

I got it (replacing as “adding”) also working on a transitive dependency, but i had to ensure, that :

  • or demo is the only (direct) dependency.
  • or it appears (locally in the pom) before swagger-request-validator-core.

That sounds not really reliable, but that’s what i’ve found/tested.

And “beyond maven” (sorry used it), we can say: the dependency with customized messages, should appear in the class path before swagger-request-validator-core.jar

User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement