SEVERE: UT000004: getResponseChannel() has already been called
by Karthick V.J.
Hi Undertow Devs,
I was getting the below error in my application. I created a sample application which throws the same error (Attached is the sample applicaiton) When I added the exchange.dispatch() statement at line 158, the problem resolves. Is it required to dispatch () every time the context is switched to a new thread. Am I doing it right?
Thank You - Karthick
Error:
------------SEVERE: UT000004: getResponseChannel() has already been called
java.lang.IllegalStateException: UT000004: getResponseChannel() has already been called
at io.undertow.io.AsyncSenderImpl.send(AsyncSenderImpl.java:208)
at io.undertow.io.AsyncSenderImpl.send(AsyncSenderImpl.java:294)
at io.undertow.io.AsyncSenderImpl.send(AsyncSenderImpl.java:270)
at io.undertow.io.AsyncSenderImpl.send(AsyncSenderImpl.java:300)
.....
.....
.....
.....
at com.google.common.util.concurrent.Futures$4.run(Futures.java:1181)
at com.google.common.util.concurrent.MoreExecutors$SameThreadExecutorService.execute(MoreExecutors.java:297)
at com.google.common.util.concurrent.ExecutionList.executeListener(ExecutionList.java:156)
at com.google.common.util.concurrent.ExecutionList.execute(ExecutionList.java:145)
at com.google.common.util.concurrent.AbstractFuture.set(AbstractFuture.java:185)
at com.google.common.util.concurrent.Futures$ChainingListenableFuture$1.run(Futures.java:872)
at com.google.common.util.concurrent.MoreExecutors$SameThreadExecutorService.execute(MoreExecutors.java:297)
at com.google.common.util.concurrent.Futures$ImmediateFuture.addListener(Futures.java:102)
at com.google.common.util.concurrent.Futures$ChainingListenableFuture.run(Futures.java:868)
at com.google.common.util.concurrent.MoreExecutors$SameThreadExecutorService.execute(MoreExecutors.java:297)
at com.google.common.util.concurrent.ExecutionList.executeListener(ExecutionList.java:156)
at com.google.common.util.concurrent.ExecutionList.execute(ExecutionList.java:145)
at com.google.common.util.concurrent.AbstractFuture.set(AbstractFuture.java:185)
at com.datastax.driver.core.DefaultResultSetFuture.onSet(DefaultResultSetFuture.java:105)
at com.datastax.driver.core.RequestHandler.setFinalResult(RequestHandler.java:246)
at com.datastax.driver.core.RequestHandler.onSet(RequestHandler.java:278)
at com.datastax.driver.core.Connection$Dispatcher.messageReceived(Connection.java:661)
at org.jboss.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleChannelUpstreamHandler.java:70)
at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:564)
at org.jboss.netty.channel.DefaultChannelPipeline$DefaultChannelHandlerContext.sendUpstream(DefaultChannelPipeline.java:791)
at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:296)
at org.jboss.netty.handler.codec.oneone.OneToOneDecoder.handleUpstream(OneToOneDecoder.java:70)
at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:564)
at org.jboss.netty.channel.DefaultChannelPipeline$DefaultChannelHandlerContext.sendUpstream(DefaultChannelPipeline.java:791)
at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:296)
at org.jboss.netty.handler.codec.frame.FrameDecoder.unfoldAndFireMessageReceived(FrameDecoder.java:462)
at org.jboss.netty.handler.codec.frame.FrameDecoder.callDecode(FrameDecoder.java:443)
at org.jboss.netty.handler.codec.frame.FrameDecoder.messageReceived(FrameDecoder.java:303)
at org.jboss.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleChannelUpstreamHandler.java:70)
at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:564)
at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:559)
at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:268)
at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:255)
at org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:88)
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.process(AbstractNioWorker.java:108)
at org.jboss.netty.channel.socket.nio.AbstractNioSelector.run(AbstractNioSelector.java:318)
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.run(AbstractNioWorker.java:89)
at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:178)
at org.jboss.netty.util.ThreadRenamingRunnable.run(ThreadRenamingRunnable.java:108)
at org.jboss.netty.util.internal.DeadLockProofWorker$1.run(DeadLockProofWorker.java:42)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
------------
9 years, 10 months
req.authenticate() problems 1.1.0
by Bill Burke
When upgrading from Undertow 1.0.15 to 1.1.0 our
HttpServleRequest.authenticate() unit test is failing. An exception is
being thrown in HttpServletRequestImpl.authenticate() line 416.
Our auth mechanism is being called correctly. It sets the status code
(302) and the Location header within a challenge object. It looks like
exchange.isResponseStarted() is returning false even though my challenge
object is setting up the resposne correctly. Am I supposed to call
exchange.endExchange() or something within my Challenge object? I tried
doing that, but Undertow is now spitting out exception messages:
java.lang.IllegalStateException: UT000002: The response has already been
started
at
io.undertow.server.HttpServerExchange.setResponseCode(HttpServerExchange.java:1246)
at
io.undertow.security.impl.SecurityContextImpl$ChallengeSender.transition(SecurityContextImpl.java:355)
at
io.undertow.security.impl.SecurityContextImpl$ChallengeSender.transition(SecurityContextImpl.java:349)
at
io.undertow.security.impl.SecurityContextImpl$ChallengeSender.transition(SecurityContextImpl.java:349)
at
io.undertow.security.impl.SecurityContextImpl$ChallengeSender.access$300(SecurityContextImpl.java:314)
at
io.undertow.security.impl.SecurityContextImpl.sendChallenges(SecurityContextImpl.java:135)
at
io.undertow.security.impl.SecurityContextImpl.authTransition(SecurityContextImpl.java:109)
at
io.undertow.security.impl.SecurityContextImpl.authenticate(SecurityContextImpl.java:99)
at
io.undertow.servlet.spec.HttpServletRequestImpl.authenticate(HttpServletRequestImpl.java:404)
--
Bill Burke
JBoss, a division of Red Hat
http://bill.burkecentral.com
9 years, 11 months
AuthMechanism called always?
by Bill Burke
A user is reporting that our Keycloak AuthMechanism is being called even
with unsecured resources. They have constraints defined in web.xml, but
if the constraint is unmatched (unsecure) the mechanism is still called.
Why is the auth mechanism called for unsecure resources?
--
Bill Burke
JBoss, a division of Red Hat
http://bill.burkecentral.com
9 years, 11 months
Undertow http client
by David Simansky
Hi all,
I have a question regarding Undertow http client. I would like to achieve something similar to what jetty http client or apache http clients can do. Pretty much just send out http requests with different kind of method(+possibly include payload). The question is, if the undertow client classes are meant to be used that way because my google search haven't found any example of usage like that. Is there any convenient way I could go for?
Thanks,
David
9 years, 11 months
scala, activate, nio, async jdbc, future, threads
by Laurent Bedubourg
Hello,
I am evaluating Undertow and trying to fit an async database (with scala,
Activate and https://github.com/mauricio/postgresql-async which use netty
and nio).
The good news is that it more or less works.
My main concern is that the database system create threads using scala
futures and that I am forced to "Await" for the result of my Futures to
send the result to the HttpServerExchange.
I am forced to dispath() the request because Await locks the current thread
and I shouldn't lock the IO thread from my Handler, should I?
It made me wondering : is is really a good idea to use futures + Await with
undertow and more generaly nio?
If the thread pool is limited and I lock threads, even if the database
driver is async and uses nio, am I bitting my own leg?
Thanks for any input you can give me and sorry if it's too scala related :)
Regards
Laurent
PS: Here's the handleRequest I am using to test this, any comment or help
welcome too since I am discovering the API.
def handleRequest(x:io.undertow.server.HttpServerExchange){
if (x.isInIoThread()){
x.dispatch(this)
return
}
// useful or not? no change
// x.startBlocking()
// Ok, we are in worker thread we can work a little with database
// val f = asyncTransactionalChain { implicit context =>
// for (
// a <- asyncTransactional { new AMember("aaa") };
// b <- asyncById[AMember](a.id)
// ) yield b
// }
// Simulate database work with just a future
val f = future {
Some(1)
}(scala.concurrent.ExecutionContext.Implicits.global)
// send string to xchange
def sendReply(str:String){
x.getResponseHeaders().put(io.undertow.util.Headers.CONTENT_TYPE,
"text/plain")
x.getResponseSender().send(str)
// x.endExchange()
}
// // this fails
// f.onSuccess {
// case Some(result) => sendReply(result.toString)
// }(scala.concurrent.ExecutionContext.Implicits.global)
// // this works
val result = Await.result(f, Duration(1000, MILLISECONDS))
sendReply(result.toString)
}
9 years, 11 months
UTF8 form parsing
by Laurent Bedubourg
Hello,
I am using utf-8 as default encoding for the web and it didn't worked out
of the box with Undertow and EagerFormParsingHandler.
It turned out that MultiPartParserDefinition has a default iso-8859-1
encoding and that it's quite hard to change it. You have to create a custom
FormParserFactory containing a MultiPartParserDefinition with the right
setDefaultEncoding() that's a lot of work for something that common and I
had to spend half an hour looking at Undertow sources to understand how it
work and why my input was garbage.
The assumption that Browsers will add a "; charset=UTF-8" to the Content
type is false (at least with google chrome).
My temporary hack is to override EagerFormParsingHandler and modify the
request CONTENT_TYPE header to add the UTF-8 charset and then setNext my
real HttpHandler (I had less mental friction doing this than learning how
to create my custom FormParserFactor).
new EagerFormParsingHandler(){
override def handleRequest(x:HttpServerExchange){
val ct = x.getRequestHeaders().get(Headers.CONTENT_TYPE).getLast()
x.getRequestHeaders().put(Headers.CONTENT_TYPE, ct+"; charset=UTF-8")
super.handleRequest(x)
}
}.setNext(new HttpHandler(){
def handleRequest(x:HttpServerExchange){ ... }
})
Now that I know it I can create my own Utf8FormParsingHandler but I imagine
that other users will want to be able to define the encoding out of the box.
Maybe with a new self documenting contructor like :
new EagerFormParsingHandler(encoding:String, nextHandler:HttpHandler)
Best regards
Laurent
9 years, 11 months
exchange.isInIoThread()
by Bill Burke
I'm using the Undertow ProxyHandler, should I be executing the
ProxyHandler in a separate thread? What I"m running into right now is
that I'm making a nested HTTP call within a Servlet request ( GET
http://proxy.com which invokes a call to http://proxy.com/test) and the
2nd call isn't getting through.
The nested call never gets passed AuthenticationCallHandler line 46.
--
Bill Burke
JBoss, a division of Red Hat
http://bill.burkecentral.com
9 years, 11 months
HTTP/2 REST API
by Davide Ungari
Hi,
I would like to understand how to make a REST API with RestEasy and
Undertow be served with HTTP/2 or SPDY. How have I to configure Undertow?
I have a frontend application running on Undertow calling this REST API on
another Undertow instance. How can I configure both to use HTTP/2?
Does all this "optimization" make sense?
Thanks everybody
--
Davide
9 years, 11 months
Unexpected RequestLimitingHandler behavior after queue gets full
by Piotr Betkier
Hello,
I wanted to introduce a constraint on the number of requests my server
tries to handle at a time and played around with RequestLimitingHandler a
little bit. However, I observed unexpected behavior once RequestLimit's
queue gets full.
I've created a RequestLimitingHandler with both maximumConcurrentRequests
and queueSize set to 1 and nextHandler that responds after a 3 second
sleep. This is what I observed:
When I sent 2 concurrent requests with a curl, I got the first response
after 3 seconds and the second one after 6 - just as expected, the second
request got queued.
When I sent 3 concurrent requests, I got two correct responses and one 513
- just as expected, my third request couldn't fit into the queue so a
failure handler got called.
Now it got tricky - this made RequestLimit enter an invalid state, where
its "state" field got decremented below the value that represents 0 current
requests. Now "state & MASK_CURRENT" gives 2147483647 instead of 0, so the
next time I make a single request, RequestLimit thinks there are 2147483647
requests in the system currently and queues my request instead of handling
it. Then I make yet another request and now the queue is full, so 513 error
is generated instantly which in turn makes RequestLimit poll my first
pending request from the queue and dispatch it for handling. RequestLimit
got corrupted and is unusable from now on.
I hope I explained my observations clearly. Is there something wrong in my
setup, my understanding of Undertow or it's a bug? This is my code snippet,
tested with undertow 1.1.0.Final and 1.2.0.Beta5:
import io.undertow.Undertow;
import io.undertow.server.HttpHandler;
import io.undertow.server.HttpServerExchange;
import io.undertow.server.handlers.RequestLimitingHandler;
import io.undertow.util.Headers;
public class Main {
public static void main(String[] args) {
Undertow server = Undertow.builder()
.addHttpListener(8080, "localhost")
.setHandler(new RequestLimitingHandler(1, 1, handler()))
.build();
server.start();
}
private static HttpHandler handler() {
return new HttpHandler() {
@Override
public void handleRequest(final HttpServerExchange exchange)
throws Exception {
Thread.sleep(3000);
exchange.getResponseHeaders().put(Headers.CONTENT_TYPE,
"text/plain");
exchange.getResponseSender().send("Hello World");
}
};
}
}
Cheers,
Piotr
9 years, 11 months