Method invocation failure JAX-RS / Wildfly / Java SDK13 with interceptor - java

I've added an interceptor to my JAX-RS / Resteasy Java SDK13 project running on Wildfly 18 in order to use annotations (e.g. #RolesAllowed). While the security implementation is way better than the programmatic approach, I'm getting an invocation error when Resteasy tries to call the matched function (deleteAll()). I've traced through the Interceptor flow just prior to the attempted invocation and the Interceptor approves the user and passes control onward. Then I get this error, which seems to be a security failure, despite my interceptor having approved the user.
I changed the Wildfly setting
<default-missing-method-permissions-deny-access value="false"/> but this hasn't changed the behavior.
Java Source being called with /consumers/deleteall with nothing in the body and no query string.
Security Interceptor
#Provider
#ServerInterceptor
public class SecurityInterceptor implements ContainerRequestFilter
{
private static final String AUTHORIZATION_PROPERTY = "Authorization";
private static final String AUTHENTICATION_SCHEME = "xxx";
private static final ServerResponse ACCESS_DENIED = new ServerResponse("Access denied for this resource", 401, new Headers<Object>());;
private static final ServerResponse ACCESS_FORBIDDEN = new ServerResponse("Nobody can access this resource", 403, new Headers<Object>());;
private static final ServerResponse SERVER_ERROR = new ServerResponse("INTERNAL SERVER ERROR", 500, new Headers<Object>());;
#Inject
private GenericUserDAO guDAO;
#Override
public void filter(ContainerRequestContext requestContext)
{
ResourceMethodInvoker methodInvoker = (ResourceMethodInvoker) requestContext.getProperty("org.jboss.resteasy.core.ResourceMethodInvoker");
Method method = methodInvoker.getMethod();
if (method != null)
System.out.println("Access attempt to "+method.getName());
//Access allowed for all
if( ! method.isAnnotationPresent(PermitAll.class))
{
//Access denied for all
if(method.isAnnotationPresent(DenyAll.class))
{
requestContext.abortWith(ACCESS_FORBIDDEN);
return;
}
//Get request headers
final MultivaluedMap<String, String> headers = requestContext.getHeaders();
//Fetch authorization header
final List<String> authorization = headers.get(AUTHORIZATION_PROPERTY);
//If no authorization information present; block access
if(authorization == null || authorization.isEmpty())
{
requestContext.abortWith(ACCESS_DENIED);
return;
}
//Get encoded username and password
final String token = authorization.get(0).replaceFirst(AUTHENTICATION_SCHEME + " ", "");
//Verify user access
if(method.isAnnotationPresent(RolesAllowed.class))
{
RolesAllowed rolesAnnotation = method.getAnnotation(RolesAllowed.class);
Set<String> rolesSet = new HashSet<String>(Arrays.asList(rolesAnnotation.value()));
//Is user valid?
if( ! isUserAllowed(token, rolesSet))
{
requestContext.abortWith(ACCESS_DENIED);
return;
}
}
}
System.out.println("approved");
}
private boolean isUserAllowed(final String token, final Set<String> rolesSet)
{
User user = guDAO.findUserByToken(token);
if (user.getClass() == SuperUser.class)
return true;
String userRole = user.getClass().getSimpleName();
System.out.println("User role is "+userRole+" Role set is "+rolesSet.toString());
return rolesSet.contains(userRole);
}
}
JAX_RS Handlers
#LocalBean
#Stateless
#Path("/consumers")
#RolesAllowed({"SuperUser","Consumer"})
public class ConsumerEndpoint extends UserEndpoint {
/**
* Delete all consumers
* #param token
* #return
*/
#DELETE
#Path("/deleteall")
#RolesAllowed({"SuperUser","Consumer"})
public Response deleteAll() {
Response.ResponseBuilder builder = null;
if (!consumerDAO.deleteAll()) {
Map<String, String> responseObj = new HashMap<String, String>();
responseObj.put("error", "Error executing deletion");
builder = Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(responseObj);
return builder.build();
}
return Response.ok().build();
}
}
LOG DATA
23:29:23,661 ERROR [org.jboss.as.ejb3.invocation] (default task-1) WFLYEJB0034: EJB Invocation failed on component ConsumerEndpoint for method public javax.ws.rs.core.Response com.eventhorizon.eva.rest.responder.ConsumerEndpoint.deleteAll(): javax.ejb.EJBAccessException: WFLYEJB0364: Invocation on method: public javax.ws.rs.core.Response com.eventhorizon.eva.rest.responder.ConsumerEndpoint.deleteAll() of bean: ConsumerEndpoint is not allowed
at org.jboss.as.ejb3#18.0.0.Final//org.jboss.as.ejb3.security.AuthorizationInterceptor.processInvocation(AuthorizationInterceptor.java:134)
at org.jboss.invocation#1.5.2.Final//org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:422)
23:29:23,665 ERROR [io.undertow.request] (default task-1) UT005023: Exception handling request to /eva/rest/consumers/deleteall: org.jboss.resteasy.spi.UnhandledException: javax.ejb.EJBAccessException: WFLYEJB0364: Invocation on method: public javax.ws.rs.core.Response com.eventhorizon.eva.rest.responder.ConsumerEndpoint.deleteAll() of bean: ConsumerEndpoint is not allowed
at org.jboss.resteasy.resteasy-jaxrs#3.9.0.Final//org.jboss.resteasy.core.ExceptionHandler.handleApplicationException(ExceptionHandler.java:82)
at org.jboss.resteasy.resteasy-jaxrs#3.9.0.Final//org.jboss.resteasy.core.ExceptionHandler.handleException(ExceptionHandler.java:346)
at org.jboss.resteasy.resteasy-jaxrs#3.9.0.Final//org.jboss.resteasy.core.SynchronousDispatcher.writeException(SynchronousDispatcher.java:193)
at org.jboss.resteasy.resteasy-jaxrs#3.9.0.Final//org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:456)
at org.jboss.resteasy.resteasy-jaxrs#3.9.0.Final//org.jboss.resteasy.core.SynchronousDispatcher.lambda$invoke$4(SynchronousDispatcher.java:229)
at org.jboss.resteasy.resteasy-jaxrs#3.9.0.Final//org.jboss.resteasy.core.SynchronousDispatcher.lambda$preprocess$0(SynchronousDispatcher.java:135)
at org.jboss.resteasy.resteasy-jaxrs#3.9.0.Final//org.jboss.resteasy.core.interception.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:356)
at org.jboss.resteasy.resteasy-jaxrs#3.9.0.Final//org.jboss.resteasy.core.SynchronousDispatcher.preprocess(SynchronousDispatcher.java:138)
at org.jboss.resteasy.resteasy-jaxrs#3.9.0.Final//org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:215)
at org.jboss.resteasy.resteasy-jaxrs#3.9.0.Final//org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:227)
at org.jboss.resteasy.resteasy-jaxrs#3.9.0.Final//org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:56)
at org.jboss.resteasy.resteasy-jaxrs#3.9.0.Final//org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:51)
at javax.servlet.api#2.0.0.Final//javax.servlet.http.HttpServlet.service(HttpServlet.java:590)
at io.undertow.servlet#2.0.26.Final//io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:74)
at io.undertow.servlet#2.0.26.Final//io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129)
at io.opentracing.contrib.opentracing-jaxrs2//io.opentracing.contrib.jaxrs2.server.SpanFinishingFilter.doFilter(SpanFinishingFilter.java:52)
at io.undertow.servlet#2.0.26.Final//io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
at io.undertow.servlet#2.0.26.Final//io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
at io.undertow.servlet#2.0.26.Final//io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84)
at io.undertow.servlet#2.0.26.Final//io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
at io.undertow.servlet#2.0.26.Final//io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68)
at io.undertow.servlet#2.0.26.Final//io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
at org.wildfly.extension.undertow#18.0.0.Final//org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)
at io.undertow.core#2.0.26.Final//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.servlet#2.0.26.Final//io.undertow.servlet.handlers.RedirectDirHandler.handleRequest(RedirectDirHandler.java:68)
at io.undertow.servlet#2.0.26.Final//io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:132)
at io.undertow.servlet#2.0.26.Final//io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
at io.undertow.core#2.0.26.Final//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.core#2.0.26.Final//io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
at io.undertow.servlet#2.0.26.Final//io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
at io.undertow.core#2.0.26.Final//io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
at io.undertow.servlet#2.0.26.Final//io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
at io.undertow.core#2.0.26.Final//io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50)
at io.undertow.core#2.0.26.Final//io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
at io.undertow.core#2.0.26.Final//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at org.wildfly.extension.undertow#18.0.0.Final//org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
at io.undertow.core#2.0.26.Final//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at org.wildfly.extension.undertow#18.0.0.Final//org.wildfly.extension.undertow.deployment.GlobalRequestControllerHandler.handleRequest(GlobalRequestControllerHandler.java:68)
at io.undertow.core#2.0.26.Final//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.core#2.0.26.Final//io.undertow.server.handlers.MetricsHandler.handleRequest(MetricsHandler.java:64)
at io.undertow.servlet#2.0.26.Final//io.undertow.servlet.core.MetricsChainHandler.handleRequest(MetricsChainHandler.java:59)
at io.undertow.servlet#2.0.26.Final//io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:269)
at io.undertow.servlet#2.0.26.Final//io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:78)
at io.undertow.servlet#2.0.26.Final//io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:133)
at io.undertow.servlet#2.0.26.Final//io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:130)
at io.undertow.servlet#2.0.26.Final//io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48)
at io.undertow.servlet#2.0.26.Final//io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
at org.wildfly.extension.undertow#18.0.0.Final//org.wildfly.extension.undertow.security.SecurityContextThreadSetupAction.lambda$create$0(SecurityContextThreadSetupAction.java:105)
at org.wildfly.extension.undertow#18.0.0.Final//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1504)
at org.wildfly.extension.undertow#18.0.0.Final//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1504)
at org.wildfly.extension.undertow#18.0.0.Final//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1504)
at org.wildfly.extension.undertow#18.0.0.Final//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1504)
at org.wildfly.extension.undertow#18.0.0.Final//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1504)
at io.undertow.servlet#2.0.26.Final//io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:249)
at io.undertow.servlet#2.0.26.Final//io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:78)
at io.undertow.servlet#2.0.26.Final//io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:99)
at io.undertow.core#2.0.26.Final//io.undertow.server.Connectors.executeRootHandler(Connectors.java:376)
at io.undertow.core#2.0.26.Final//io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:830)
at org.jboss.threads#2.3.3.Final//org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
at org.jboss.threads#2.3.3.Final//org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1982)
at org.jboss.threads#2.3.3.Final//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1486)
at org.jboss.threads#2.3.3.Final//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1377)
at java.base/java.lang.Thread.run(Thread.java:830)
Caused by: javax.ejb.EJBAccessException: WFLYEJB0364: Invocation on method: public javax.ws.rs.core.Response com.eventhorizon.eva.rest.responder.ConsumerEndpoint.deleteAll() of bean: ConsumerEndpoint is not allowed
at org.jboss.as.ejb3#18.0.0.Final//org.jboss.as.ejb3.security.AuthorizationInterceptor.processInvocation(AuthorizationInterceptor.java:134)
at org.jboss.invocation#1.5.2.Final//org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:422)
at org.jboss.as.ejb3#18.0.0.Final//org.jboss.as.ejb3.security.SecurityContextInterceptor.processInvocation(SecurityContextInterceptor.java:100)
at org.jboss.invocation#1.5.2.Final//org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:422)
at org.jboss.as.ejb3#18.0.0.Final//org.jboss.as.ejb3.deployment.processors.StartupAwaitInterceptor.processInvocation(StartupAwaitInterceptor.java:22)
at org.jboss.invocation#1.5.2.Final//org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:422)
at org.jboss.as.ejb3#18.0.0.Final//org.jboss.as.ejb3.component.interceptors.ShutDownInterceptorFactory$1.processInvocation(ShutDownInterceptorFactory.java:64)
at org.jboss.invocation#1.5.2.Final//org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:422)
at org.jboss.as.ejb3#18.0.0.Final//org.jboss.as.ejb3.component.interceptors.LoggingInterceptor.processInvocation(LoggingInterceptor.java:67)
at org.jboss.invocation#1.5.2.Final//org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:422)
at org.jboss.as.ee#18.0.0.Final//org.jboss.as.ee.component.NamespaceContextInterceptor.processInvocation(NamespaceContextInterceptor.java:50)
at org.jboss.invocation#1.5.2.Final//org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:422)
at org.jboss.invocation#1.5.2.Final//org.jboss.invocation.ContextClassLoaderInterceptor.processInvocation(ContextClassLoaderInterceptor.java:60)
at org.jboss.invocation#1.5.2.Final//org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:422)
at org.jboss.invocation#1.5.2.Final//org.jboss.invocation.InterceptorContext.run(InterceptorContext.java:438)
at org.wildfly.security.elytron-private#1.10.3.Final//org.wildfly.security.manager.WildFlySecurityManager.doChecked(WildFlySecurityManager.java:627)
at org.jboss.invocation#1.5.2.Final//org.jboss.invocation.AccessCheckingInterceptor.processInvocation(AccessCheckingInterceptor.java:57)
at org.jboss.invocation#1.5.2.Final//org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:422)
at org.jboss.invocation#1.5.2.Final//org.jboss.invocation.ChainedInterceptor.processInvocation(ChainedInterceptor.java:53)
at org.jboss.as.ee#18.0.0.Final//org.jboss.as.ee.component.ViewService$View.invoke(ViewService.java:198)
at org.jboss.as.ee#18.0.0.Final//org.jboss.as.ee.component.ViewDescription$1.processInvocation(ViewDescription.java:185)
at org.jboss.as.ee#18.0.0.Final//org.jboss.as.ee.component.ProxyInvocationHandler.invoke(ProxyInvocationHandler.java:81)
at deployment.eva.war//com.eventhorizon.eva.rest.responder.ConsumerEndpoint$$$view8.deleteAll(Unknown Source)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:567)
at org.jboss.resteasy.resteasy-jaxrs#3.9.0.Final//org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:138)
at org.jboss.resteasy.resteasy-jaxrs#3.9.0.Final//org.jboss.resteasy.core.ResourceMethodInvoker.internalInvokeOnTarget(ResourceMethodInvoker.java:517)
at org.jboss.resteasy.resteasy-jaxrs#3.9.0.Final//org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTargetAfterFilter(ResourceMethodInvoker.java:406)
at org.jboss.resteasy.resteasy-jaxrs#3.9.0.Final//org.jboss.resteasy.core.ResourceMethodInvoker.lambda$invokeOnTarget$0(ResourceMethodInvoker.java:370)
at org.jboss.resteasy.resteasy-jaxrs#3.9.0.Final//org.jboss.resteasy.core.interception.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:356)
at org.jboss.resteasy.resteasy-jaxrs#3.9.0.Final//org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:372)
at org.jboss.resteasy.resteasy-jaxrs#3.9.0.Final//org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:344)
at org.jboss.resteasy.resteasy-jaxrs#3.9.0.Final//org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:317)
at org.jboss.resteasy.resteasy-jaxrs#3.9.0.Final//org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:440)
... 59 more
23:29:23,670 INFO [io.undertow.request.dump] (default task-1)
----------------------------REQUEST---------------------------
URI=/eva/rest/consumers/deleteall
characterEncoding=null
contentLength=0
contentType=[application/json]
header=Accept=application/json
header=Connection=keep-alive
header=Authorization=ApiKey-v1 AC0gP9D-2jrCRDXfzyTayDb5LuUTTX9_Z2NwMDcwM0BnbWFpbC5jb20=
header=Content-Type=application/json
header=Content-Length=0
header=User-Agent=Java/13.0.1
header=Host=localhost:8080
locale=[]
method=DELETE
protocol=HTTP/1.1
queryString=
remoteAddr=/127.0.0.1:53053
remoteHost=localhost
scheme=http
host=localhost:8080
serverPort=8080
isSecure=false
--------------------------RESPONSE--------------------------
contentLength=-1
contentType=text/html;charset=UTF-8
header=Connection=keep-alive
header=Transfer-Encoding=chunked
header=Content-Type=text/html;charset=UTF-8
header=Date=Tue, 14 Jan 2020 06:29:23 GMT
status=500
==============================================================
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>com.eventhorizon</groupId>
<artifactId>eva</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>Eva REST Interface</name>
<properties>
<!-- Explicitly declaring the source encoding eliminates the following
message: -->
<!-- [WARNING] Using platform encoding (UTF-8 actually) to copy filtered
resources, i.e. build is platform dependent! -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- You can reference property in pom.xml or filtered resources (must
enable third-party plugin if using Maven < 2.1) -->
<!-- JBoss dependency versions -->
<version.jboss.maven.plugin>7.9.Final</version.jboss.maven.plugin>
<!-- Define the version of the JBoss BOMs we want to import to specify
tested stacks. -->
<version.jboss.bom>1.0.7.Final</version.jboss.bom>
<!-- Other dependency versions -->
<version.org.eclipse.m2e>1.0.0</version.org.eclipse.m2e>
<version.ro.isdc.wro4j>1.4.4</version.ro.isdc.wro4j>
<!-- other plugin versions -->
<version.surefire.plugin>2.10</version.surefire.plugin>
<version.war.plugin>2.2</version.war.plugin>
<!-- maven-compiler-plugin -->
<maven.compiler.target>12</maven.compiler.target>
<maven.compiler.source>12</maven.compiler.source>
</properties>
<dependencyManagement>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.wildfly.bom/wildfly-jakartaee8-with-tools-builder -->
<dependency>
<groupId>org.wildfly.bom</groupId>
<artifactId>wildfly-jakartaee8-with-tools-builder</artifactId>
<version>18.0.1.Final</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.jboss.spec.javax.management.j2ee/jboss-j2eemgmt-api_1.1_spec-parent -->
<dependency>
<groupId>org.jboss.spec.javax.management.j2ee</groupId>
<artifactId>jboss-j2eemgmt-api_1.1_spec-parent</artifactId>
<version>2.0.0.Final</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.jboss.arquillian</groupId>
<artifactId>arquillian-bom</artifactId>
<version>1.1.8.Final</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20180130</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mongodb/mongo-java-driver -->
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>3.12.0</version>
</dependency>
<dependency>
<groupId>com.sendgrid</groupId>
<artifactId>sendgrid-java</artifactId>
<version>4.4.1</version>
</dependency>
<dependency>
<groupId>com.sendgrid</groupId>
<artifactId>java-http-client</artifactId>
<version>4.1.0</version>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>
</dependencies>
<build>
<!-- Maven will append the version to the finalName (which is the name
given to the generated war, and hence the context root) -->
<!-- <finalName>${project.artifactId}</finalName> -->
<finalName>eva</finalName>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
<configuration>
<!-- Java EE 6 doesn't require web.xml, Maven needs to catch up! -->
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
</project>

You are using an EJB (#LocalBean) annotation. And you applied #RolesAllowed annotation. This means, your EJB / REST service invocation is automatically protected by the JEE runtime.
Basically, what you are doing in your interceptor is already performed by Wildfly. But in a different way. Now you accidentally have two ways or levels of authentication. I suggest you stick to a single implementation.
Either you go with JAAS framework or use your custom interceptor. You should not use both at the same time.
My recommended approach would be to setup a JAAS Login module in Wildfly. There should be plenty of examples of how to do that, e.g. use https://docs.wildfly.org/18/WildFly_Elytron_Security.html#Database_Authentication_Migration or JBoss Wildfly - database login module
Do not use JAAS and provide your custom security interceptor. Basically you could keep your interceptor class. In order to make it work, you could use your own set of annotations to check for access.

Related

ClassNotFoundException in embedded Jetty when using Module system

I use an embedded Jetty (11.0.13) server with Jersey (3.1.0) that provides a simple REST interface which returns JSON objects. The JSON objects are serialized using Jackson.
The setup works fine as long as I don´t use Java´s module system.
But when I add the module-info.java file (see below), I get the following error as soon as I call the service.
WARNING: The following warnings have been detected: WARNING: Unknown HK2 failure detected:
MultiException stack 1 of 2
java.lang.NoClassDefFoundError: jakarta/xml/bind/annotation/XmlElement
at com.fasterxml.jackson.module.jakarta.xmlbind.JakartaXmlBindAnnotationIntrospector.<init>(JakartaXmlBindAnnotationIntrospector.java:137)
...
Caused by: java.lang.ClassNotFoundException: jakarta.xml.bind.annotation.XmlElement
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
... 83 more
MultiException stack 2 of 2
java.lang.IllegalStateException: Unable to perform operation: post construct on org.glassfish.jersey.jackson.internal.DefaultJacksonJaxbJsonProvider
at org.jvnet.hk2.internal.ClazzCreator.create(ClazzCreator.java:429)
at org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:466)
...
To make it work, I have to add the JAX-B-API to the pom.xml and to the module-info.java.
The error only occurs when using Java modules. When I simply delete the module-info.java file, everythink works fine even without the JAX-B dependency.
This is the point where I am really confused. Why do I need the JAX-B dependency when I use the module system, but not when I don´t use it? And why does the ClassNotFoundException even occur? Shouldn´t warn the module system about missing dependencies on startup?
I hope someone can explain that. It took me days to make it work.
This is the setup that produces the issue:
pom.xml
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.target>17</maven.compiler.target>
<maven.compiler.source>17</maven.compiler.source>
</properties>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>11.0.13</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
<version>11.0.13</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>3.1.0</version>
</dependency>
</dependencies>
</project>
Main.java
public class Main {
public static void main(String[] args) throws Exception {
Server server = new Server(8080);
server.setStopAtShutdown(true);
ServletContextHandler context = new ServletContextHandler(server, "/");
ServletHolder servletHolder = context.addServlet(ServletContainer.class, "/*");
servletHolder.setInitParameter("jersey.config.server.provider.packages", "com.example.demo");
servletHolder.setInitParameter("jersey.config.server.wadl.disableWadl", "true");
server.start();
}
}
DemoResource.java
#Path("/hello")
public class DemoResource {
#GET
#Produces("application/json")
public HelloDto hello() {
return new HelloDto("Hello, World!");
}
public record HelloDto(String value) {
#JsonGetter("value")
public String value() {
return this.value;
}
}
}
module-info.java
module demo {
requires org.eclipse.jetty.server;
requires org.eclipse.jetty.servlet;
requires jersey.container.servlet.core;
requires jakarta.ws.rs;
requires com.fasterxml.jackson.annotation;
}
This is the standard JVM behavior of classpath (old school Java) and modulepath (new school Java Platform Module System, aka JPMS).
Once you have a module-info.class you have a modulepath active, and all of the access rules it has.
Your runtime can have both at the same time, and this is quite normal.
Don't rely on old school classpath to get around bad code and bad behavior, use JPMS and module-info.class and you'll know what the developers of those projects jars intend for you to use (you won't be allowed to use internal classes for example, as those are highly volatile and can change at a moments notice).
jakarta.xml.bind is required by HK2 to operate, so you have to declare it in your build dependencies to just compile, and then your module-info.java to be able to access it.
Check the other answers here on Stackoverflow for advice on how to use module-info.java properly (there's far more to it than just requires <module>).

An "Error creating bean with name 'functionBindingRegistrar'" exception every time I start my application

I have a normal spring cloud stream application that simple reads data from Kafka topic and produces messages to another Kafka topic, please find below the configurations:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.6</version>
<relativePath/>
</parent>
<properties>
<spring-cloud.version>2020.0.4</spring-cloud.version>
<spring-boot-maven-plugin.version>2.3.0.RELEASE</spring-boot-maven-plugin.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-stream-kafka</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
And the following application.proeprties
#Kafka Configurations
spring.kafka.bootstrap-servers=localhost:9092
spring.cloud.stream.kafka.binder.configuration.auto.offset.reset=latest
spring.cloud.function.definition=merchantCredentials;validatedProducts;validateImages;retryUnprocessedItems
#Input topics
#Merchants
spring.cloud.stream.bindings.merchantCredentials-in-0.destination=mis.merchantCtpCredentials
spring.cloud.stream.kafka.bindings.merchantCredentials-in-0.consumer.ack-mode=manual_immediate
spring.cloud.stream.bindings.merchantCredentials-in-0.contentType=application/json
spring.cloud.stream.bindings.merchantCredentials-in-0.consumer.header-mode=headers
spring.cloud.stream.bindings.merchantCredentials-in-0.consumer.partitioned=true
spring.cloud.stream.bindings.merchantCredentials-in-0.consumer.max-attempts=1
spring.cloud.stream.bindings.merchantCredentials-in-0.group=tuevGroup
#kfc.notifications.product
spring.cloud.stream.bindings.validatedProducts-in-0.destination=kfc.notifications.product
spring.cloud.stream.kafka.bindings.validatedProducts-in-0.consumer.ack-mode=manual_immediate
spring.cloud.stream.bindings.validatedProducts-in-0.contentType=application/json
spring.cloud.stream.bindings.validatedProducts-in-0.consumer.header-mode=headers
spring.cloud.stream.bindings.validatedProducts-in-0.consumer.concurrency=5
spring.cloud.stream.bindings.validatedProducts-in-0.consumer.partitioned=true
spring.cloud.stream.bindings.validatedProducts-in-0.consumer.max-attempts=1
spring.cloud.stream.bindings.validatedProducts-in-0.group=tuevGroup
#marketplace.products
spring.cloud.stream.bindings.validateImages-in-0.destination=marketplace.products
spring.cloud.stream.kafka.bindings.validateImages-in-0.consumer.ack-mode=manual_immediate
spring.cloud.stream.bindings.validateImages-in-0.contentType=application/json
spring.cloud.stream.bindings.validateImages-in-0.consumer.header-mode=headers
spring.cloud.stream.bindings.validateImages-in-0.consumer.partitioned=true
spring.cloud.stream.bindings.validateImages-in-0.consumer.max-attempts=1
spring.cloud.stream.bindings.validateImages-in-0.group=tuevGroup
#Output topics
#productValidated
spring.cloud.stream.bindings.validatedProducts-out-0.destination=marketplace.validated.products
spring.cloud.stream.bindings.validatedProducts-out-0.contentType=application/json
spring.cloud.stream.bindings.validatedProducts-out-0.producer.partition-count=10
spring.cloud.stream.bindings.validatedProducts-out-0.producer.header-mode=headers
spring.cloud.stream.bindings.retryUnprocessedItems-out-0.destination=marketplace.validated.products
spring.cloud.stream.bindings.retryUnprocessedItems-out-0.contentType=application/json
spring.cloud.stream.bindings.retryUnprocessedItems-out-0.producer.partition-count=10
spring.cloud.stream.bindings.retryUnprocessedItems-out-0.producer.header-mode=headers
spring.cloud.stream.poller.cron=0 0/10 * * * *
spring.cloud.stream.poller.initial-delay=10000
And below is the signature of all defined spring cloud functions
#Bean
public Consumer<Flux<Message<JsonNode>>> merchantCredentials() {
#Bean
public Function<Message<NotificationMessage>, Message<ProductValidatedEvent>> validatedProducts() {
#Bean
public Consumer<Message<ProductImportMessage>> validateImages() {
#PollableBean
#SchedulerLock(name = "retryProcess_scheduledTask", lockAtMostFor = "${retry.job.lock.atMost}", lockAtLeastFor = "${retry.job.lock.atLeast}")
public Supplier<Flux<Message<ProductValidatedEvent>>> retryUnprocessedItems() {
Everything works fine, and the application starts and functions as it should, however, in the logs I encounter this exception multiple times, specially during the start up phase of the application
org.springframework.boot.SpringApplication - Application run failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'functionBindingRegistrar' defined in class path resource [org/springframework/cloud/stream/function/FunctionConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Type must be one of Supplier, Function or Consumer
I have double checked all configurations and I still have no clue how can I prevent this issue from happening. Why this exception is happening? is it ignorable ?
UPDATE 1:
I have tracked the bug to this function in spring framework, FunctionTypeUtils:
public static Type discoverFunctionTypeFromClass(Class<?> functionalClass) {
Assert.isTrue(isFunctional(functionalClass), "Type must be one of Supplier, Function or Consumer");
this function gets called by this function in FunctionConfiguration:
private String[] filterEligibleFunctionDefinitions() {
...
for (int i = 0; i < functionNames.length && eligibleDefinition; i++) {
String functionName = functionNames[i];
if (this.applicationContext.containsBean(functionName)) {
And when I added debug points to this one, as well as the previous one I got the following output
functionName: merchantCredentials
functionalClass: com.rewedigital.services.tuev.marketplace.merchant.flow.MerchantFlowManger$$Lambda$1323/0x00000008008fc040
functionName: validatedProducts
functionalClass: com.rewedigital.services.tuev.marketplace.validator.listener.ProductChangedListener$$Lambda$1331/0x00000008008fa040
functionName: validateImages
functionalClass: com.rewedigital.services.tuev.marketplace.sieve.listener.ProductImagesListener$$Lambda$1324/0x00000008008fc440
functionName: retryUnprocessedItems
functionalClass: org.springframework.beans.factory.support.NullBean
Showing that the retryUnprocessedItems is the culprit, not sure why though?
After some investigation, it turned out that the problem is mainly with the #SchedulerLock annotation.
I observed that this issue happens while then shedLock table has lock added on the method, and hence it was preventing the FunctionBeanRegistrar from adding the method, and so the exception.
Of course this means on the other hand that the annotation is now deemed not usable because what #PollableBean annotation really runs is not the function itself, but rather the Supplier lambda expression returned by the function, practically rendering the ShedLock useless.
Once I remove the annotation, all the exceptions are gone and the sun shines again, birds sing, etc etc..
The next question to answer would be how to use rollable bean in a distributed manner but that is out of the scope of this question

RestEasyClient IncompatibleClassChangeError (ResteasyProviderFactory.getContextData(java.lang.Class))

When using org.jboss.resteasy:resteasy-client:4.5.9.Final, I'm getting this exception: Caused by: java.lang.IncompatibleClassChangeError: Expected static method 'java.lang.Object org.jboss.resteasy.spi.ResteasyProviderFactory.getContextData(java.lang.Class)'
However, when I use an earlier version, it seems to work fine. (Or at least it works well enough to fool me.)
Here's my simplified pom:
<?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>example-project</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>15</maven.compiler.source>
<maven.compiler.target>15</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<keycloak.version>12.0.4</keycloak.version>
<!-- Seems to work with this version, but not 4.5.9.Final -->
<resteasy.version>3.6.2.Final</resteasy.version>
</properties>
<dependencies>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-admin-client</artifactId>
<version>${keycloak.version}</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-client</artifactId>
<version>${resteasy.version}</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jackson2-provider</artifactId>
<version>${resteasy.version}</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-multipart-provider</artifactId>
<version>${resteasy.version}</version>
</dependency>
</dependencies>
</project>
And here's my code:
package org.example.keycloak;
import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;
import org.keycloak.OAuth2Constants;
import org.keycloak.admin.client.Keycloak;
import org.keycloak.admin.client.KeycloakBuilder;
public class KeycloakClientAuthExample {
public static void main(String[] args) {
Keycloak keycloak = KeycloakBuilder.builder()
.serverUrl("http://localhost:8080/auth")
.grantType(OAuth2Constants.PASSWORD)
.realm("DungeoneersDemo")
.clientId("dungeoneers-data")
.clientSecret("11111111-2222-3333-4444-555555555555")
.username("user")
.password("pass")
.resteasyClient(
// new ResteasyClientBuilderImpl() // <-- For 4.5.9.Final
new ResteasyClientBuilder()
.connectionPoolSize(10).build()
).build();
keycloak.tokenManager().getAccessToken();
AccessTokenResponse atr =
keycloak.tokenManager().getAccessToken();
System.out.println(atr.getToken());
}
}
Seems to work and I get what looks enough to me like a bearer token: eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI2bWhhWUQ..etc...
However, when I update my resteasy.version to the a later version✳ (4.5.9.Final), I get an error:
Exception in thread "main" java.lang.RuntimeException: java.lang.RuntimeException: RESTEASY003940: Unable to instantiate MessageBodyReader
at org.jboss.resteasy.plugins.providers.RegisterBuiltin.register(RegisterBuiltin.java:78)
at org.jboss.resteasy.plugins.providers.RegisterBuiltin.getClientInitializedResteasyProviderFactory(RegisterBuiltin.java:54)
at org.jboss.resteasy.client.jaxrs.internal.ResteasyClientBuilderImpl.getProviderFactory(ResteasyClientBuilderImpl.java:372)
at org.jboss.resteasy.client.jaxrs.internal.ResteasyClientBuilderImpl.build(ResteasyClientBuilderImpl.java:390)
at org.sandbox.security.openidc.keycloak.KeycloakClientAuthExample.main(KeycloakClientAuthExample.java:22)
Caused by: java.lang.RuntimeException: RESTEASY003940: Unable to instantiate MessageBodyReader
at org.jboss.resteasy.core.providerfactory.CommonProviders.processProviderContracts(CommonProviders.java:93)
at org.jboss.resteasy.core.providerfactory.ClientHelper.processProviderContracts(ClientHelper.java:104)
at org.jboss.resteasy.core.providerfactory.ResteasyProviderFactoryImpl.processProviderContracts(ResteasyProviderFactoryImpl.java:841)
at org.jboss.resteasy.core.providerfactory.ResteasyProviderFactoryImpl.registerProvider(ResteasyProviderFactoryImpl.java:829)
at org.jboss.resteasy.core.providerfactory.ResteasyProviderFactoryImpl.registerProvider(ResteasyProviderFactoryImpl.java:816)
at org.jboss.resteasy.plugins.providers.RegisterBuiltin.registerProviders(RegisterBuiltin.java:109)
at org.jboss.resteasy.plugins.providers.RegisterBuiltin.register(RegisterBuiltin.java:74)
... 4 more
Caused by: java.lang.RuntimeException: RESTEASY003325: Failed to construct public org.jboss.resteasy.plugins.providers.jaxb.JAXBElementProvider()
at org.jboss.resteasy.core.ConstructorInjectorImpl.constructOutsideRequest(ConstructorInjectorImpl.java:250)
at org.jboss.resteasy.core.ConstructorInjectorImpl.construct(ConstructorInjectorImpl.java:209)
at org.jboss.resteasy.core.providerfactory.Utils.createProviderInstance(Utils.java:102)
at org.jboss.resteasy.core.providerfactory.CommonProviders.processProviderContracts(CommonProviders.java:87)
... 10 more
Caused by: java.lang.IncompatibleClassChangeError: Expected static method 'java.lang.Object org.jboss.resteasy.spi.ResteasyProviderFactory.getContextData(java.lang.Class)'
at org.jboss.resteasy.plugins.providers.jaxb.AbstractJAXBProvider.<init>(AbstractJAXBProvider.java:52)
at org.jboss.resteasy.plugins.providers.jaxb.JAXBElementProvider.<init>(JAXBElementProvider.java:46)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:64)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:500)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:481)
at org.jboss.resteasy.core.ConstructorInjectorImpl.constructOutsideRequest(ConstructorInjectorImpl.java:225)
... 13 more
Process finished with exit code 1
✳ Note: When upgrading to the later version, ResteasyClientBuilder was abstracted and the constructor call needed to be replaced with new ResteasyClientBuilderImpl().
I was typing out my question and, while looking into it one last time before submitting, I found the issue and figured I'd throw it out there just in case someone else has this issue.
It turns out that there is another resteasy dependency that needed to be pulled in because, otherwise, an old version is pulled in. When using the newer version of resteasy-client, the other dependency being pulled in was org.jboss.resteasy:resteasy-jaxb-provider:3.9.1.Final. I added the newer version to my pom (org.jboss.resteasy:resteasy-jaxb-provider:4.5.9.Final) and everything seems to now work.
Not sure why this is the case. I would think if the dependency was being pulled in anyway by resteasy-client, it should've been pulling in the same version.
We were facing the same issue and your reply really helped to find out the mistake. To let other users check the error in detail, further details are:
KC 15.* and KC16.1 uses, in their main pom.xml, resteasy version 3.*
<resteasy.version>3.15.1.Final</resteasy.version>
<resteasy.undertow.version>${resteasy.version}</resteasy.undertow.version>
When you check the version for the container in the server, you can see that, from KC16, the new Widlfly server uses resteasy v4.*
This concept causes a difference in the jars, while it has the behavior to have scope provided (but is not). As you mentioned, the solution to that is the following.
<properties>
<resteasy.version>4.5.9.Final</resteasy.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-client</artifactId>
<version>${resteasy.version}</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jackson2-provider</artifactId>
<version>${resteasy.version}</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-multipart-provider</artifactId>
<version>${resteasy.version}</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxb-provider</artifactId>
<version>${resteasy.version}</version>
</dependency>
</dependencies></dependencyManagement>
This will force 3 main API changes to consider:
final ResteasyClient client = new ResteasyClientBuilder()
.disableTrustManager()
.socketTimeout(60, TimeUnit.SECONDS)
.establishConnectionTimeout(10, TimeUnit.SECONDS)
/// will need to change to the new methods:
final ResteasyClient client = new ResteasyClientBuilderImpl()
.disableTrustManager()
.readTimeout(60, TimeUnit.SECONDS)
.connectTimeout(10, TimeUnit.SECONDS)
And also this change:
HttpServletResponse contextData = ResteasyProviderFactory.getContextData(HttpServletResponse.class);
//Change to
ResteasyProviderFactory resteasyProviderFactory = ResteasyProviderFactoryImpl.getInstance();
HttpServletResponse contextData = resteasyProviderFactory.getContextData(HttpServletResponse.class);
You r previous reply help us to understand under the hood the problem, but, anyway, users shall have more info. See the image bellow as a running KC16 container showing all related libs

Dialogflow v2 Java Client Library detectIntent with Spring Boot: No DesignTimeAgent found for project

While trying to detectIntent from text I have received a below exception (project-id was replaced). Cannot find anything in google related to DesignTimeAgent issue. Any help is appreciated.
Exception :
There was an unexpected error (type=Internal Server Error, status=500).
io.grpc.StatusRuntimeException: NOT_FOUND: com.google.apps.framework.request.NotFoundException: No DesignTimeAgent found for project 'MY_PROJECT_ID'.
com.google.api.gax.rpc.NotFoundException: io.grpc.StatusRuntimeException: NOT_FOUND: com.google.apps.framework.request.NotFoundException: No DesignTimeAgent found for project 'MY_PROJECT_ID'.
at com.google.api.gax.rpc.ApiExceptionFactory.createException(ApiExceptionFactory.java:45)
at com.google.api.gax.grpc.GrpcApiExceptionFactory.create(GrpcApiExceptionFactory.java:72)
at com.google.api.gax.grpc.GrpcApiExceptionFactory.create(GrpcApiExceptionFactory.java:60)
at com.google.api.gax.grpc.GrpcExceptionCallable$ExceptionTransformingFuture.onFailure(GrpcExceptionCallable.java:95)
at com.google.api.core.ApiFutures$1.onFailure(ApiFutures.java:61)
at com.google.common.util.concurrent.Futures$CallbackListener.run(Futures.java:1015)
at com.google.common.util.concurrent.DirectExecutor.execute(DirectExecutor.java:30)
at com.google.common.util.concurrent.AbstractFuture.executeListener(AbstractFuture.java:1137)
at com.google.common.util.concurrent.AbstractFuture.complete(AbstractFuture.java:957)
at com.google.common.util.concurrent.AbstractFuture.setException(AbstractFuture.java:748)
at io.grpc.stub.ClientCalls$GrpcFuture.setException(ClientCalls.java:493)
at io.grpc.stub.ClientCalls$UnaryStreamToFuture.onClose(ClientCalls.java:468)
at io.grpc.PartialForwardingClientCallListener.onClose(PartialForwardingClientCallListener.java:39)
at io.grpc.ForwardingClientCallListener.onClose(ForwardingClientCallListener.java:23)
at io.grpc.ForwardingClientCallListener$SimpleForwardingClientCallListener.onClose(ForwardingClientCallListener.java:40)
at io.grpc.internal.CensusStatsModule$StatsClientInterceptor$1$1.onClose(CensusStatsModule.java:684)
...
Suppressed: com.google.api.gax.rpc.AsyncTaskException: Asynchronous task failed
at com.google.api.gax.rpc.ApiExceptions.callAndTranslateApiException(ApiExceptions.java:57)
at com.google.api.gax.rpc.UnaryCallable.call(UnaryCallable.java:112)
at com.google.cloud.dialogflow.v2.SessionsClient.detectIntent(SessionsClient.java:245)
at com.google.cloud.dialogflow.v2.SessionsClient.detectIntent(SessionsClient.java:184)
at com.my.microservices.controllers.DialogFlowRestController.test(DialogFlowRestController.java:35)
...
Caused by: io.grpc.StatusRuntimeException: NOT_FOUND: com.google.apps.framework.request.NotFoundException: No DesignTimeAgent found for project 'MY_PROJECT_ID'.
at io.grpc.Status.asRuntimeException(Status.java:533)
... 23 more
Rest controller to trigger detectIntent test (as https://localhost:8080/api/test):
package com.my.microservices.controllers;
import com.google.cloud.dialogflow.v2.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.util.UUID;
#RestController
#RequestMapping("/api")
public class DialogFlowRestController {
private static final Logger logger = LoggerFactory.getLogger(DialogFlowRestController.class);
private String userText = "Weather forecast for today in Berlin";
private final String LANG_CODE = "en-US";
private final String PROJECT_ID = System.getenv().get("GOOGLE_CLOUD_PROJECT");
private String sessionId = UUID.randomUUID().toString();
#GetMapping(value = "/test", produces = MediaType.APPLICATION_JSON_VALUE)
#ResponseBody
public String test() throws Exception {
logger.info("test was called");
try (SessionsClient sessionsClient = SessionsClient.create()) {
SessionName session = SessionName.of(PROJECT_ID, sessionId);
TextInput.Builder textInput = TextInput.newBuilder().setText(userText).setLanguageCode(LANG_CODE);
QueryInput queryInput = QueryInput.newBuilder().setText(textInput).build();
DetectIntentResponse response = sessionsClient.detectIntent(session, queryInput);
return response.toString();
}
}
}
Provided environment variables:
GOOGLE_CLOUD_PROJECT=MY_PROJECT_ID
GOOGLE_APPLICATION_CREDENTIALS=/Users/me/.my/pk.json
Spring-Boot 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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.my.microservices</groupId>
<artifactId>dialog-flow-test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>dialog-flow-test</name>
<description>Demo project with Dialog Flow</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Dialogflow API Client Library for Java -->
<dependency>
<groupId>com.google.apis</groupId>
<artifactId>google-api-services-dialogflow</artifactId>
<version>v2-rev81-1.25.0</version>
</dependency>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-dialogflow</artifactId>
<version>0.103.0-alpha</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
OK, I have figured it out.
The above misleading error message was caused by the use of a wrong PROJECT_ID. My mistake was, that first I have created a new Project with a Service Account, gave to it dialogflow API rights and later I have tried to use its name and related PK JSON for my detectIntent calls. BUT it was not linked with Dialogflow Project ID.
So, to fix it I have started with a default Project ID, which was given to my new Dialogflow Agent and following instruction https://dialogflow.com/docs/reference/v2-auth-setup I have created a new Project with a Service Account which fit my Dialogflow Agent.
In my case I needed to move my Agent to Global serving from EU-W1

Netflix Feign Exception

Dependencies
org.springframework.cloud:spring-cloud-starter-feign:jar:1.2.2.RELEASE:compile
com.netflix.feign:feign-core:jar:8.16.2:compile
com.netflix.feign:feign-slf4j:jar:8.16.2:compile
com.netflix.feign:feign-jackson:jar:8.15.1:compile
Enabling Feign on SpringBootAppilication
#EnableFeignClients(basePackages = "com.vett.services.bucket.restclient")
Feign interface Client
#FeignClient(name = "myClient", configuration = ClientConfigs.class, url = "https://my-endpoint");
public interface MyClient {
Results in this error
org.springframework.core.annotation.AnnotationConfigurationException: Attribute 'value' in annotation [org.springframework.cloud.netflix.feign.FeignClient] must be declared as an #AliasFor [serviceId], not [name]
So far I have
As its unclear to me what the issue is i have used the value instead of name, my searching has not been successful i have see a few issues with feign annotation but not appear to be similar to this at all
I was getting the same issue, Once I added the below dependency , it started working :
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:Brixton.SR7"}
}
I am using Spring boot 1.4 but Spring 4.3.6. Also Spring feign 1.2.5.RELEASE
This error may occur when using multiple feign clients or bad package architecture. Sometimes this error occurs due to version incompatibilities, but in some projects we may not be able to change the versions. Therefore, you can solve the problem with the following codes. This codes worked for me.
Use this annotation in ApplicationStarter class:
#EnableFeignClients
Feign Client Interface:
import org.springframework.cloud.netflix.feign.FeignClient;
#FeignClient(value = "account-service", url = "${feign.client.account-service}", path = "/account/api/v1")
public interface AccountServiceClient {
#RequestLine("POST /customer/{email}/?name={accountName}")
Long registerCustomer(#Param("email") String email, #Param("accountName") String accountName);
}
Define bean for multiple feign usage:
#Bean
#Qualifier("account-feign-client")
public AccountServiceClient accountServiceClient() {
return Feign.builder().target( AccountServiceClient.class,"${feign.client.account-service}");
}
#Bean
#Qualifier("mail-feign-client")
public MailServiceClient mailServiceClient() {
return Feign.builder().target( MailServiceClient.class,"${feign.client.mail-service}");
}
Autowire in service:
#Autowired
#Qualifier("account-feign-client")
private AccountServiceClient accountServiceClient;
pom.xml:
<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>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Brixton.SR7</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
<version>1.4.7.RELEASE</version>
</dependency>
...
</dependencies>

Categories