Schedule Task with Jax-RS and CDI - java

I'm try to understand how to manage scheduled tasks in my project with Jax-RS and CDI.
With Spring I was easily able to achive that with ThreadPoolTaskScheduler or #Scheduled annotation and I'm trying to replicate both ways without success.
First of all, I'm using Wildfly 14 and this seems to cause some issues because I've tryied to inject with #Resource both ManagedScheduledExecutorService and TimerService but Wildfly throws exception of missing dependencies (but the Admin guide didn't help me about that).
Instead of inject resources I've tryied to use a singleton object like this:
#Singleton
public class CacheManager {
private final static Logger log = LogManager.getLogger();
public CacheManager() {
log.error("######## Init" + LocalTime.now());
}
#Schedule(hour = "*", minute = "*", second = "*/1")
private void timeout() {
log.error("######## " + LocalTime.now());
}
}
But the method is never called.
So I'm not understanding what I'm missing. Maybe I have wrongly configured the project so this is my pom.xml dependencies:
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.10.2</version>
</dependency>
<!-- Import the JAX-RS API, we use provided scope as the API is included in JBoss WildFly -->
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<version>3.10.0.Final</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>jaxrs-api</artifactId>
<version>3.0.12.Final</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-multipart-provider</artifactId>
<version>3.0.12.Final</version>
<scope>provided</scope>
</dependency>
<!-- Import the CDI API, we use provided scope as the API is included in JBoss WildFly -->
<dependency>
<groupId>javax.enterprise</groupId>
<artifactId>cdi-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
<!-- Import the JSF API, we use provided scope as the API is included in JBoss WildFly -->
<dependency>
<groupId>org.jboss.spec.javax.faces</groupId>
<artifactId>jboss-jsf-api_2.2_spec</artifactId>
<version>2.2.14</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.11.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.11.2</version>
</dependency>
<dependency>
<groupId>javax.ejb</groupId>
<artifactId>ejb-api</artifactId>
<version>3.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
This is my beans.xml
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd" bean-discovery-mode="annotated">
</beans>
I am using Java 8.
EDIT: the CacheManager is instantiated in the JAX-WS Application
#ApplicationScoped
#ApplicationPath("/rest")
public class JaxRsActivator extends Application {
private static final Logger logger = LogManager.getLogger();
private Set<Object> singletons = new HashSet<Object>();
private HashSet<Class<?>> classes = new HashSet<Class<?>>();
public JaxRsActivator() {
singletons.add(new CorsFilter());
singletons.add(new CacheManager());
}
#Override
public Set<Object> getSingletons() {
return singletons;
}
#Override
public HashSet<Class<?>> getClasses(){
return classes;
}
}

I've found the solutions: #Singleton must be javax.ejb.Singleton and not javax.inject.Singleton.

Related

Springboot Actuator Refresh does not reload #Value properties in #ConfigurationProperties

I have a springboot application that ingests an application.properties via #ConfigurationProperties and #PropertySource("classpath:application.properties"). My desire is to reload these properties on the fly for the purposes of support. When I POST to http://localhost:8080/actuator/refresh I get a 200 OK response but the body is empty, which I think implies no #RefreshScopes have been refreshed but I'm not sure. I have read and viewed most docs and SO while trying various things but haven't managed to reload a new value.
Here is my app:
application.properties:
# suppress inspection "UnusedProperty" for whole file
# the name of Camel
camel.springboot.name = IntegrationsCamel
# how often to trigger the timer (millis)
myPeriod = 2000
spring.main.allow-bean-definition-overriding=true
# to turn off Camel info in (/actuator/info)
management.info.camel.enabled=false
# to configure logging levels
logging.level.org.springframework = INFO
logging.level.org.apache.camel.spring.boot = INFO
logging.level.org.apache.camel.impl = DEBUG
logging.level.sample.camel = DEBUG
# Environment
integration.env = DEV
spring.application.name = integration
spring.config.import=aws-parameterstore:
# Client API Auth -- Set by Instance
integration.client.auth.key = tempclientkey
integration.client.auth.secret = tempclientsecret
# Client API Credentials -- Set by Instance
integration.client.endpoint = https://127.0.0.2
integration.client.port = 6060
# AWS Paramstore Config
aws.paramstore.enabled=true
aws.paramstore.prefix=/integration
aws.paramstore.defaultContext=application
aws.paramstore.profile-separator=_
# AWS OAuth
cloud.aws.credentials.instance-profile=true
cloud.aws.credentials.profile-name=default
cloud.aws.credentials.access-key=${AWS_ACCESS_KEY_ID}
cloud.aws.credentials.secret-key=${AWS_SECRET_ACCESS_KEY}
# Non EC2 vars (remove when running live)
cloud.aws.stack.auto=false
cloud.aws.region.static=eu-west-1
AWS_EC2_METADATA_DISABLED=true
logging.level.com.amazonaws.util.EC2MetadataUtils=error
logging.level.com.amazonaws.internal.InstanceMetadataServiceResourceFetcher=error
# DB Vars
spring.datasource.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriver
spring.datasource.url=jdbc:sqlserver://${RDS_HOSTNAME:my-server-domain.com}:${RDS_PORT:1337};databaseName=${RDS_DB_NAME:MYDB}
spring.datasource.username=${RDS_USERNAME:readuser}
spring.datasource.password=${RDS_PASSWORD:${read_pass}}
spring.jpa.properties.hibernate.default_schema=dbo
# Actuator Management
management.endpoints.enabled-by-default=false
management.endpoint.refresh.enabled=true
management.endpoints.web.exposure.include=refresh
All of these are successfully pulled in to the bean
package com.Integration.Configuration;
import lombok.Getter;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.cloud.context.scope.refresh.RefreshScopeRefreshedEvent;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.event.EventListener;
#Getter
#Setter
#RefreshScope
#Configuration
public class ApplicationProperties {
#Value("${integration.env}")
private String env;
#Value("${spring.datasource.url}")
private String DB_URL;
#Value("${rds-username}")
private String DB_USERNAME;
#Value("${rds-password}")
private String DB_ENCRYPTED_PASSWORD;
#Value("${oauth2.key}")
private String OAuth2Key;
#Value("${oauth2.secret}")
private String OAuth2Secret;
#Value("${integration.client.endpoint}")
private String ClientAPIEndpoint;
#Value("${integration.client.port}")
private String ClientAPIPort;
#Value("${integration.client.auth.key}")
private String ClientAPIKey;
#Value("${integration.client.auth.secret}")
private String ClientAPISecret;
public ApplicationProperties() {}
#SuppressWarnings("unused")
#EventListener(RefreshScopeRefreshedEvent.class)
public void onRefresh(RefreshScopeRefreshedEvent event) {
// todo: Bug-#01 #RefreshScope actuator/refresh not updating #Values
System.out.println(this.ClientAPIEndpoint);
}
}
The event listener fires without issue too and it will successfully print the value from application.properties. I have debugged main below and all values are populated without issue.
I suspect the issue is here but I'm not sure what I'm doing wrong in main()
package com.Integration;
import com.Integration.AutoLoader.RouteBuilderAutoLoader;
import com.Integration.Configuration.ApplicationProperties;
import com.Integration.Scheduler.TasksScheduler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ConfigurableApplicationContext;
import org.apache.camel.CamelContext;
import org.apache.camel.impl.DefaultCamelContext;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import java.util.Objects;
#SpringBootApplication
#RefreshScope
#EnableScheduling
public class Integration {
public static String SERVER_ADDR;
protected static CamelContext context;
public static void main(String[] args) throws Exception {
// Spring Boot App Entry
ConfigurableApplicationContext appContext = SpringApplication.run(Integration.class, args);
// Get ApplicationProperties
ApplicationProperties properties = appContext.getBean(ApplicationProperties.class);
SERVER_ADDR = (Objects.equals(properties.getEnv(), "DEV")) ? "0.0.0.0" : "localhost";
// Start Camel Context Engine
context = new DefaultCamelContext();
// Feed Camel our defined routes & start
RouteBuilderAutoLoader.loadRoutes(context);
context.start();
}
}
The last thing I'm unsure of is if I have the necessary dependencies or if I'm missing something here.
<?xml version="1.0" encoding="UTF-8"?>
<!--suppress MavenPackageUpdate -->
<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>com.Integration</groupId>
<artifactId>Integration</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Integration</name>
<description>Generic API Integration App</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR12</spring-cloud.version>
</properties>
<dependencies>
<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>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>2.6.5</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<version>2.6.5</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.2.4.Final</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.21</version>
</dependency>
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>9.4.1.jre8</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2021.0.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- AWS/Cloud -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-aws</artifactId>
<version>2.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>io.awspring.cloud</groupId>
<artifactId>spring-cloud-aws-context</artifactId>
<version>2.4.0</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
<version>3.1.1</version>
</dependency>
<dependency>
<groupId>io.awspring.cloud</groupId>
<artifactId>spring-cloud-starter-aws-parameter-store-config</artifactId>
<version>2.4.0</version>
</dependency>
<!-- Camel 3.14.1 Latest LTS version -->
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-spring-boot-bom</artifactId>
<version>3.14.1</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
<version>3.14.1</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core-languages</artifactId>
<version>3.14.1</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-bean</artifactId>
<version>3.14.1</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-rest</artifactId>
<version>3.14.1</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-direct</artifactId>
<version>3.14.1</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-netty-http</artifactId>
<version>3.14.1</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-platform-http</artifactId>
<version>3.14.1</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-management</artifactId>
<version>3.14.1</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-endpointdsl</artifactId>
<version>3.14.1</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-spring</artifactId>
</dependency>
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<version>4.3.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
</project>
Edit 12/04/2022
Completely redid my classes with #ConfigurationProperties
So when I post to refresh the values in propertySource for AWS automatically update. So eg I change cobaltdlt to cobaltdlttest below, hit refresh, and then I can see the change when I query GET http://localhost:8080/actuator/env
So the refresh is working but it's not reflective in the #Component beans even though the propertySource is updating. In fact the only beans it is working with are the AWS beans.
Have you tried a PropertiesConfiguration bean? See here: https://www.baeldung.com/spring-reloading-properties.
Once configured correctly, it should automatically read changes to your properties file and reload them. Also, there are some limitations that are mentioned in that article that you should be aware of.
#I2obiN. As you have mentioned that ApplicationProperties is getting refreshed by Refresh Scopes, therefore actuator refresh is working properly.
But I noticed that you are using RefreshScope on main application class. IMO this actuator management/refresh will not restart application. You can try to create an extra method that reinitializes Camel Context.
Hope this helps!!
https://www.baeldung.com/java-restart-spring-boot-app#actuators-restart-endpoint
You can invoke the refresh Actuator endpoint by sending an empty HTTP POST to the client's refresh endpoint: http://localhost:8080/actuator/refresh . Then you can confirm it worked by visiting the http://localhost:8080/message endpoint.
And once you refresh, try to rebind immediately by calling the POST endpoint http://localhost:8080/actuator/env
This worked on a spring boot I tried and it reloads the values and you can see it in the stack trace.
I tried doing a field in spring data source with the given payload to Rebind and it reloads Example as the value.
Payload:
{"name":"spring.datasource.userName", "value":"Example"}
In the application.properties, add the following
management.endpoint.env.post.enabled=true
management.endpoint.restart.enabled=true
endpoints.sensitive=true
endpoints.actuator.enabled=true
management.security.enabled=false
management.endpoints.web.exposure.include=*

Spring cache Caffeine integration without SpringBoot

I want to integrate Caffeine Cache in my Spring 5 application. I know that I need the CaffeineCacheManager, but i dont have the class. The only way i found is to add the SpringBoot Starter Cache package to the pom, but i dont want to use Spring Boot.
I have this Spring packages in my pom:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-web -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>5.3.3.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-config -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>5.3.3.RELEASE</version>
</dependency>
Is any way to have CaffeineCacheManager class wihouth Spring Boot? Thanks.
Actually i am using this code to configure the cache:
#Bean
public CacheManager cacheManager() {
SimpleCacheManager cacheManager = new SimpleCacheManager();
cacheManager.setCaches(Arrays.asList(
new ConcurrentMapCache(
"categorias",
Caffeine.newBuilder().expireAfterWrite(Duration.ofDays(1)).maximumSize(100).build().asMap(),
false
),
new ConcurrentMapCache(
"ciudad",
Caffeine.newBuilder().maximumSize(100).build().asMap(),
false
)
));
return cacheManager;
}
The main spring cache implementation is located in spring-context dependency. You should only setup that cache manager and use #Cacheable annotation.
For examples see: https://www.baeldung.com/spring-cache-tutorial
Let me know if you need code example of connection Caffeine cache with spring cache mechanism.
CaffeineCacheManager configuration:
CaffeineCacheManager is located in
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
And caffeine dependency:
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>2.8.8</version>
</dependency>
Configuration:
#Configuration
#EnableCaching
public class Config {
#Bean
public Caffeine<Object, Object> caffeineConfig() {
return Caffeine.newBuilder().expireAfterWrite(60, TimeUnit.MINUTES);
}
#Bean
public CacheManager cacheManager(Caffeine<Object, Object> caffeine) {
CaffeineCacheManager caffeineCacheManager = new CaffeineCacheManager();
caffeineCacheManager.setCaffeine(caffeine);
return caffeineCacheManager;
}
}

Swagger ApiListingResource is not recognized as a valid resource

I'm trying to integrate Swagger into my Jersey application following the guide they provide: https://github.com/swagger-api/swagger-core/wiki/Swagger-Core-Jersey-1.X-Project-Setup-1.5
I'm using Jersy v1.17 and I'm using a custom application rather than web.xml
The following is everything I have in my simple test project which is failing!
public class ResConfig extends DefaultResourceConfig { // custom app
public ResConfig() {
super();
BeanConfig beanConfig = new BeanConfig();
beanConfig.setVersion("1.0.2");
beanConfig.setSchemes(new String[] { "http" });
beanConfig.setHost("localhost:9998");
beanConfig.setBasePath("/api");
beanConfig.setResourcePackage("test.resources"); // the package containing my resource
beanConfig.setScan(true);
}
}
The simple resource I have
#Path("hello")
#Produces("application/json")
public class Res {
public Res() {
}
#GET
public Response getHello() {
Result result = new Result(); // Result is annotated with XmlRootElement and contains one field String str;
result.setStr("hello");
return Response.status(Status.OK).entity(result).build();
}
}
The main:
public static void main(String[] args) throws Exception {
ResConfig resConfig = new ResConfig();
resConfig.getClasses().add(Res.class);
resConfig.getClasses().add(io.swagger.jaxrs.listing.ApiListingResource.class);
resConfig.getClasses().add(io.swagger.jaxrs.listing.SwaggerSerializers.class);
GrizzlyServerFactory.createHttpServer("http://localhost:9998/", resConfig);
System.in.read();
}
the POM contains the following:
<dependencies>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-jersey-jaxrs</artifactId>
<version>1.5.9</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-core</artifactId>
<version>${jersey-version}</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
<version>${jersey-version}</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-servlet</artifactId>
<version>${jersey-version}</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
<version>${jersey-version}</version>
</dependency>
<dependency>
<groupId>com.sun.jersey.contribs</groupId>
<artifactId>jersey-multipart</artifactId>
<version>${jersey-version}</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-grizzly2</artifactId>
<version>${jersey-version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
</dependencies>
The Jersey Grizzly server fails on start by throwing exception:
SEVERE: The following errors and warnings have been detected with resource and/or provider classes:
SEVERE: Missing dependency for method public javax.ws.rs.core.Response io.swagger.jaxrs.listing.ApiListingResource.getListing(javax.ws.rs.core.Application,javax.servlet.ServletConfig,javax.ws.rs.core.HttpHeaders,javax.ws.rs.core.UriInfo,java.lang.String) at parameter at index 1
SEVERE: Method, public javax.ws.rs.core.Response io.swagger.jaxrs.listing.ApiListingResource.getListing(javax.ws.rs.core.Application,javax.servlet.ServletConfig,javax.ws.rs.core.HttpHeaders,javax.ws.rs.core.UriInfo,java.lang.String), annotated with GET of resource, class io.swagger.jaxrs.listing.ApiListingResource, is not recognized as valid resource method.
SEVERE: Missing dependency for field: javax.servlet.ServletContext io.swagger.jaxrs.listing.ApiListingResource.context
Exception in thread "main" com.sun.jersey.spi.inject.Errors$ErrorMessagesException
at com.sun.jersey.spi.inject.Errors.processErrorMessages(Errors.java:170)
at com.sun.jersey.spi.inject.Errors.postProcess(Errors.java:136)
at com.sun.jersey.spi.inject.Errors.processWithErrors(Errors.java:199)
at com.sun.jersey.server.impl.application.WebApplicationImpl.initiate(WebApplicationImpl.java:795)
at com.sun.jersey.api.container.ContainerFactory.createContainer(ContainerFactory.java:172)
at com.sun.jersey.api.container.ContainerFactory.createContainer(ContainerFactory.java:134)
at com.sun.jersey.api.container.grizzly2.GrizzlyServerFactory.createHttpServer(GrizzlyServerFactory.java:243)
at com.sun.jersey.api.container.grizzly2.GrizzlyServerFactory.createHttpServer(GrizzlyServerFactory.java:137)
I searched the first 2 pages of Google for an answer but nothing helped!
Swagger uses Servlet APIs, so the application MUST run in a servlet environment. The way you are configuring Grizzly does not set up a servlet container. It is only an HTTP server.
You want to use the jersey-grizzly2-servlet dependency instead, and use the GrizzlyWebContainerFactory to bootstrap the application. This will set up a servlet container.
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-grizzly2-servlet</artifactId>
<version>1.19.1</version>
</dependency>
Map<String, String> initParams = new HashMap<>();
initParams.put("javax.ws.rs.Application", "com.package.ResConfig");
GrizzlyWebContainerFactory.create(uri, initParams);

Spring 4.2.3 with Hibernate validator 5.2.2.Final does not work

I am trying to integration Spring 4.2.3 with hibernate validator v.5.2.2.Final to validate input JSON data expose with REST Controller.
I don't see any compile time or running time exception but at the same time it does not validate input data.
Pom.xml
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.2.3.RELEASE</version>
<scope>compile</scope>
</dependency>
<!-- jsr303 validation dependencies -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.2.2.Final</version>
</dependency>
<dependency>
<groupId>javax.el</groupId>
<artifactId>javax.el-api</artifactId>
<version>2.2.4</version>
</dependency>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>javax.el</artifactId>
<version>2.2.4</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator-cdi</artifactId>
<version>5.2.2.Final</version>
</dependency>
Pojo java class:
public class RequestVO {
#NotEmpty
private String testValidation;
#NotNull
private String testNull;
#NotBlank
private String testBlank;
.... getters and setters .....
}
#Controller
#RequestMapping("/login")
public class LoginController {
#RequestMapping(method=RequestMethod.POST, value="/user")
public #ResponseBody ResponseVO getLoginResponse(#Valid #RequestBody RequestVO request, Errors error) {
ResponseVO response = new ResponseVO ();
if (error.hasErrors()) {
System.err.println("Success");
}
return response;
}
}
In your dependency list there's a comment saying ...jsr303 validation dependencies.... Note the bean validation has an updated specification (JSR-349), and this can very well be your issue.
You should align your dependencies in the following manner
hibernate-validator-5.x.x
validation-api-1.1.x
which implement JSR-349
OR
hibernate-validator-4.x.x
validation-api-1.0.x.
which implements JSR-303
If you mix the dependencies, the validation will simply not kick-in. As a solution suggestion, add
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.1.0.Final</version>
</dependency>
and make sure that you remove any dependency to validation-api-1.0 jar
I think is interest to take a look at this link
and if you to remove the validation just remove #Valid from method and you're ok.

Spring 3 with Drools 6 maven inconcistency

I have a problem integrating Drools with Spring. I am trying to make a simple Hello World spring example, I reached a moment where my simple project refuses to compile.
To work with Drools annotations like #KSession I need the drools-spring package, but it seems incompatible with Spring 3. As builder I use Maven. Here is how my .pom's looks like:
<dependencies>
<!-- Drools -->
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-compiler</artifactId>
<version>6.0.0.Final</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-core</artifactId>
<version>6.0.0.Final</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-decisiontables</artifactId>
<version>6.0.0.Final</version>
</dependency>
<dependency>
<groupId>org.kie</groupId>
<artifactId>kie-api</artifactId>
<version>6.0.0.Final</version>
</dependency>
<dependency>
<groupId>org.kie</groupId>
<artifactId>kie-internal</artifactId>
<version>6.0.0.Final</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-spring</artifactId>
<version>6.0.0.Beta2</version>
</dependency>
<!-- Inject -->
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
<!-- Spring 3 dependencies -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>3.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>3.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>3.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>3.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>3.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>3.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>3.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>3.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>3.2.4.RELEASE</version>
</dependency>
</dependencies>
I use very simple case of controller class:
#Controller
#RequestMapping(value = "/")
public class BaseController extends AbstractController {
private static final Logger log = Logger.getLogger(BaseController.class);
#Autowired
#KSession("ksession-rules")
KieSession mySession;
#RequestMapping(value = "/test")
public #ResponseBody
String test() {
Fact myFact = new Fact();
myFact.setFactNumber(20); //According to my rule when myFact.number>20
//then result will be set to "Hello World"
mySession.insert(myFact);
mySession.fireAllRules();
return myFact.getResult();
}
}
At this point I receive an error:
"The hierarchy of the type BaseController is inconsistent".
I noticed that if I remove drools-spring from the dependency list the project compiles successfully. However without that package I cannot deploy my project, because the deployer demands the drools' class responsible for interpreting #KSession and that class is located in drools-spring package.
After some investigation it appears that my Drools session configuration seems to have
nothing to do with the error above, so for the sake of succinctness I will not quote them. Instead of that I will mark that even if I don't make any modifications to the spring configuration and remove the KieSession from my example, making it a simple spring hello world example, I receive one and the same error out of my IDE (Eclipse): "The hierarchy of the type BaseController is inconsistent" and if I remove the drools-spring dependency the problem disappears.
It seems to me as dependency conflict.
Does anyone experienced similar problems with drools+spring?
Can someone suggest a solution to the problem?
Am I doing something wrong?
Thanks for the help!
After some research I found two things.
Drools' drools-spring package declares its own spring dependencies that are overriding my spring dependencies, which leads to spring malunctions. What I did is to manually remove the spring dependencies from drools-spring .pom file.
Another mistake that I had in the upper example is that I didn't have kie-spring as dependency. Kie-spring is mandatory for one drools bean KModuleBeanFactoryPostProcessor, which is responsible to read my kmodule-kbase-ksession configuration from the spring configuration.
After resolving these two problems my project compiles now and I can see in the code that KModuleBeanFactoryPostProcessor defines that my configuration is being read and analized as I expected it to be.

Categories

Resources