scala netty codec when calling to Facebook - facebook

I am using play 2.2.1 built with Scala 2.10.2 (running Java 1.7.0_45). I have an endpoint which makes calls to Facebook to validate Facebook oauth tokens passed to us from our clients.
We asynchronously call to both a homegrown RESTful database service and to https facebook graph api. In other words, we're calling to two systems simultaneously. Intermittently, we're getting the exception below.
java.lang.IllegalArgumentException: invalid version format: ᅥBヌ쪠ᄌS
at org.jboss.netty.handler.codec.http.HttpVersion.(HttpVersion.java:102) ~[netty-3.7.0.Final.jar:na]
at org.jboss.netty.handler.codec.http.HttpVersion.valueOf(HttpVersion.java:62) ~[netty-3.7.0.Final.jar:na]
at org.jboss.netty.handler.codec.http.HttpResponseDecoder.createMessage(HttpResponseDecoder.java:104) ~[netty-3.7.0.Final.jar:na]
at org.jboss.netty.handler.codec.http.HttpMessageDecoder.decode(HttpMessageDecoder.java:189) ~[netty-3.7.0.Final.jar:na]
at org.jboss.netty.handler.codec.http.HttpClientCodec$Decoder.decode(HttpClientCodec.java:143) ~[netty-3.7.0.Final.jar:na]
at org.jboss.netty.handler.codec.http.HttpClientCodec$Decoder.decode(HttpClientCodec.java:127) ~[netty-3.7.0.Final.jar:na]
at org.jboss.netty.handler.codec.replay.ReplayingDecoder.callDecode(ReplayingDecoder.java:500) ~[netty-3.7.0.Final.jar:na]
at org.jboss.netty.handler.codec.replay.ReplayingDecoder.messageReceived(ReplayingDecoder.java:435) ~[netty-3.7.0.Final.jar:na]
at org.jboss.netty.handler.codec.http.HttpClientCodec.handleUpstream(HttpClientCodec.java:92) ~[netty-3.7.0.Final.jar:na]
at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:268) ~[netty-3.7.0.Final.jar:na]
at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:255) ~[netty-3.7.0.Final.jar:na]
at org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:88) ~[netty-3.7.0.Final.jar:na]
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.process(AbstractNioWorker.java:109) ~[netty-3.7.0.Final.jar:na]
at org.jboss.netty.channel.socket.nio.AbstractNioSelector.run(AbstractNioSelector.java:312) ~[netty-3.7.0.Final.jar:na]
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.run(AbstractNioWorker.java:90) ~[netty-3.7.0.Final.jar:na]
at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:178) ~[netty-3.7.0.Final.jar:na]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) ~[na:1.7.0_45]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) ~[na:1.7.0_45]
at java.lang.Thread.run(Thread.java:744) ~[na:1.7.0_45]
2013-11-20 16:55:27,175: ERROR [lt-dispatcher-2] application - An unexpected error occurred
I am aware of this post to stackoverflow: Send multiple asynchonous requests on a Netty client. Although they get a similar error, their code is doing much more complicated bootstrapping, so I think the solution for me will be different. Here is our code:
def getUserInfo(token: String): Future[FacebookUserInfo] = {
val futureResponse: Future[Response] = WS.url(fbUrl + mePath).withQueryString("access_token" -> token).get()
futureResponse.map {
response => parseFacebookUserInfoResponse(response)
}
}
def parseFacebookUserInfoResponse(response: Response): FacebookUserInfo = {
Logger.debug("Got response code:" + response.status)
if (response.status == HttpURLConnection.HTTP_OK) {
val json: JsValue = Json.parse(response.body)
val jsonResult: JsResult[FacebookUserInfo] = json.validate[FacebookUserInfo]
jsonResult.fold(
valid = {
success => success
},
invalid = {
error => throw new FacebookResponseException("Invalid Response received.")
}
)
}
else if (response.status == HttpURLConnection.HTTP_BAD_REQUEST) {
throw new FacebookTokenException(response.json.as[FacebookError].message)
} else
throw new MyException(response.body)
}
What is the best way to fix this problem? Can I switch the default http client and use Apache HttpClient, for example? Do I need to update the codec? Do I need to upgrade/downgrade netty?

Related

Call a Scala service using HttpClient from a Java API is not working

I am trying to call a Scala service from a Java API using the HttpClient from Java 11.
On the Java API the code looks like:
var client = HttpClient.newHttpClient();
var packagesCountUrl = getPackagesCountUrl();
var sessionUserToken = sessionUserHelper.getSessionUserToken();
var request = HttpRequest.newBuilder(URI.create(packagesCountUrl))
.GET()
.header(HttpHeaders.AUTHORIZATION, sessionUserToken)
.header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)
.timeout(Duration.of(10, SECONDS))
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
On the Java API, I receive a response with 503 status code and in the logs of Scala API there is the following:
ERROR] [10/05/2021 18:59:29.711] [abc-api-actorSystem-akka.actor.default-dispatcher-11] [akka://abc-api-actorSystem/system/StreamSupervisor-0/flow-24966-1-mapAsyncUnordered] Error in stage [ExposeAttributes(akka.http.impl.engine.http2.Http2Blueprint$$$Lambda$889/2094115865#e6b910)]: requirement failed: Requests with method 'CONNECT' must have an empty entity
java.lang.IllegalArgumentException: requirement failed: Requests with method 'CONNECT' must have an empty entity
at scala.Predef$.require(Predef.scala:277)
at akka.http.scaladsl.model.HttpRequest.<init>(HttpMessage.scala:276)
at akka.http.scaladsl.model.HttpRequest$.apply(HttpMessage.scala:442)
at akka.http.impl.engine.http2.RequestParsing$.rec$1(RequestParsing.scala:84)
at akka.http.impl.engine.http2.RequestParsing$.$anonfun$parseRequest$3(RequestParsing.scala:140)
at akka.http.impl.util.ExposeAttributes$$anon$14.onPush(StreamUtils.scala:354)
at akka.stream.impl.fusing.GraphInterpreter.processPush(GraphInterpreter.scala:523)
at akka.stream.impl.fusing.GraphInterpreter.execute(GraphInterpreter.scala:409)
at akka.stream.impl.fusing.GraphInterpreterShell.runBatch(ActorGraphInterpreter.scala:606)
at akka.stream.impl.fusing.ActorGraphInterpreter$SimpleBoundaryEvent.execute(ActorGraphInterpreter.scala:47)
at akka.stream.impl.fusing.ActorGraphInterpreter$SimpleBoundaryEvent.execute$(ActorGraphInterpreter.scala:43)
at akka.stream.impl.fusing.ActorGraphInterpreter$BatchingActorInputBoundary$OnNext.execute(ActorGraphInterpreter.scala:85)
at akka.stream.impl.fusing.GraphInterpreterShell.processEvent(ActorGraphInterpreter.scala:581)
at akka.stream.impl.fusing.ActorGraphInterpreter.akka$stream$impl$fusing$ActorGraphInterpreter$$processEvent(ActorGraphInterpreter.scala:749)
at akka.stream.impl.fusing.ActorGraphInterpreter$$anonfun$receive$1.applyOrElse(ActorGraphInterpreter.scala:764)
at akka.actor.Actor.aroundReceive(Actor.scala:539)
at akka.actor.Actor.aroundReceive$(Actor.scala:537)
at akka.stream.impl.fusing.ActorGraphInterpreter.aroundReceive(ActorGraphInterpreter.scala:671)
at akka.actor.ActorCell.receiveMessage(ActorCell.scala:612)
at akka.actor.ActorCell.invoke(ActorCell.scala:581)
at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:268)
at akka.dispatch.Mailbox.run(Mailbox.scala:229)
at akka.dispatch.Mailbox.exec(Mailbox.scala:241)
at akka.dispatch.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
at akka.dispatch.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
at akka.dispatch.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
at akka.dispatch.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
The issue was the Scala API with its configurations didn't support HTTP2.
The solution was to mention to the HttpClient to use HTTP1 instead.
var client = HttpClient.newHttpClient();
var packagesCountUrl = getPackagesCountUrl(loopLabel);
var sessionUserToken = sessionUserHelper.getSessionUserToken();
var request = HttpRequest.newBuilder(URI.create(packagesCountUrl))
.GET()
.header(HttpHeaders.AUTHORIZATION, sessionUserToken)
.header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)
.version(HttpClient.Version.HTTP_1_1) // This was the SOLUTION
.timeout(Duration.of(10, SECONDS))
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());

Server-Sent Event with Jersey and weblogic

I am experimenting with server sent event. Am following this link https://jersey.java.net/documentation/latest/user-guide.html#d0e8376. When I make request to the resource representing Server Sent Event, I get 500 Internal server error.
According to following error, I have to register the body writer for org.glassfish.jersey.media.sse.EventOutput. But, how to do it?
####<21 Nov, 2013 3:17:28 PM IST> <Error> <com.sun.jersey.spi.container.ContainerResponse> <Laptop1> <AdminServer> <[ACTIVE] ExecuteThread: '16' for queue: 'weblogic.kernel.Default (self-tuning)'> <<anonymous>> <> <> <1385027248248> <BEA-000000> <Mapped exception to response: 500 (Internal Server Error)
javax.ws.rs.WebApplicationException: com.sun.jersey.api.MessageException: A message body writer for Java class org.glassfish.jersey.media.sse.EventOutput, and Java type class org.glassfish.jersey.media.sse.EventOutput, and MIME media type text/event-stream was not found
at com.sun.jersey.spi.container.ContainerResponse.write(ContainerResponse.java:285)
at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1479)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1391)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1381)
at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:416)
at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:538)
at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:716)
at weblogic.jaxrs.server.portable.servlet.ServletContainer.service(ServletContainer.java:218)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:844)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:280)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:254)
at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:136)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:341)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:238)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3363)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3333)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)
at weblogic.servlet.provider.WlsSubjectHandle.run(WlsSubjectHandle.java:57)
at weblogic.servlet.internal.WebAppServletContext.doSecuredExecute(WebAppServletContext.java:2220)
at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2146)
at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2124)
at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1564)
at weblogic.servlet.provider.ContainerSupportProviderImpl$WlsRequestExecutor.run(ContainerSupportProviderImpl.java:254)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:295)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:254)
Caused By: com.sun.jersey.api.MessageException: A message body writer for Java class org.glassfish.jersey.media.sse.EventOutput, and Java type class org.glassfish.jersey.media.sse.EventOutput, and MIME media type text/event-stream was not found
at com.sun.jersey.spi.container.ContainerResponse.write(ContainerResponse.java:285)
at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1479)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1391)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1381)
at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:416)
at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:538)
at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:716)
at weblogic.jaxrs.server.portable.servlet.ServletContainer.service(ServletContainer.java:218)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:844)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:280)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:254)
at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:136)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:341)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:238)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3363)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3333)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)
at weblogic.servlet.provider.WlsSubjectHandle.run(WlsSubjectHandle.java:57)
at weblogic.servlet.internal.WebAppServletContext.doSecuredExecute(WebAppServletContext.java:2220)
at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2146)
at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2124)
at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1564)
at weblogic.servlet.provider.ContainerSupportProviderImpl$WlsRequestExecutor.run(ContainerSupportProviderImpl.java:254)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:295)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:254)
Here is solution for my own question.
To register SseFeature, getSingletons method should be overridden in Application derived class, as show in below code.
#javax.ws.rs.ApplicationPath("webresources")
public class ApplicationConfig extends Application {
//....
#Override
public Set<Object> getSingletons() {
Set<Object> singletons = super.getSingletons();
if(singletons == null){
singletons=new java.util.HashSet<Object>();
}
singletons.add(new SseFeature());
return singletons;
}
//....
}
to use jersey latest version ( jersey 2.8 ) we should get rid of com.sun.jersey.api
Jersey APIs are now in org.glassfish.jersey package.
I suggest you to go through the following post and resolve the issues
check the update in question and comments
NoClassDefFoundError ProcessingException while migrating from jersey 1.x to jersey 2.x ( 2.8 )

Grails : org.codehaus.groovy.runtime.InvokerInvocationException: java.lang.NoSuchMethodError: org/apache/http/protocol/BasicHttpContext.<init>()V

I'm using grails restclient plugin(':rest:0.7') to consume rest grails rest services.
Here is my code:
def restClient = new RESTClient(ServiceURL)
def httpResponseDecorator = restClient.get(query: requestMessage)
pdfData = handleServiceResponse(httpResponseDecorator)
But getting the follwing error :
java.lang.NoSuchMethodError:
org/apache/http/protocol/BasicHttpContext.()V at
org.apache.jk.server.JkCoyoteHandler.invoke(JkCoyoteHandler.java:190)
at
org.apache.jk.common.HandlerRequest.invoke(HandlerRequest.java:291)
at org.apache.jk.common.ChannelSocket.invoke(ChannelSocket.java:776)
at
org.apache.jk.common.ChannelSocket.processConnection(ChannelSocket.java:705)
at
org.apache.jk.common.ChannelSocket$SocketConnection.runIt(ChannelSocket.java:898)
at java.lang.Thread.run(Thread.java:736) Caused by:
org.codehaus.groovy.runtime.InvokerInvocationException:
java.lang.NoSuchMethodError:
org/apache/http/protocol/BasicHttpContext.()V
Any idea how to resolve this issue?

Endpoints API generation error when using Guava

We are using Appengine Endpoints Java with Guava and when Function is used inside an endpoint method the API generator returns an exception.
Function is NOT part of the method signature. Its just used inside the method to transform a list. Comment out this body part and it generates OK.
Guava sure is in the classpath, and other parts of the application uses it normally.
I'm not sure its related to Guava or any outside API would give the same error.
The method:
#ApiMethod(
httpMethod = "GET",
name = "ledgers.accountgroups.get",
path="ledgers/{ledgerId}/accountgroups")
public Collection<IAccountGroup> listAccountGroups(#Named("ledgerId") String ledgerId, User user) throws Exception {
collaboratorDAO.assertCollaboratorOn(ledgerId, user);
List<Group> groups = accountGroupsDAO.getAccountGroups(ledgerId);
List<IAccountGroup> transformedGroups = Lists.transform(groups, new Function<Group, IAccountGroup>() {
#Override
public IAccountGroup apply(Group group) {
return group.createClient();
}
});
return transformedGroups;
}
The exception:
INFO: Successfully processed ./war/WEB-INF/appengine-web.xml
interface com.google.api.server.spi.config.Api
interface com.google.api.server.spi.config.Api
Exception in thread "main" java.lang.NoClassDefFoundError: com/google/common/base/Function
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2436)
at java.lang.Class.getDeclaredMethods(Class.java:1793)
at com.google.api.server.spi.MethodHierarchyReader.addServiceMethods(MethodHierarchyReader.java:174)
at com.google.api.server.spi.MethodHierarchyReader.readMethodHierarchyIfNecessary(MethodHierarchyReader.java:44)
at com.google.api.server.spi.MethodHierarchyReader.getEndpointOverrides(MethodHierarchyReader.java:99)
at com.google.api.server.spi.config.annotationreader.ApiConfigAnnotationReader.readEndpointMethods(ApiConfigAnnotationReader.java:215)
at com.google.api.server.spi.config.annotationreader.ApiConfigAnnotationReader.loadEndpointMethods(ApiConfigAnnotationReader.java:92)
at com.google.api.server.spi.config.ApiConfigLoader.loadConfiguration(ApiConfigLoader.java:55)
at com.google.api.server.spi.tools.AnnotationApiConfigGenerator.generateConfigObjects(AnnotationApiConfigGenerator.java:237)
at com.google.api.server.spi.tools.AnnotationApiConfigGenerator.generateConfig(AnnotationApiConfigGenerator.java:185)
at com.google.api.server.spi.tools.GenApiConfigAction.genApiConfig(GenApiConfigAction.java:78)
at com.google.api.server.spi.tools.GetClientLibAction.getClientLib(GetClientLibAction.java:66)
at com.google.api.server.spi.tools.GetClientLibAction.execute(GetClientLibAction.java:49)
at com.google.api.server.spi.tools.EndpointsTool.execute(EndpointsTool.java:66)
at com.google.api.server.spi.tools.EndpointsTool.main(EndpointsTool.java:92)
Caused by: java.lang.ClassNotFoundException: com.google.common.base.Function
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
... 16 more
It's very simple not to use Guava at this point, and it works. I just want to know why this is happening as I need a more have use of Guava in other parts.
Update:
I think it the same problem as:
Google Cloud Endpoints doesn't know about the Work class from Objectify 4 Transaction, causing ClassNotFoundException
Any tips?
Thanks!

simple Restful call results in InvocationTargetException

I'm using Seam with RestEasy. RestEasy provides httpClient type functionality, among other things.
An action of mine that is called when a page loads (that is, it is called from the xxx.page.xml). The code looks like:
try {
ClientRequest request = new ClientRequest(url);
ClientResponse response = null;
response = request.get();
} catch (Exception e) {
e.printStackTrace();
}
the e.printStackTrace() is never reached, but while trying the request.get(), the code generates the following exception:
Exception during request processing:
Caused by javax.el.ELException with message: "java.lang.reflect.InvocationTargetException"
org.jboss.el.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:339)
org.jboss.el.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:348)
org.jboss.el.parser.AstPropertySuffix.invoke(AstPropertySuffix.java:58)
org.jboss.el.parser.AstValue.invoke(AstValue.java:96)
org.jboss.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:276)
org.jboss.seam.core.Expressions$2.invoke(Expressions.java:175)
org.jboss.seam.navigation.Page.preRender(Page.java:311)
org.jboss.seam.navigation.Pages.preRender(Pages.java:350)
org.jboss.seam.jsf.SeamPhaseListener.preRenderPage(SeamPhaseListener.java:561)
org.jboss.seam.jsf.SeamPhaseListener.beforeRenderResponse(SeamPhaseListener.java:472)
org.jboss.seam.jsf.SeamPhaseListener.beforeServletPhase(SeamPhaseListener.java:148)
org.jboss.seam.jsf.SeamPhaseListener.beforePhase(SeamPhaseListener.java:118)
com.sun.faces.lifecycle.Phase.handleBeforePhase(Phase.java:214)
com.sun.faces.lifecycle.Phase.doPhase(Phase.java:96)
com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
javax.faces.webapp.FacesServlet.service(FacesServlet.java:266)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
Why would a Reflection API call even be involved????