AWS Lambda Java how to read properties file

Viewed 8622

I try to load properties into Properties class from a file. I would expect this solution to work: How to load property file from classpath in AWS lambda java

I have a class with few static methods and I want to use it as a Config holder. Inside it there is this line

final InputStream inputStream = 
Config.class.getClass().getResourceAsStream("/application-main.properties");

and it always returns null. I downloaded the zip package that Lambda is using and the file is inside in root. Does not work nevertheless.

Anyone had similar issue?

EDIT: config file is here:

project
└───src
│   └───main
│      └───resources
│            application-main.properties

EDIT: My "temporary" workaround looks like that:

// LOAD PROPS FROM CLASSPATH...
try (InputStream is = Config.class.getResourceAsStream(fileName)) {
        PROPS.load(is);
    } catch (IOException|NullPointerException exc) {
        // ...OR FROM FILESYSTEM
        File file = new File(fileName);
        try (InputStream is = new FileInputStream(file)) {
            PROPS.load(is);
        } catch (IOException exc2) {
            throw new RuntimeException("Could not read properties file.");
        }
    }

During tests it reads from classpath, after deployment in AWS Lambda runtime it uses filesystem. To identify the file I used env variable:

fileName = System.getenv("LAMBDA_TASK_ROOT")  + "/application-main.properties";

But I would rather just use classpath without working this around.

6 Answers

Assuming src/main/resources/config.properties

File file = new File(classLoader.getResource("resources/config.properties").getFile());
FileInputStream fileInput = new FileInputStream(file);
prop.load(fileInput);

I am confused a lambda is part of a serveless application. So when you upload the Lambda to AWS Lambda, it wont see the properties file. since that is in your dev env.

To solve something like this you can use lightweight-config, which is a library for loading .yml files into POJOs. This wraps up the boilerplate of finding the configuration file in your resources, and also handles interpolating things like environment variables or system properties into the configuration. This is much easier to use than Properties and removes all the boilerplate.

E.g.

username: ${DB_USERNAME}
port: 3306

Then a java class to represent these (as Properties or Map are less type-safe):

public class Config {
    private String username;
    private int port;

    // getters and setters
}

To load:

Config config = ConfigLoader.loadYmlConfigFromResource("config.yml", Config.class);

The full library is available here - https://github.com/webcompere/lightweight-config

Related