REST Endpoint slow on GAE at the first call - api

I have a REST Controller developed in Java 8, with Jersey 2.35 and Google App Engine.
Here is my Controller.
package com.foo.rest
#Controller
#Path(BookApi.BASE_ENDPOINT)
public class BookController extends AbstractController implements BookApi {
#Autowired
private BookService bookService;
}
In this Controller, I have an endpoint GET /books which return books.
The endpoint is annotated by #Checklogin which checks if the user is connected.
The endpoint will return JSON.
This endpoint is written in a Controller stored in com.foo.rest package
#GET
#Path("/books/")
#Checklogin
#Produces(MediaType.APPLICATION_JSON)
#Override
public Settings getBooks(
#Context final HttpServletRequest request) {
return this.bookService.getBooks();
}
Here is the BookService
#Singleton
#Component
public interface BookService {}
I'm using Jersey on Google App Engine.
I defined my REST API in the web.xml
<servlet>
<servlet-name>jersey-serlvet</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.foo.rest</param-value>
</init-param>
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider,org.glassfish.jersey.media.multipart.MultiPartFeature</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jersey-serlvet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
I configured my pom.xml like below
<dependency>
<groupId>org.glassfish.jersey.ext</groupId>
<artifactId>jersey-bean-validation</artifactId>
<version>2.35</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-server</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-common</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.ext</groupId>
<artifactId>jersey-spring5</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-multipart</artifactId>
<version>${jersey.version}</version>
</dependency>
Everything works fine in local environment.
But, in production, the first request takes too much times.
I don't understand why.
I added a lot of logs and this is the workflow.
First call after a warmup, restart, or long inactivity
So, I added logs to visualize the Container / Request workflow, as explained in Jersey documentation : https://eclipse-ee4j.github.io/jersey.github.io/documentation/latest/monitoring_tracing.html#monitoring
Here is the workflow
ServletContainer initialization
1 INFO 2023-02-12T21:50:14 com.foo.rest.config.ServletContainer INIT ServletContainer : 2023-02-12T21:50:14
2 INFO 2023-02-12T21:50:26 com.foo.rest.config.MyContainerEventListener onStartup: onStartup
3 INFO 2023-02-12T21:50:26 com.foo.rest.config.ServletContainer INIT ServletContainer : 12300 ms
Request processing
4 INFO 2023-02-12T21:50:26 com.foo.rest.handlers.security.filters.ApiReqPerfLogsFilter filter: PATH : books/5969737255223296/ Start : 2023-02-12T21:50:26
5 INFO 2023-02-12T21:50:27 com.foo.rest.config.MyRequestEventListener onEvent: Request books/5969737255223296 books/5969737255223296/ MATCHING_START : 2023-02-12T21:50:27
6 INFO 2023-02-12T21:50:27 com.foo.rest.handlers.security.filters.BookFilter filter: Call FUNC #CheckBook : 21 ms
7 INFO 2023-02-12T21:50:27 com.foo.rest.handlers.security.filters.SecureFilter filter: start SecureFilter : 2023-02-12T21:50:27
8 INFO 2023-02-12T21:50:27 com.foo.rest.handlers.security.filters.SecureFilter filter: Call FUNC #CheckLogin : 92 ms
9 INFO 2023-02-12T21:50:27 com.foo.rest.handlers.security.filters.SecureFilter filter: end SecureFilter : 2023-02-12T21:50:27
10 INFO 2023-02-12T21:50:27 com.foo.rest.config.MyRequestEventListener onEvent: Request books/5969737255223296/ REQUEST_FILTERED : 2023-02-12T21:50:27
11 INFO 2023-02-12T21:50:27 com.foo.rest.config.MyRequestEventListener onEvent: Request books/5969737255223296/ RESOURCE_METHOD_START : 2023-02-12T21:50:27
12 INFO 2023-02-12T21:50:29 com.foo.rest.controller.BookController getbook: start getbook : 2023-02-12T21:50:29
13 INFO 2023-02-12T21:50:29 com.foo.rest.handlers.security.filters.ApiFunPerfLogsFilter logDuration: METHOD com.foo.rest.service.bookservice.get() Duration 187 ms
14 INFO 2023-02-12T21:50:29 com.foo.rest.controller.BookController getbook: end getbook : 2023-02-12T21:50:29
15 INFO 2023-02-12T21:50:29 com.foo.rest.config.MyRequestEventListener onEvent: Request books/5969737255223296/ RESOURCE_METHOD_FINISHED : 2023-02-12T21:50:29
16 INFO 2023-02-12T21:50:29 com.foo.rest.config.MyRequestEventListener onEvent: Request books/5969737255223296/ RESP_FILTERS_START : 2023-02-12T21:50:29
17 INFO 2023-02-12T21:50:29 com.foo.rest.handlers.security.filters.ApiReqPerfLogsFilter filter: PATH : books/5969737255223296/ Duration : 2499 ms
18 INFO 2023-02-12T21:50:29 com.foo.rest.config.MyRequestEventListener onEvent: Request books/5969737255223296/ RESP_FILTERS_FINISHED : 2023-02-12T21:50:29
19 INFO 2023-02-12T21:50:29 com.foo.rest.config.MyRequestEventListener onEvent: RequestGET books/5969737255223296/ FINISHED : 2023-02-12T21:50:29
For the first request, there is :
ServletContainer initialization
A whole of 2 seconds between RESOURCE_METHOD_START indicated by Jersey and the real start of the method getBooks() logged in the controller.
What happen between step 11 and 12 described in my logs ?
I downloaded the Jersey source code and i don't understand.
Here is the bottleneck
Class ResourceMethodInvoker method private Response invoke(RequestProcessingContext context, Object resource)
I can see the event RESOURCE_METHOD_START pushed here.
1 context.triggerEvent(org.glassfish.jersey.server.monitoring.RequestEvent.Type.RESOURCE_METHOD_START);
2 this.dispatcher.dispatch(resource, context.request());
3 this.doDispatch(resource, request);
4 invokeMethodAction.run(); // this line call the controller
5 BookController.getBooks();
I did not find the logic which could take 2 secondes between the RESOURCE_METHOD_START and invokeMethodAction.run();
If someone has an idea.
Thanks.

Related

JPA API Application spring boot errors need a fix

This is my console output.
I have been trying to find and fix my spring boot error for days and couldn't find a solution. This error is making my application not work as intended. I have included both my console output and pom.xml. Please let me know what I have to fix in order for my application to run properly.
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v3.0.0)
2022-12-03T17:35:11.248-05:00 INFO 20075 --- [ main] c.rdeleon.app.rest.RestApiApplication : Starting RestApiApplication using Java 17.0.3.1 with PID 20075 (/Users/ryandeleon/Desktop/Fall 2022/cen 4025/Documents/module13/sourcecode/rest/target/classes started by ryandeleon in /Users/ryandeleon/Desktop/Fall 2022/cen 4025/Documents/module13/sourcecode/rest)
2022-12-03T17:35:11.254-05:00 INFO 20075 --- [ main] c.rdeleon.app.rest.RestApiApplication : No active profile set, falling back to 1 default profile: "default"
2022-12-03T17:35:11.948-05:00 INFO 20075 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2022-12-03T17:35:12.025-05:00 INFO 20075 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 64 ms. Found 1 JPA repository interfaces.
2022-12-03T17:35:12.467-05:00 INFO 20075 --- [ main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default]
2022-12-03T17:35:12.544-05:00 INFO 20075 --- [ main] org.hibernate.Version : HHH000412: Hibernate ORM core version 6.1.5.Final
2022-12-03T17:35:12.858-05:00 WARN 20075 --- [ main] org.hibernate.orm.deprecation : HHH90000021: Encountered deprecated setting [javax.persistence.sharedCache.mode], use [jakarta.persistence.sharedCache.mode] instead
2022-12-03T17:35:13.062-05:00 INFO 20075 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
2022-12-03T17:35:13.484-05:00 INFO 20075 --- [ main] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection com.mysql.cj.jdbc.ConnectionImpl#3d615b2e
2022-12-03T17:35:13.487-05:00 INFO 20075 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
2022-12-03T17:35:13.584-05:00 INFO 20075 --- [ main] SQL dialect : HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect
2022-12-03T17:35:14.042-05:00 INFO 20075 --- [ main] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
2022-12-03T17:35:14.057-05:00 INFO 20075 --- [ main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2022-12-03T17:35:14.292-05:00 WARN 20075 --- [ main] s.c.a.AnnotationConfigApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'apiControllers': Unsatisfied dependency expressed through field 'userRepo': Error creating bean with name 'userRepo' defined in com.rdeleon.app.rest.Repo.UserRepo defined in #EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration: Not a managed type: class com.rdeleon.app.rest.Models.User
2022-12-03T17:35:14.293-05:00 INFO 20075 --- [ main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
2022-12-03T17:35:14.297-05:00 INFO 20075 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated...
2022-12-03T17:35:14.307-05:00 INFO 20075 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed.
2022-12-03T17:35:14.319-05:00 INFO 20075 --- [ main] .s.b.a.l.ConditionEvaluationReportLogger :
Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
2022-12-03T17:35:14.352-05:00 ERROR 20075 --- [ main] o.s.boot.SpringApplication : Application run failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'apiControllers': Unsatisfied dependency expressed through field 'userRepo': Error creating bean with name 'userRepo' defined in com.rdeleon.app.rest.Repo.UserRepo defined in #EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration: Not a managed type: class com.rdeleon.app.rest.Models.User
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:712) ~[spring-beans-6.0.2.jar:6.0.2]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:692) ~[spring-beans-6.0.2.jar:6.0.2]
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:127) ~[spring-beans-6.0.2.jar:6.0.2]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:481) ~[spring-beans-6.0.2.jar:6.0.2]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1397) ~[spring-beans-6.0.2.jar:6.0.2]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:598) ~[spring-beans-6.0.2.jar:6.0.2]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:521) ~[spring-beans-6.0.2.jar:6.0.2]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326) ~[spring-beans-6.0.2.jar:6.0.2]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-6.0.2.jar:6.0.2]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324) ~[spring-beans-6.0.2.jar:6.0.2]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-6.0.2.jar:6.0.2]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:961) ~[spring-beans-6.0.2.jar:6.0.2]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:915) ~[spring-context-6.0.2.jar:6.0.2]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:584) ~[spring-context-6.0.2.jar:6.0.2]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:730) ~[spring-boot-3.0.0.jar:3.0.0]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:432) ~[spring-boot-3.0.0.jar:3.0.0]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:308) ~[spring-boot-3.0.0.jar:3.0.0]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1302) ~[spring-boot-3.0.0.jar:3.0.0]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1291) ~[spring-boot-3.0.0.jar:3.0.0]
at com.rdeleon.app.rest.RestApiApplication.main(RestApiApplication.java:11) ~[classes/:na]
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userRepo' defined in com.rdeleon.app.rest.Repo.UserRepo defined in #EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration: Not a managed type: class com.rdeleon.app.rest.Models.User
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1751) ~[spring-beans-6.0.2.jar:6.0.2]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:599) ~[spring-beans-6.0.2.jar:6.0.2]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:521) ~[spring-beans-6.0.2.jar:6.0.2]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326) ~[spring-beans-6.0.2.jar:6.0.2]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-6.0.2.jar:6.0.2]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324) ~[spring-beans-6.0.2.jar:6.0.2]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-6.0.2.jar:6.0.2]
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:254) ~[spring-beans-6.0.2.jar:6.0.2]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1405) ~[spring-beans-6.0.2.jar:6.0.2]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1325) ~[spring-beans-6.0.2.jar:6.0.2]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:709) ~[spring-beans-6.0.2.jar:6.0.2]
... 19 common frames omitted
Caused by: java.lang.IllegalArgumentException: Not a managed type: class com.rdeleon.app.rest.Models.User
at org.hibernate.metamodel.model.domain.internal.JpaMetamodelImpl.managedType(JpaMetamodelImpl.java:181) ~[hibernate-core-6.1.5.Final.jar:6.1.5.Final]
at org.hibernate.metamodel.model.domain.internal.MappingMetamodelImpl.managedType(MappingMetamodelImpl.java:496) ~[hibernate-core-6.1.5.Final.jar:6.1.5.Final]
at org.hibernate.metamodel.model.domain.internal.MappingMetamodelImpl.managedType(MappingMetamodelImpl.java:99) ~[hibernate-core-6.1.5.Final.jar:6.1.5.Final]
at org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformation.<init>(JpaMetamodelEntityInformation.java:77) ~[spring-data-jpa-3.0.0.jar:3.0.0]
at org.springframework.data.jpa.repository.support.JpaEntityInformationSupport.getEntityInformation(JpaEntityInformationSupport.java:69) ~[spring-data-jpa-3.0.0.jar:3.0.0]
at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getEntityInformation(JpaRepositoryFactory.java:246) ~[spring-data-jpa-3.0.0.jar:3.0.0]
at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:211) ~[spring-data-jpa-3.0.0.jar:3.0.0]
at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:194) ~[spring-data-jpa-3.0.0.jar:3.0.0]
at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:81) ~[spring-data-jpa-3.0.0.jar:3.0.0]
at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:317) ~[spring-data-commons-3.0.0.jar:3.0.0]
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.lambda$afterPropertiesSet$5(RepositoryFactoryBeanSupport.java:279) ~[spring-data-commons-3.0.0.jar:3.0.0]
at org.springframework.data.util.Lazy.getNullable(Lazy.java:229) ~[spring-data-commons-3.0.0.jar:3.0.0]
at org.springframework.data.util.Lazy.get(Lazy.java:113) ~[spring-data-commons-3.0.0.jar:3.0.0]
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:285) ~[spring-data-commons-3.0.0.jar:3.0.0]
at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:132) ~[spring-data-jpa-3.0.0.jar:3.0.0]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1797) ~[spring-beans-6.0.2.jar:6.0.2]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1747) ~[spring-beans-6.0.2.jar:6.0.2]
... 29 common frames omitted
This is my POM.xml
<?xml version="1.0" encoding="UTF-8"?>
<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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.rdeleon.app</groupId>
<artifactId>rest</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>RestAPI</name>
<description>Sample Crud Rest API</description>
<properties>
<java.version>17</java.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>javax.persistence-api</artifactId>
<version>2.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.30</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Api Application should open instead of throwing an error.
I face the same issue, I don't know what exact reason for this but I think this issue happen because of the "spring-boot-starter-parent" dependency version in pom.xml.
So you can try this dependency version in pom.xml that works for me.
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.1</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
So I have the same issues using this build
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
This does not happen when version changed to
<version>2.6.1</version>
Another fix I found that worked for 3.0.1,
the imports need to be changed from
import javax.persitence.*
import jakarta.persistence.*
So I think in your model class you are using javax instead of jakarta.
Also your POM.xml is using javax
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>javax.persistence-api</artifactId>
<version>2.2</version>
<scope>provided</scope>
</dependency>

Error occurs when call CuratorCache.start: Unable to read additional data from server sessionid

As the title says, something goes wrong when calling CuratorCache.start. The problem occurs in my project, so I create a small test project to reproduce it.
Env
jdk17(or jdk11)
spring-cloud-starter-zookeeper-all 3.1.0 (with curator-recipes 5.1.0) or curator-recipes 5.2.0
zookeeper 3.6.X or 3.7.0
MacOS Monterey or CentOS7.4
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>curator-test</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zookeeper-all</artifactId>
<version>3.1.0</version>
<exclusions>
<exclusion>
<artifactId>curator-recipes</artifactId>
<groupId>org.apache.curator</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>5.2.0</version>
</dependency>
</dependencies>
</project>
Preparing data
add some String to zookeeper path: /test/1
Test code
var curator = CuratorFrameworkFactory.builder()
.connectString("localhost:2181")
.retryPolicy(new ExponentialBackoffRetry(1000, 3))
.build();
curator.start();
var bytes = curator.getData().forPath("/test/1");
System.out.println("value for path /test/1 is " + new String(bytes));
var curatorCache = CuratorCache.builder(curator, "/test").build();
curatorCache.listenable().addListener(
CuratorCacheListener.builder()
.forCreates(node -> System.out.println(String.format("Node created: [%s]", node)))
.forChanges((oldNode, node) -> System.out.println(String.format("Node changed. Old: [%s] New: [%s]", oldNode, node)))
.forDeletes(oldNode -> System.out.println(String.format("Node deleted. Old value: [%s]", oldNode)))
.forInitialized(() -> System.out.println("Cache initialized"))
.build()
);
curatorCache.start();
The test codes mostly comes from CuratorCache Example from official, as the test code shows, I can read data from the zookeeper path, but when I call CuratorCache.start the exception is thrown:
2022-01-23 16:07:53.578 INFO 55099 --- [ main] org.apache.zookeeper.ClientCnxnSocket : jute.maxbuffer value is 1048575 Bytes
2022-01-23 16:07:53.579 INFO 55099 --- [ main] org.apache.zookeeper.ClientCnxn : zookeeper.request.timeout value is 0. feature enabled=false
2022-01-23 16:07:53.580 INFO 55099 --- [ main] o.a.c.f.imps.CuratorFrameworkImpl : Default schema
2022-01-23 16:07:53.586 INFO 55099 --- [16.153.68:2181)] org.apache.zookeeper.ClientCnxn : Opening socket connection to server 172.16.153.68/172.16.153.68:2181.
2022-01-23 16:07:53.586 INFO 55099 --- [16.153.68:2181)] org.apache.zookeeper.ClientCnxn : SASL config status: Will not attempt to authenticate using SASL (unknown error)
2022-01-23 16:07:53.588 INFO 55099 --- [16.153.68:2181)] org.apache.zookeeper.ClientCnxn : Socket connection established, initiating session, client: /192.168.195.34:49599, server: 172.16.153.68/172.16.153.68:2181
2022-01-23 16:07:53.639 INFO 55099 --- [16.153.68:2181)] org.apache.zookeeper.ClientCnxn : Session establishment complete on server 172.16.153.68/172.16.153.68:2181, session id = 0x1007127ce8c071d, negotiated timeout = 40000
2022-01-23 16:07:53.640 INFO 55099 --- [ain-EventThread] o.a.c.f.state.ConnectionStateManager : State change: CONNECTED
2022-01-23 16:07:53.644 INFO 55099 --- [ain-EventThread] o.a.c.framework.imps.EnsembleTracker : New config event received: {}
2022-01-23 16:07:53.644 INFO 55099 --- [ain-EventThread] o.a.c.framework.imps.EnsembleTracker : New config event received: {}
2022-01-23 16:07:53.829 WARN 55099 --- [ main] iguration$LoadBalancerCaffeineWarnLogger : Spring Cloud LoadBalancer is currently working with the default cache. You can switch to using Caffeine cache, by adding it and org.springframework.cache.caffeine.CaffeineCacheManager to the classpath.
2022-01-23 16:07:53.909 INFO 55099 --- [ main] org.test.Application : Started Application in 1.966 seconds (JVM running for 3.09)
2022-01-23 16:07:53.917 INFO 55099 --- [tor-Framework-0] o.a.c.f.imps.CuratorFrameworkImpl : backgroundOperationsLoop exiting
2022-01-23 16:07:53.929 WARN 55099 --- [16.153.68:2181)] org.apache.zookeeper.ClientCnxn : An exception was thrown while closing send thread for session 0x1007127ce8c071d.
org.apache.zookeeper.ClientCnxn$EndOfStreamException: Unable to read additional data from server sessionid 0x1007127ce8c071d, likely server has closed socket
at org.apache.zookeeper.ClientCnxnSocketNIO.doIO(ClientCnxnSocketNIO.java:77) ~[zookeeper-3.6.3.jar:3.6.3]
at org.apache.zookeeper.ClientCnxnSocketNIO.doTransport(ClientCnxnSocketNIO.java:350) ~[zookeeper-3.6.3.jar:3.6.3]
at org.apache.zookeeper.ClientCnxn$SendThread.run(ClientCnxn.java:1290) ~[zookeeper-3.6.3.jar:3.6.3]
2022-01-23 16:07:54.036 INFO 55099 --- [ain-EventThread] org.apache.zookeeper.ClientCnxn : EventThread shut down for session: 0x1007127ce8c071d
2022-01-23 16:07:54.036 INFO 55099 --- [ionShutdownHook] org.apache.zookeeper.ZooKeeper : Session: 0x1007127ce8c071d closed
So is there anybody has some idea, thanks for your comments.

Weblogic 12.1.3 + JAX-RS 2 + jersey multipart

I have a server Weblogic 12.1.3, with JAX-RS 2.x installed as a shared library (see e.g. https://docs.oracle.com/middleware/1213/wls/RESTF/use-jersey20-ri.htm#RESTF297). This shared library includes e.g. javax.ws.rs-api-2.0.jar and jersey-media-multipart-2.5.1.jar.
Please notice I am not sure that my webapp is really using this shared library, or it is using the standard JAX-RS 1.x library.
Now I want to upload files in multipart/form-data format, so I guess I need to add this dependency on my project:
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-multipart</artifactId>
<version>2.5.1</version>
<scope>provided</scope>
</dependency>
However, the deploy fails, with error:
java.lang.ClassNotFoundException: org.glassfish.jersey.media.multipart.FormDataContentDisposition
So, I thought I could put my own library within my webapp:
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-multipart</artifactId>
<version>2.5.1</version>
</dependency>
In this second case, the deploy fails with the following error:
java.lang.ClassNotFoundException: org.glassfish.jersey.ExtendedConfig
Any idea? Thank you.
At last, I got it work. I was missing both configuration in weblogic.xml and web.xml (I didn't know it was necessary web.xml).
Weblogic.xml:
<wls:weblogic-web-app xmlns:wls="http://xmlns.oracle.com/weblogic/weblogic-web-app" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd http://xmlns.oracle.com/weblogic/weblogic-web-app http://xmlns.oracle.com/weblogic/weblogic-web-app/1.9/weblogic-web-app.xsd">
<!-- Questo รจ per referenzialre la shared library jax-rs 2.x -->
<wls:library-ref>
<wls:library-name>jax-rs</wls:library-name>
<wls:specification-version>2</wls:specification-version>
<wls:implementation-version>2.5.1</wls:implementation-version>
<wls:exact-match>false</wls:exact-match>
</wls:library-ref>
<wls:container-descriptor>
<wls:prefer-application-packages>
<!-- apis -->
<wls:package-name>javax.ws.rs.*</wls:package-name>
<!-- guava -->
<wls:package-name>com.google.common.*</wls:package-name>
<!-- jersey1 providers -->
<wls:package-name>com.sun.jersey.*</wls:package-name>
<!-- media providers -->
<wls:package-name>org.eclipse.persistence.jaxb.rs.*</wls:package-name>
<wls:package-name>org.codehaus.jackson.jaxrs.*</wls:package-name>
<!-- wls -->
<wls:package-name>weblogic.jaxrs.api.client.*</wls:package-name>
<wls:package-name>weblogic.jaxrs.internal.api.client.*</wls:package-name>
<wls:package-name>weblogic.jaxrs.dispatch.*</wls:package-name>
<wls:package-name>weblogic.jaxrs.monitoring.util.*</wls:package-name>
</wls:prefer-application-packages>
</wls:container-descriptor>
<wls:context-root>uploader</wls:context-root>
</wls:weblogic-web-app>
Web.xml:
<servlet>
<servlet-name>JAX-RS</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer
</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>mypackage.jaxrs.JAXRSApplication
</param-value>
</init-param>
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>org.glassfish.jersey.filter.LoggingFilter;org.glassfish.jersey.media.multipart.MultiPartFeature
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>JAX-RS</servlet-name>
<url-pattern>/v1/*</url-pattern>
</servlet-mapping>
Notice in particular the reference to MultiPartFeature.
Edit
As I thought, the web.xml is not necessary. You can put all the properties inside the Application class. The configuration above is more or less equivalent to the following
#ApplicationPath("/v1")
public class JAXRSApplication extends Application {
#Override
public Map<String, Object> getProperties() {
Map<String, Object> properties = new HashMap<>();
properties.put("jersey.config.server.provider.packages", "mypackage");
properties.put("jersey.config.server.provider.classnames",
"org.glassfish.jersey.filter.LoggingFilter;org.glassfish.jersey.media.multipart.MultiPartFeature");
return properties;
}
}

Apache Kafka consumer client connecting to Apache Zookeeper: EndOfStreamException

I get an error when trying to 'consume' messages from Kafka (2.9.2-0.8.1) with a Zookeer stand-alone (3.4.5). You can see the source code below as well as the error message and logfile from Zookeeper.
I'm not sure if the Java libraries are incompatible, because I added dependency kafka_0.9.2 (0.8.1) via Maven which automatically resolved dependency of zkclient (0.3) and zookeeper (3.3.4).
The consumer source code:
import java.util.Properties;
import kafka.consumer.Consumer;
import kafka.consumer.ConsumerConfig;
import kafka.javaapi.consumer.ConsumerConnector;
public class ConsumerTest {
public static void main(String[] args)
{
try
{
Properties props = new Properties();
props.put("zookeeper.connect", "192.168.0.1:2181/kafka");
props.put("group.id", "my-consumer");
props.put("zookeeper.session.timeout.ms", "400");
props.put("zookeeper.sync.time.ms", "200");
props.put("auto.commit.interval.ms", "1000");
ConsumerConfig config = new ConsumerConfig(props);
#SuppressWarnings("unused")
ConsumerConnector consumer = Consumer.createJavaConsumerConnector(config);
}
catch(Exception e)
{
System.out.println(e.getMessage());
e.printStackTrace();
}
}
}
The 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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>test.my</groupId>
<artifactId>kafka-consumer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka_2.9.2</artifactId>
<exclusions>
<exclusion>
<artifactId>jms</artifactId>
<groupId>javax.jms</groupId>
</exclusion>
<exclusion>
<artifactId>jmxtools</artifactId>
<groupId>com.sun.jdmk</groupId>
</exclusion>
<exclusion>
<artifactId>jmxri</artifactId>
<groupId>com.sun.jmx</groupId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka_2.9.2</artifactId>
<version>0.8.1</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
The exception message and stack trace:
Unable to connect to zookeeper server within timeout: 400
org.I0Itec.zkclient.exception.ZkTimeoutException: Unable to connect to zookeeper server within timeout: 400
at org.I0Itec.zkclient.ZkClient.connect(ZkClient.java:880)
at org.I0Itec.zkclient.ZkClient.<init>(ZkClient.java:98)
at org.I0Itec.zkclient.ZkClient.<init>(ZkClient.java:84)
at kafka.consumer.ZookeeperConsumerConnector.connectZk(ZookeeperConsumerConnector.scala:156)
at kafka.consumer.ZookeeperConsumerConnector.<init>(ZookeeperConsumerConnector.scala:114)
at kafka.javaapi.consumer.ZookeeperConsumerConnector.<init>(ZookeeperConsumerConnector.scala:65)
at kafka.javaapi.consumer.ZookeeperConsumerConnector.<init>(ZookeeperConsumerConnector.scala:67)
at kafka.consumer.Consumer$.createJavaConsumerConnector(ConsumerConnector.scala:100)
at kafka.consumer.Consumer.createJavaConsumerConnector(ConsumerConnector.scala)
at ConsumerTest.main(ConsumerTest.java:23)
The zookeeper log:
2014-05-06 11:48:11,907 [myid:] - INFO [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181:NIOServerCnxnFactory#197] - Accepted socket connection from /192.168.0.4:52568
2014-05-06 11:48:11,909 [myid:] - WARN [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181:NIOServerCnxn#349] - caught end of stream exception
EndOfStreamException: Unable to read additional data from client sessionid 0x0, likely client has closed socket
at org.apache.zookeeper.server.NIOServerCnxn.doIO(NIOServerCnxn.java:220)
at org.apache.zookeeper.server.NIOServerCnxnFactory.run(NIOServerCnxnFactory.java:208)
at java.lang.Thread.run(Thread.java:701)
2014-05-06 11:48:11,909 [myid:] - INFO [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181:NIOServerCnxn#1001] - Closed socket connection for client /192.168.0.4:52568 (no session established for client)
Note I can successfully 'produce' and 'consume' messages from Kafka nodes with the command line tools:
$ sudo -u kafka bin/kafka-console-producer.sh --broker-list 192.168.0.2:9092,192.168.0.3:9092 --topic my-topic
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
This is a first message.
This is a second message.
$ sudo -u kafka bin/kafka-console-consumer.sh --zookeeper 192.168.0.1:2181/kafka --topic my-topic --from-beginning
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
This is a first message.
This is a second message.
I can even successfully produce messages from a Java client producer.
I had the same problem and I have solved it.The zookeeper timeout is too small.

Arquillian, tomee-embedded and JAX-RS

I am using Arquillian with a tomee-embedded container in order to test my JAX-RS web service. In my test case, I am running a jersey test client accessing the provided resource. However, the test always results in a 404 NOT FOUND status when accessing the resource.
When deploying the same project on my tomee-jaxrs instance, the resource is provided properly.
These are the maven dependencies that I've included in my test project:
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-server</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.apache.openejb</groupId>
<artifactId>arquillian-tomee-embedded</artifactId>
<version>${tomee.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.junit</groupId>
<artifactId>arquillian-junit-container</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.shrinkwrap.resolver</groupId>
<artifactId>shrinkwrap-resolver-depchain</artifactId>
<scope>test</scope>
<type>pom</type>
</dependency>
My test case looks as follows:
#RunWith(Arquillian.class)
public class DemoTest {
#Deployment
public static WebArchive createDeployment() throws Exception {
return ShrinkWrap.create(WebArchive.class).addPackage(Controller.class.getPackage()).setWebXML("ch/codenation/test/regression/resources/container/WEB-INF/web.xml");
}
#ArquillianResource
private URL url;
#Test
public void testGetData() throws Exception {
final IApplicationLayer applicationLayer = new JaxRsApplicationLayer(url.toURI());
final Callable<String> dataProvider = new DataProvider(applicationLayer);
Assert.assertEquals("asdf", dateProvider.call());
}
}
As well as my web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
<display-name>codenation-service</display-name>
<servlet>
<servlet-name>javax.ws.rs.core.Application</servlet-name>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>javax.ws.rs.core.Application</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
The JAX-RS resource is indeed unavailable, for when I put a breakpoint in the test method and try to access the resource in the browser, I receive a 404 message. Doing the same thing when deplyoing the archive to a tomee-jaxrs server works fine, however. Are there any additional maven dependencies or arquillian configuration settings I need to add here in order to make this work?
Thanks for any feedback and best regards
Pascal
Just include this in your pom.xml
<dependency>
<groupId>org.apache.openejb</groupId>
<artifactId>tomee-jaxrs</artifactId>
<version>${tomee.version}</version>
<scope>test</scope>
</dependency>
and you can work with the embedded TomEE.
There seems to be no way to switch the tomee-embedded adapter to a plus configuration. I therefore switched over to the tomee-remote adapter.