Java Spring Boot won't pick up variable from application.yml - java

I am working on an application that uses a variable that is declared in the application.yml file. In my application.yml file it is defined as so:
lwt:
application:
five-minute-jobs: ${ENABLE_FIVE_MINUTE_JOBS:true}
In my controller file it is declared this way but it is always returning false whenever I log it in in the console. Here is the shortened version:
import org.springframework.beans.factory.annotation.Value;
public class EmailJobSchedulerController {
#Value("${lwt.application.five-minute-jobs}")
private boolean fiveMinuteJobsEnabled;
Am I declaring it correctly in the file? Been searching on other threads but haven't been able to find a clear answer for this. Thanks!

Have you tried with code below?
lwt:
application:
five-minute-jobs: true

May be you are not setting the env variable correctly. Can you do the following in your main #SpringBootApplication class and tell me what it is printing?
#SpringBootApplication
public class AccessingDataJpaApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(AccessingDataJpaApplication.class);
System.out.println(context.getEnvironment().getProperty("ENABLE_FIVE_MINUTE_JOBS"));
System.out.println(context.getEnvironment().getProperty("lwt.application.five-minute-jobs"));
}
}

#value annotation will get the value if it's under bean life cycle else you need to take from ConfigureEnviornment class, is below code is registered with bean ? I feel you might be missed adding #RestController on top of this class
import org.springframework.beans.factory.annotation.Value;
#RestController
public class EmailJobSchedulerController {
#Value("${lwt.application.five-minute-jobs}")
private boolean fiveMinuteJobsEnabled;

Related

Is it OK to inject value directly inside Bean function?

I was wondering how to do dependency injection in the most effective way inside my code.
I have this code:
#Configuration
public class SomeName {
#Autowired
private Other other;
#Bean
public void method() {
other.someMethod();
// some code
}
}
Can this code be changed into the following code(other will be used only inside this function)?
#Configuration
public class SomeName {
#Bean
public void method(Other other) {
other.someMethod();
// some code
}
}
You should avoid #Autowired if possible and inject using a constructor or method.
Starting with Java 9 and java modules (project jigsaw) there are some strict rules that make it harder for your framework to change the values of a private field.
What Spring is doing in the first example is essentially that - it breaks encapsulation to change the value of a private value. (There is a way to overcome this with "opens" directive in module-info..)
You are also becoming dependent on the framework you are using and your code becomes harder to test compared to when using a simple setter.
You are also not explicitly declaring that your class depends on another class since I can easily instantiate it and "Other" will be null.
Some resources:
https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-scanning-autodetection (search for jigsaw)
https://blog.marcnuri.com/field-injection-is-not-recommended/
PS: You are probably missing #Configuration on your class

Not able to access application.yml properties in springboot component

I have an application.yml file which contains properties as below
NAME:
CLASS:
ID: ABC123456
and here is my spring boot component class
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
#Component
#Slf4j
public class ProcessMe {
#Value("${NAME.CLASS.ID}")
String StuId;
public boolean IsRightOrWrong(){
System.out.println(StuId);
}
}
In above componenent System.out.println(StuId); is always coming as null. When i am tying to call this function using Junit test class. What's wrong in the above code?
I suppose this solution to define in constructor like
#Component
#Slf4j
public class ProcessMe {
String StuId;
#Autowired
ProcessMe(#Value("${NAME.CLASS.ID}") String StuId) {
this.StuId = StuId;
}
public boolean IsRightOrWrong(){
System.out.println(this.StuId);
}
}
Hope useful
If you can start the application then I believe that your configuration is correct. I mean that StuId have some value.
The problem is how you testing When i am tying to call this function using Junit test class. What's wrong in the above code?
It seems that you're calling from the unit test. Then you need to clone application.yaml to test profile then your test container can read data, otherwise you have to mock your configuration.
btw: Java Object property should using camel case lol

What´s a good practice for accessing external configurations in Spring Boot?

I´m setting up a Spring Boot application where certain configurations are being read from my application.yaml-file. I´ve done this a few times before and it works well, but I wondered whether there is a better way to access this configuration during runtime or whether I´m creating possible issues by not following some best practice.
Right now the class that extracts the configuration is simply defined as a Component like this:
#Component
#EnableConfigurationProperties
#ConfigurationProperties("myPrefix")
public class MyExternalConfiguration{
private HashMap<String, Boolean> entries= new HashMap<String, Boolean>();
public Boolean getConfigurationForKey(String key) {
return this.entries.get(key);
}
}
And then autowired to several other classes that need to access this configuration like this:
#Component
public class MyClass{
#Autowired
private MyExternalConfiguration myExternalConfiguration;
public void doSomething(){
//...
Boolean someEntry = myExternalConfiguration.getConfigurationForKey(someKey);
}
}
Now, this does work just fine. It´s just that I have seen examples of where configurations like this are handled as a singleton for example (although not in a Spring-Boot environment). I would just like to ask, whether there is some commonly accepted way to access external configurations or whether you see an issue with the way i access it in my project.
Thank you in advance!
There is a whole chapter about configuration in the Spring Boot Reference Manual:
https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-external-config
Simply said there are two options to access configuration:
With the Value annotation:
#Value("${name}")
private String name;
Or typesafe with a configuration class:
#ConfigurationProperties(prefix="my")
public class Config {
private List<String> servers = new ArrayList<String>();
public List<String> getServers() {
return this.servers;
}
}
So there is no need to read the configuration file by your own.

spring boot remote shell custom command

I try to add a new custom command to the spring boot remote shell without success.
In the documentation is only a groovy example available but I like to use Java do create a new command.
http://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-remote-shell.html
I also check the CRaSH documentation: http://www.crashub.org/1.3/reference.html#_java_commands
I put my class under package commands and crash.commands but I don't see my new command if I connect to the shell via ssh and type help. Any idea what I'm doing wrong?
Here is my Java Code:
package commands;
import org.crsh.cli.Command;
import org.crsh.cli.Usage;
import org.crsh.command.BaseCommand;
import org.springframework.stereotype.Component;
#Component
public class hello extends BaseCommand {
#Command
#Usage("Say Hello")
public String test() {
return "HELLO";
}
}
If your class is called 'hello', put it in
resources/crash/commands/hello/hello.java
Having a package statement doesn't matter.
You don't have to put anything inside src, just have this inside resources.
#Component isn't required.
This class is compiled during runtime. See:
org.crsh.lang.impl.java.JavaCompiler#compileCommand
Therefor any dependency injection requirements need to be considered accordingly with lazy initialization.
Put the class in the default package (i.e. omit the package statement) and put the Java source for the class in src/main/resources/commands. Spring/Crash will compile the Java code the first time you invoke the command. Also, if the class implements a single command the method name should be ‘main’ otherwise users have to type:
> hello test
You also don't need the #Component annotation on the class as it is not a Spring managed bean.

Play Framework 2.1 - Syntax error using java.util.properties in Play Controller

I am having a strange sort of conflict when attempting to use the java.util.Properties class in a Play Controller, consider the following:
package controllers;
import play.mvc.*;
import java.util.*;
public class Simple extends Controller {
Properties prop = new Properties();
prop.setProperty("database", "localhost");
}
In Eclipse the setProperty method returns:
Syntax error on token(s), misplaced construct(s)
Syntax error on tokens, delete these tokens
I think there is some conflict with this code being within a Controller, the same two lines work in a simple Java class in a bespoke package.
Any help would be much appreciated, I am new Play with some Java experience.
Put these two lines inside a method block:
import play.mvc.*;
import java.util.*;
public class Simple extends Controller {
public static void pickABetterMethodName() { // Method
Properties prop = new Properties();
prop.setProperty("database", "localhost");
}
}
This will solve the syntax problem. The reason is that you can't have code that is not method or field declaration in the class declaration itself. Behavior is implemented in methods. Here's the Java Tutorial about class declaration and here the about method declaration.
I think what you're trying to do is execute code during the controller initialization. If I remember correctly, in Play 1.x this was possible with a #OnApplicationStart decorator (on a method). I'm not sure this is still the case with Play 2.x.
Edit: With Play 2.x you do this with the Application global settings.

Categories