I have setup a simple spring boot application based on version 2.1 (https://github.com/dkellenb/spring-boot-2.1-cache-actuator-missing). I cannot find the reason why the cache actuator is not available at http://localhost:8080/actuator/caches .
#EnableCaching
#SpringBootApplication
#Controller
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
#Cacheable(cacheNames = "helloWorld")
#GetMapping
public ResponseEntity<String> hello() {
return ResponseEntity.ok("hello world");
}
}
And for the pom.xml i have added cache and actuator:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
Also i have tested with
endpoints.caches.enabled=true
management.endpoints.web.exposure.include=info,health,cache
Note that Cache Actuator is available with JMX, but on on web.
The reason was:
cache is not exposed by default (see https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-endpoints.html#production-ready-endpoints-exposing-endpoints)
There was a typo for the exposure, it should be caches (plural)
I had a similar problem and it turned out that the actuator must be be in the version spring-boot-autoconfigure-2.1.3.RELEASE.jar.
My previous version was spring-boot-actuator-autoconfigure-2.0.2.RELEASE.jar. In this version CachesEndpointAutoConfiguration not exist. This class is responsible for creating the "cachesEndpoint" bean if the "cacheManager" bean is present in the application.
Try the version 2.1.3.
Related
I have a spring boot application running a feature. I want to toggle that feature(on/off) at runtime without redeploying or restarting the application. Issue is that I can't deploy any rest endpoint as server has only exposed some specific port because of security.
I want to remotely control the toggle so that I can set that feature on and off. I tried reading the environment variable on my local machine using:
System.getEnv("envVariable")
but even after updating it using export envVariable=true it's not reflecting updated value in the code.
Can someone suggest any way to achieve this ?
Thanks,
To do this you need some more dependencies.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR9</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
in properties file you need to write
management.endpoints.web.exposure.include=*
and on the class wherever you are are using environment variables use Annotation #RefreshScope like
import org.springframework.web.bind.annotation.RestController;
import org.springframework.cloud.context.config.annotation.RefreshScope;
#RefreshScope
#RestController
public class DemoController {
#Value("${my.data}")
String str;
// code
}
and whenever you are changing environment variable just hit a post request http://localhost:PORT/actuator/refresh
using above configuration you can change the environment variables.
There is a programming pattern Feature Toggle that provides a way to turn on/off application components during the runtime. The core idea is to ask property files or database config table about current states of config fields and change application functionality if config changed. This pattern described here https://martinfowler.com/bliki/FeatureToggle.html. You can find more by using keyword "Feature Flags".
One of popular implementations of Feature Flags for Java is togglz (https://www.togglz.org/quickstart.html).
Here is an exaple of using togglz:
Create enum for features representation
public enum MyFeatures implements Feature {
#EnabledByDefault
#Label("First Feature")
FEATURE_ONE,
#Label("Second Feature")
FEATURE_TWO;
public boolean isActive() {
return FeatureContext.getFeatureManager().isActive(this);
}
Implement TogglzConfig
#ApplicationScoped
public class DemoConfiguration implements TogglzConfig {
public Class<? extends Feature> getFeatureClass() {
return MyFeatures.class;
}
public StateRepository getStateRepository() {
return new FileBasedStateRepository(new File("/tmp/features.properties"));
}
public UserProvider getUserProvider() {
return new ServletUserProvider("admin");
}
}
Describe the feature behavior depended on toggle:
if( MyFeatures.FEATURE_ONE.isActive() ) {
// new stuff here
}
Source: https://www.togglz.org/quickstart.html
I am implementing how to send email using spring boot
I am trying to implement this in visual studio code.
But it gives me the following error
I added the following two dependencies in my pom.xml for email configuration:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
my main bootstrap class:
#SpringBootApplication
#ComponentScan(basePackages = {
"email"
})
public class Application {
public static void main(String[] args) {
Mail mail = new Mail();
mail.setMailFrom("abc#gmail.com");
mail.setMailTo("xyz#gmail.com");
mail.setMailSubject("Hi");
mail.setMailContent("Hope you are doing well");
ApplicationContext ctx = SpringApplication.run(Application.class,
args);
MailService mailService = (MailService) ctx.getBean("mailService");
mailService.sendEmail(mail);
}
I think my error is related to the #ComponentScan(basePackages = {"email"}) annotation that I have used above
Can anyone help me with the error?
Since we don't know the package structure it is difficult to tell what should be there in the basePackages inside #ComponentScan
Firstly, please move your Application class to one level up in the package structure, so that it reads all packages under it by default and remove the basePackages in component scan. So, it should be just #ComponentScan
That is, if all your classes are in package com.test.mailer then your Application class file should be in com.test
Try this and let us know, also I hope you have the #Service annotation as #Service("mailService")
Update:
Since the user has updated the question later, I am posting the solution that worked for him.
He moved the class one level up and removed the basePackages and it worked for him. As stated in the first part of my answer.
Alternatively, he could have changed #ComponentScan(basePackages = {"email"}) to #ComponentScan("java.risknucleus") in the same structure.
I am upgrading Spring Boot from 1.3 to 1.5. For upgrading to 1.5 I have replaced
#SpringApplicationConfiguration(classes = TestConfig.class)
#WebIntegrationTest
with
#SpringBootTest(classes = TestConfig.class)
Also, I am using
#Value("${local.server.port}")
protected int port;
to get port number defined in application.properties file. I further use this port number to build a REST URL.
But after the upgrade I am getting the error below whereas the same works fine with 1.3 Spring Boot Test.
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'local.server.port' in value "${local.server.port}"
at org.springframework.util.PropertyPlaceholderHelper.parseStringValue(PropertyPlaceholderHelper.java:174)
Am I missing any changes that I need to do for this to work.
You have to provide a value for webEnvironment. In your case DEFINED_PORT like this
#SpringBootTest(classes = App.class, webEnvironment = WebEnvironment.DEFINED_PORT)
public class YourTest {
#LocalServerPort // shorthand for #Value("${local.server.port}")
private Integer port;
...
}
For details see: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html#boot-features-testing-spring-boot-applications
Adding another alternate solution which I had elsewhere.
I had configured
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
and
#RunWith(SpringRunner.class)
#SpringBootTest(classes = App.class, webEnvironment = WebEnvironment.RANDOM_PORT)
public class YourTest {
#LocalServerPort // shorthand for #Value("${local.server.port}")
private Integer port;
...
}
Thinking that was it, and still getting this error even when specifying web environment etc. My ${local.server.port} seemed to be always null.
After some time, I noticed that my Spring Boot startup message contained no notion of the port it was using, so apparently it really didn't listen to any port at all - which explained why it was null in the first place. Adding actual container implementation dependency:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
Caused this to appear on my logs:
2019-02-26 18:45:47.231 INFO 12504 --- [ main] o.s.b.web.embedded.jetty.JettyWebServer : Jetty started on port(s) 43132 (http/1.1) with context path '/'
after which local.server.port and #LocalServerPort would also work.
For me the problem was that there was alternative #Configuration class(es) in my other test(s) like this:
#Configuration
public class ReadPropertiesConfiguration {
#Bean
PropertyPlaceholderConfigurer propConfig() {
PropertyPlaceholderConfigurer placeholderConfigurer = new PropertyPlaceholderConfigurer();
placeholderConfigurer.setLocation(new ClassPathResource("application.properties"));
return placeholderConfigurer;
}
}
and #SpringBootApplication of the app was picking that up due to its #ComponentScan, and for some reason it resulted in this problem. When adding exclusion for those and/or replacing them with other solutions things started again to work without problems.
I don't know the root cause why this happens, but that might be your issue as well.
First make sure the property is correctly spelled in the properties file. As i did just few days back using spring-boot-1.5.2 & it works.
Or
You need to add
#PropertySource("classpath:application.properties")
to your class, so it will pick your configurations.
If you need different configurations for test you can add
#TestPropertySource(locations="classpath:test.properties")
Refer #Value not work on Spring Boot Test
I want to use Swagger 2.0 with my Spring Boot RESTful web service to generate documentation. I have searched quite a bit for an answer to this. Basically I have a Spring Boot project with a set of controllers and I want to document the API's. I have the following dependencies setup in my POM file.
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.4.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.5.0</version>
</dependency>
This is my Swagger configuration class with the #Configuration and #EnableSwagger2:
#Configuration
#EnableSwagger2
public class SwaggerConfig {
#Bean
public Docket api(){
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.regex("/api/.*"))
.build()
.apiInfo(apiInfo());
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("My application title")
.description("This is a test of documenting EST API's")
.version("V1.2")
.termsOfServiceUrl("http://terms-of-services.url")
.license("LICENSE")
.licenseUrl("http://url-to-license.com")
.build();
}
}
From what I have gathered in reading a couple of other answers here that at this point I should be able to see something at a URL such as http://myapp/v2/api-docs or alternatively http://localhost:8080/myapp/api-docs I have made the assumption that the "myapp" portion of the above URL refers to the name of the class in which my main resides (is this correct)? Also I have tried this with port 8080 and port 80 and the bottom line is that I see nothing other than site can't be reached. I have looked at the answers provided here and here however I'm not having any success. Any help would be much appreciated, thank you in advance.
As you can see on the following documentation :
https://springfox.github.io/springfox/docs/snapshot/#springfox-swagger-ui
The endpoint is now on swagger-ui.html, for your case, it will be http://localhost:8080/myapp/swagger-ui.html
I used, <artifactId>springdoc-openapi-ui</artifactId> with
public class OpenApiConfiguration{
#Bean
public GroupedOpenApi abcApp(){
String[] abcAppRootPath={"com.stockoverflow.swagger"};
return GroupedOpenApi.builder().group("my app").packagesToScan(abcAppRootPath).build();
}
}
reference : https://springdoc.org/#getting-started
I am trying to programmatically restart my spring boot application end point. Below is the lines I have used.
public class FileWatcher {
#Autowired
private RestartEndpoint restartEndpoint;
public void onFileChange() {
Thread restartThread = new Thread(() -> restartEndpoint.restart());
restartThread.setDaemon(false);
restartThread.start();
}
}
But it throws the below error.
Error:(32, 64) java: cannot access org.springframework.boot.actuate.endpoint.AbstractEndpoint
class file for org.springframework.boot.actuate.endpoint.AbstractEndpoint not found
What am I doing wrong here? Any help would be much appreciated.
http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#production-ready
Add the actuator dependencies, in maven:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
For Gradle, use the declaration:
dependencies {
compile("org.springframework.boot:spring-boot-starter-actuator")
}