I have a Spring Boot 2.0.0 RC2 with embedded jetty and I want to enable HTTP/2.
According to docs on how to enable http/2 for jetty I added server.http2.enabled=true to my apllication.properties
And my pom.xml looks like this:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.RC2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<!-- Exclude the Tomcat dependency -->
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Use Jetty instead -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.eclipse.jetty/jetty-alpn-conscrypt-server -->
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-alpn-conscrypt-server</artifactId>
<version>9.4.8.v20171121</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.eclipse.jetty.http2/http2-server -->
<dependency>
<groupId>org.eclipse.jetty.http2</groupId>
<artifactId>http2-server</artifactId>
<version>9.4.8.v20171121</version>
</dependency>
</dependencies>
Then I start it and do some GET requests (first one is HTTP1, second is HTTP2). Here is the output:
2018-02-26 18:24:59.670 INFO 20338 --- [ main] o.s.b.web.embedded.jetty.JettyWebServer : Jetty started on port(s) 8080 (http/1.1) with context path '/'
2018-02-26 18:24:59.674 INFO 20338 --- [ main] ru.example.vpndemo.VpnDemoApplication : Started VpnDemoApplication in 4.772 seconds (JVM running for 5.45)
127.0.0.1 - - [26/Feb/2018:15:25:11 +0000] "GET /example/ HTTP/1.1" 200 13
127.0.0.1 - - [26/Feb/2018:15:33:52 +0000] "PRI * HTTP/2.0" 426 0
Why does my 2nd request prints as PRI in console?
Here is a cURL output for HTTP1 request:
$ curl http://localhost:8080/example/ -v
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /example/ HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.58.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Date: Mon, 26 Feb 2018 15:37:03 GMT
< Content-Type: text/plain;charset=utf-8
< Content-Length: 13
<
* Connection #0 to host localhost left intact
Hello Spring!
And here is the output for HTTP2:
$ curl --http2-prior-knowledge http://localhost:8080/example/ -v
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8080 (#0)
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x1ac3f90)
> GET /example/ HTTP/2
> Host: localhost:8080
> User-Agent: curl/7.58.0
> Accept: */*
>
* Connection #0 to host localhost left intact
curl: (16) Error in the HTTP2 framing layer
Looks like HTTP2 is still not enabled. If so, how do I enable it for Jetty (I know, that it can be easily enabled for Tomcat or Undertow).
If it is already enabled, then what am I doing wrong to get the desired output?
Any ideas?
Thanks in advance!
UPD
To make sure my cURL is working properly with HTTP2 i started app with Undertow HTTP2. Here is the output:
$ curl --http2-prior-knowledge http://localhost:8080/example/ -v
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8080 (#0)
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x2582f90)
> GET /example/ HTTP/2
> Host: localhost:8080
> User-Agent: curl/7.58.0
> Accept: */*
>
* Connection state changed (MAX_CONCURRENT_STREAMS updated)!
< HTTP/2 200
< content-type: text/plain;charset=UTF-8
< content-length: 13
< date: Mon, 26 Feb 2018 14:31:06 GMT
<
* Connection #0 to host localhost left intact
Hello Spring!
The sequence ...
PRI * HTTP/2.0
SM
Looking like "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" is the "HTTP/2 Connection Preface"
See: https://www.rfc-editor.org/rfc/rfc7540#section-3.5
In HTTP/2, each endpoint is required to send a connection preface as
a final confirmation of the protocol in use and to establish the
initial settings for the HTTP/2 connection. The client and server
each send a different connection preface.
For http/2 and jetty application server via maven dependency management:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-alpn-server</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-alpn-conscrypt-server</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.http2</groupId>
<artifactId>http2-server</artifactId>
</dependency>
Related
How to add custom metrics to /info endpoint in Spring Actuator 2.7.0?
Currently have the following related to actuator.
I have verified that info.app.version can retrieve the proper value from pom.xml using #Value.
pom.xml
<version>0.0.1-SNAPSHOT</version>
...
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<version>2.7.0</version>
</dependency>
application.properties
info.app.version=#project.version#
management.endpoint.info.enabled=true
management.endpoints.web.exposure.include=info,health
But despite this I am only getting an empty response on /info.
Response header:
< HTTP/1.1 200
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Frame-Options: DENY
< Content-Type: application/vnd.spring-boot.actuator.v3+json
< Transfer-Encoding: chunked
< Date: Wed, 15 Jun 2022 04:12:47 GMT
* Received 7 B chunk
* Received 5 B chunk
* Connection #26 to host localhost left intact
Response body :
{}
My understanding is any property under info is included in /info endpoint. Or does this not work on actuator v2+ ?
Source
From the Spring-Boot 2.6 release notes https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.6-Release-Notes#actuator-env-infocontributor-disabled-by-default
You need to enable the info env property:
management.info.env.enabled=true
Latest spring boot requires two things to be set up:
1- exposing the endpoint in application.properties file:
management.endpoints.web.exposure.include=info, health
You can use a wildcard and expose all endpoints if you want
management.endpoints.web.exposure.include=*
2- enabling info.env in application.properties:
management.info.env.enabled=true
I have a Spring Boot's application, using Cassandra DB 4.0, running into the ubuntu 16.0 with java 1.8_292.
when I start the tomcat 9, the message below appear in catalina.out log:
> 2021-05-11 22:57:49.614 WARN 1184 --- [s0-admin-1] c.d.o.d.i.c.control.ControlConnection: [s0] Error connecting to Node(endPoint=127.0.0.1:9042, hostId=null,
> 2021-05-11 22:57:49.628 WARN 1184 --- [ main] ConfigServletWebServerApplicationContext: Exception encountered during context initialization - cancelling re
> 2021-05-11 22:57:49.645 INFO 1184 --- [main] ConditionEvaluationReportLoggingListener: Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
> 2021-05-11 22:57:49.692 ERROR 1184 --- [main] o.s.boot.SpringApplication : Application run failed
I checked and the CQLSH 6 is running correct :
Connected to SSP at 127.0.0.1:9042
[cqlsh 6.0.0 | Cassandra 4.0 | CQL spec 3.4.5 | Native protocol v5]
Use HELP for help.
cqlsh>
The nodetool status is ok:
Datacenter: datacenter1
=======================
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
-- Address Load Tokens Owns (effective) Host ID Rack
UN 127.0.0.1 414.45 KiB 16 100.0% f457b508-1b91-456c-85bc-1a621c5c1d78 rack1
However the spring boot could not connect to Cassandra. And it gave me this erro [s0] Error connecting to Node(endPoint=127.0.0.1:9042, hostId=null, .
The cassandra.yaml and cassandra-env.sh are configurated the default with 127.0.0.1.
Does someone have any idea about what is happenning?
Pom.xml
<!-- https://mvnrepository.com/artifact/com.datastax.cassandra/cassandra-driver-core -->
<dependency>
<groupId>com.datastax.cassandra</groupId>
<artifactId>cassandra-driver-core</artifactId>
<version>4.0.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.datastax.spark/spark-cassandra-connector -->
<dependency>
<groupId>com.datastax.spark</groupId>
<artifactId>spark-cassandra-connector_2.12</artifactId>
<version>3.0.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.spark/spark-core -->
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_2.12</artifactId>
<version>3.1.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.spark/spark-sql -->
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-sql_2.12</artifactId>
<version>3.1.1</version>
</dependency>
It was a Cassandra issue. Increase version of datastax/driver-java to 4.11.1. This version fixed the real problem : unexpected failure (java.lang.IllegalArgumentException: Unsupported request opcode: 0 in protocol 6).
For more details :
https://issues.apache.org/jira/browse/CASSANDRA-16636?page=com.atlassian.jira.plugin.system.issuetabpanels%3Aall-tabpanel
https://datastax-oss.atlassian.net/browse/JAVA-2936
I am trying to enable the actuator on an existing Spring Boot 2 application, which I thought would be straightforward as I have done few times for the application I created from scratch. However, somehow tomcat (as default server) not startup with the actuator port configured in the properties, when the application starts.
Here are snippets of the config and pom
server:
port: 8085
management:
port: 9085
<spring-boot.version>2.3.5.RELEASE</spring-boot.version>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
In the log of application startup, I can see the server port has been bound to the application but didn't see the actuator one specified in the properties.
18:32:08.435 [main] INFO o.a.c.h.Http11NioProtocol - Starting ProtocolHandler ["http-nio-8085"]
18:32:08.524 [main] INFO o.s.b.w.e.t.TomcatWebServer - Tomcat started on port(s): 8085 (http) with context path ''
I would expect to see a port binding like the log below right after the one above.
2021-01-20 17:01:35.636 INFO 20044 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 9085 (http)
I have checked the port has not been used by any other application. Did I miss anything else?
From your posting info, you should add some setting to enable endpoints. I give a sample. please try. By another word, management.port is used in spring boot 1.x.
In simple way, you just enable all endpoints and expose all. for security reason, you should make management.endpoints.enabled-by-default to false. then enable endpoint you want to expose.
management:
server:
port: 9085
endpoints:
enabled-by-default: true
web:
# base-path: /mgmt # you can change /actuator to another name
exposure:
include: "*"
# endpoint:
# refresh:
# enabled: true
# loggers:
# enabled: true
# env:
# enabled: true
I know, there are a lot of such quesions and answers here, but none of them helped me. I try to install my simple Spring Boot app on AWS Elastic Beanstalk. There is a limitation: it must use .jsp templates, so it's .war, not .jar. If I use predefined Tomcat env on Elastic Beanstalk, everything works fine, but my goal is to use Java env.
When I install my app, its status is getting Degraded and I become 502 when trying to reach the url.
Locally everything works perfect.
I changed port in application.properties to 5000, but it didn't help. I found a recommendation to use a security rule for inbound for TCP Port 5000 "0.0.0.0/32" but it didn't help eather.
Here are my pom.xml dependencies:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jdt.core.compiler</groupId>
<artifactId>ecj</artifactId>
<version>4.6.1</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
application.properties:
spring.mvc.view.prefix=/WEB-INF/view/
spring.mvc.view.suffix=.jsp
server.port=5000
Main Java class:
#SpringBootApplication
public class DemowebApplication extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(DemowebApplication.class);
}
public static void main(String[] args) {
SpringApplication.run(DemowebApplication.class, args);
}
}
AWS error logs:
2019/05/07 21:04:45 [error] 7827#0: *19 connect() failed (111: Connection refused) while connecting to upstream, client: 91.232.158.8, server: , request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:5000/", host: "my-endpoint-tst.us-east-2.elasticbeanstalk.com"
2019/05/07 21:04:46 [error] 7827#0: *19 connect() failed (111: Connection refused) while connecting to upstream, client: 91.232.158.8, server: , request: "GET /favicon.ico HTTP/1.1", upstream: "http://127.0.0.1:5000/favicon.ico", host: "my-endpoint-tst.us-east-2.elasticbeanstalk.com", referrer: "my-endpoint-tst.us-east-2.elasticbeanstalk.com/"
I suspect that problem is with my Tomcat configuration, but all my experiments with it didn't help yet.
I had a similar issue with this. I would load the JAR up to Elastic Beanstalk and when I would try to access the URL, I would get the 502 Apache error with the degraded status. Locally, I was set to port 8080 but when I tried to access it through my URL I was getting the 502. My problem was:
1) I was not exporting and uploading the fat .JAR file from my IDE when I was exporting it. I know you said you cant use .JAR but just make sure when you are exporting your project, you are also exporting all the dependencies from Maven with it.
2) This might be a bigger help than the first part of this answer but even when I was putting my port in the application.properties, it wasn't pulling through to the Elastic Beanstalk instance. What I successfully ended up doing to solve this issue was going into the management console in AWS, going to my Beanstalk instance, and going to the configuration tab.
On the configuration tab there is a section Software and in that subsection, go to the Environment Properties. In the Name section of the environment properties, enter SERVER_PORT and for the value section, enter 5000. Click apply and let the instance restart.
I have the following config in my /users//settings.xml.
Under PluginsGroup:
<pluginGroup>org.apache.tomcat.maven</pluginGroup>
Under servers:
<server>
<id>localhost</id>
<username>tom</username>
<password>cat</password>
</server>
Under profiles:
<plugin>
<configuration>
<server>localhost</server>
<url>http://localhost:8080/manager/text</url>
<path>/</path>
</configuration>
</plugin>
I ran the maven command with -X options, and I see the following:
[DEBUG] Reading global settings from C:\Tools\apache-maven-3.1.1\bin\..\conf\settings.xml
[DEBUG] Reading user settings from C:\Users\<user>\.m2\settings.xml
I have the manager-script role in tomcat users xml file.
When I manually verify the access through browser, it works fine. But when I run mvn tomcat7:deploy I get the following:
Receiving response: HTTP/1.1 401 Unauthorized
User name and password are correct. I verified it manually. What else could be wrong?
Googling did not help much.
Edit: More details from Log.
HTTP/1.1 401 Unauthorized
Server: Apache-Coyote/1.1
Cache-Control: private
Expires: Wed, 31 Dec 1969 18:00:00 CST
WWW-Authenticate: Basic realm="Tomcat Manager Application"
Set-Cookie: JSESSIONID=7320C7326C51E8F7FF9F4D23A39E6971; Path=/manager/; HttpOnly
Content-Type: text/html;charset=ISO-8859-1
Transfer-Encoding: chunked
Date: Thu, 24 Apr 2014 02:56:27 GMT
Cookie accepted: "[version: 0][name: JSESSIONID][value: 7320C7326C51E8F7FF9F4D23A39E6971]
[domain: localhost][path: /manager/][expiry: null]".
Connection can be kept alive indefinitely
Authentication required
localhost:8080 requested authentication
Authorization challenge processed
Authentication failed
Clearing cached auth scheme for http://localhost:8080
Edit:
Well, this is what I found out. When I pass username and password from mvn command, its working fine. But its not picking up from settings.xml.
Does it ring any bell? I tried moving the config stuff to MAVEN_HOME/config/settings.xml as well. (Deleted the user settings.xml). But still the same.
Any settings cache?
Edit:
I turned on the debugger with -X. Even though I deleted /user/.m2/settings.xml, it says its reading that file.
[DEBUG] Reading global settings from C:\Tools\apache-maven-3.1.1\bin\..\conf\settings.xml
[DEBUG] Reading user settings from C:\Users\<user>\.m2\settings.xml
How to flush?
The pluging configuration should be like that:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>tomcat-maven-plugin</artifactId>
<version>1.0</version>
<configuration>
<server>text</server>
<url>http://localhost:8080/manager/text</url>
</configuration>
</plugin>
This should work
I am guessing that the application you want to deploy is named text. If it is not replace text with your web application name.
Also I would try removing the last <path>/</path> element to see if this helps or not...