You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomee.apache.org by Daniel Cunha <da...@gmail.com> on 2014/12/28 12:46:13 UTC
Re: tomee git commit: missing files
Thank you Romain! :)
On Sun, Dec 28, 2014 at 11:43 AM, <rm...@apache.org> wrote:
> Repository: tomee
> Updated Branches:
> refs/heads/develop 2a9630a02 -> ce3ee00b9
>
>
> missing files
>
>
> Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
> Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/ce3ee00b
> Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/ce3ee00b
> Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/ce3ee00b
>
> Branch: refs/heads/develop
> Commit: ce3ee00b9cafc4cf73ecf57070ab27aa3f611b37
> Parents: 2a9630a
> Author: Romain Manni-Bucau <rm...@apache.org>
> Authored: Sun Dec 28 12:42:36 2014 +0100
> Committer: Romain Manni-Bucau <rm...@apache.org>
> Committed: Sun Dec 28 12:42:36 2014 +0100
>
> ----------------------------------------------------------------------
> .../openejb/testing/ContainerProperties.java | 37 +++
> .../AppComposerClassConfigurationTest.java | 37 +++
> ...ghtweightWebAppBuilderListenerExtractor.java | 62 ++++
> .../server/httpd/OpenEJBAsyncContext.java | 320 +++++++++++++++++++
> .../openejb/server/httpd/AsyncHttpTest.java | 171 ++++++++++
> 5 files changed, 627 insertions(+)
> ----------------------------------------------------------------------
>
>
>
> http://git-wip-us.apache.org/repos/asf/tomee/blob/ce3ee00b/container/openejb-core/src/main/java/org/apache/openejb/testing/ContainerProperties.java
> ----------------------------------------------------------------------
> diff --git
> a/container/openejb-core/src/main/java/org/apache/openejb/testing/ContainerProperties.java
> b/container/openejb-core/src/main/java/org/apache/openejb/testing/ContainerProperties.java
> new file mode 100644
> index 0000000..8284bdf
> --- /dev/null
> +++
> b/container/openejb-core/src/main/java/org/apache/openejb/testing/ContainerProperties.java
> @@ -0,0 +1,37 @@
> +/*
> + * Licensed to the Apache Software Foundation (ASF) under one or more
> + * contributor license agreements. See the NOTICE file distributed with
> + * this work for additional information regarding copyright ownership.
> + * The ASF licenses this file to You under the Apache License, Version 2.0
> + * (the "License"); you may not use this file except in compliance with
> + * the License. You may obtain a copy of the License at
> + *
> + * http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> implied.
> + * See the License for the specific language governing permissions and
> + * limitations under the License.
> + */
> +package org.apache.openejb.testing;
> +
> +import java.lang.annotation.ElementType;
> +import java.lang.annotation.Retention;
> +import java.lang.annotation.RetentionPolicy;
> +import java.lang.annotation.Target;
> +
> +@Target(ElementType.TYPE)
> +@Retention(RetentionPolicy.RUNTIME)
> +public @interface ContainerProperties {
> + Property[] value();
> +
> + @Target(ElementType.PARAMETER) // TODO: method
> + @Retention(RetentionPolicy.RUNTIME)
> + public @interface Property {
> + String IGNORED = "__not__set__so__ignored";
> +
> + String name();
> + String value() default IGNORED;
> + }
> +}
>
>
> http://git-wip-us.apache.org/repos/asf/tomee/blob/ce3ee00b/container/openejb-core/src/test/java/org/apache/openejb/testing/AppComposerClassConfigurationTest.java
> ----------------------------------------------------------------------
> diff --git
> a/container/openejb-core/src/test/java/org/apache/openejb/testing/AppComposerClassConfigurationTest.java
> b/container/openejb-core/src/test/java/org/apache/openejb/testing/AppComposerClassConfigurationTest.java
> new file mode 100644
> index 0000000..f324536
> --- /dev/null
> +++
> b/container/openejb-core/src/test/java/org/apache/openejb/testing/AppComposerClassConfigurationTest.java
> @@ -0,0 +1,37 @@
> +/*
> + * Licensed to the Apache Software Foundation (ASF) under one or more
> + * contributor license agreements. See the NOTICE file distributed with
> + * this work for additional information regarding copyright ownership.
> + * The ASF licenses this file to You under the Apache License, Version 2.0
> + * (the "License"); you may not use this file except in compliance with
> + * the License. You may obtain a copy of the License at
> + *
> + * http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> implied.
> + * See the License for the specific language governing permissions and
> + * limitations under the License.
> + */
> +package org.apache.openejb.testing;
> +
> +import org.apache.openejb.junit.ApplicationComposerRule;
> +import org.apache.openejb.loader.SystemInstance;
> +import org.junit.Rule;
> +import org.junit.Test;
> +
> +import static org.junit.Assert.assertEquals;
> +
> +@ContainerProperties(@ContainerProperties.Property(name =
> "AppComposerClassConfigurationTest.test", value = "expected result"))
> +@Classes(context = "app")
> +public class AppComposerClassConfigurationTest {
> + @Rule
> + public final ApplicationComposerRule rule = new
> ApplicationComposerRule(this);
> +
> + @Test
> + public void run() {
> + assertEquals("expected result",
> SystemInstance.get().getProperty("AppComposerClassConfigurationTest.test"));
> + assertEquals("expected result",
> System.getProperty("AppComposerClassConfigurationTest.test"));
> + }
> +}
>
>
> http://git-wip-us.apache.org/repos/asf/tomee/blob/ce3ee00b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/LightweightWebAppBuilderListenerExtractor.java
> ----------------------------------------------------------------------
> diff --git
> a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/LightweightWebAppBuilderListenerExtractor.java
> b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/LightweightWebAppBuilderListenerExtractor.java
> new file mode 100644
> index 0000000..5dddd47
> --- /dev/null
> +++
> b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/LightweightWebAppBuilderListenerExtractor.java
> @@ -0,0 +1,62 @@
> +/*
> + * Licensed to the Apache Software Foundation (ASF) under one or more
> + * contributor license agreements. See the NOTICE file distributed with
> + * this work for additional information regarding copyright ownership.
> + * The ASF licenses this file to You under the Apache License, Version 2.0
> + * (the "License"); you may not use this file except in compliance with
> + * the License. You may obtain a copy of the License at
> + *
> + * http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> implied.
> + * See the License for the specific language governing permissions and
> + * limitations under the License.
> + */
> +package org.apache.openejb.server.httpd;
> +
> +import org.apache.openejb.AppContext;
> +import org.apache.openejb.assembler.classic.WebAppBuilder;
> +import org.apache.openejb.core.WebContext;
> +import org.apache.openejb.loader.SystemInstance;
> +import org.apache.openejb.spi.ContainerSystem;
> +import org.apache.openejb.web.LightweightWebAppBuilder;
> +
> +import java.util.ArrayList;
> +import java.util.Collection;
> +import java.util.Collections;
> +
> +// could be optimized since we could bind to the request the listeners in
> org.apache.openejb.server.httpd.OpenEJBHttpRegistry.ClassLoaderHttpListener.onMessage()
> +// but ok for now since that's fully for the embedded mode
> +public final class LightweightWebAppBuilderListenerExtractor {
> + public static <T> Collection<T> findByTypeForContext(final String
> context, final Class<T> type) {
> + final WebAppBuilder builder =
> SystemInstance.get().getComponent(WebAppBuilder.class);
> + if (!LightweightWebAppBuilder.class.isInstance(builder)) {
> + return Collections.emptyList();
> + }
> +
> + for (final AppContext app :
> SystemInstance.get().getComponent(ContainerSystem.class).getAppContexts()) {
> + for (final WebContext web : app.getWebContexts()) {
> + if (web.getContextRoot().replace("/",
> "").equals(context.replace("/", ""))) {
> + final Collection<Object> potentials =
> LightweightWebAppBuilder.class.cast(builder).listenersFor(web.getContextRoot());
> + if (potentials == null) {
> + return Collections.emptyList();
> + }
> + final Collection<T> filtered = new
> ArrayList<>(potentials.size());
> + for (final Object o : potentials) {
> + if (type.isInstance(o)) {
> + filtered.add(type.cast(o));
> + }
> + }
> + return filtered;
> + }
> + }
> + }
> + return Collections.emptyList();
> + }
> +
> + private LightweightWebAppBuilderListenerExtractor() {
> + // no-op
> + }
> +}
>
>
> http://git-wip-us.apache.org/repos/asf/tomee/blob/ce3ee00b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/OpenEJBAsyncContext.java
> ----------------------------------------------------------------------
> diff --git
> a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/OpenEJBAsyncContext.java
> b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/OpenEJBAsyncContext.java
> new file mode 100644
> index 0000000..bdd3b4e
> --- /dev/null
> +++
> b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/OpenEJBAsyncContext.java
> @@ -0,0 +1,320 @@
> +/**
> + * Licensed to the Apache Software Foundation (ASF) under one or more
> + * contributor license agreements. See the NOTICE file distributed with
> + * this work for additional information regarding copyright ownership.
> + * The ASF licenses this file to You under the Apache License, Version 2.0
> + * (the "License"); you may not use this file except in compliance with
> + * the License. You may obtain a copy of the License at
> + *
> + * http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> implied.
> + * See the License for the specific language governing permissions and
> + * limitations under the License.
> + */
> +package org.apache.openejb.server.httpd;
> +
> +import org.apache.openejb.AppContext;
> +import org.apache.openejb.OpenEJBRuntimeException;
> +import org.apache.openejb.core.WebContext;
> +import org.apache.openejb.loader.SystemInstance;
> +import org.apache.openejb.spi.ContainerSystem;
> +import org.apache.openejb.util.DaemonThreadFactory;
> +
> +import javax.servlet.AsyncContext;
> +import javax.servlet.AsyncEvent;
> +import javax.servlet.AsyncListener;
> +import javax.servlet.ServletContext;
> +import javax.servlet.ServletException;
> +import javax.servlet.ServletRequest;
> +import javax.servlet.ServletResponse;
> +import javax.servlet.http.HttpServletRequest;
> +import javax.servlet.http.HttpServletResponse;
> +import java.io.IOException;
> +import java.net.HttpURLConnection;
> +import java.net.Socket;
> +import java.util.ArrayList;
> +import java.util.List;
> +import java.util.Set;
> +import java.util.concurrent.CopyOnWriteArraySet;
> +import java.util.concurrent.Executors;
> +import java.util.concurrent.ScheduledExecutorService;
> +import java.util.concurrent.TimeUnit;
> +
> +// stupid impl, ~ mock. it handles itself eviction to avoid to have it
> always started which is not the common case
> +public class OpenEJBAsyncContext implements AsyncContext {
> + private static final Set<OpenEJBAsyncContext> INITIALIZED = new
> CopyOnWriteArraySet<>();
> + private static volatile ScheduledExecutorService es;
> +
> + public static void destroy() {
> + if (es == null) {
> + return;
> + }
> + es.shutdownNow();
> + for (final OpenEJBAsyncContext ctx : new
> ArrayList<>(INITIALIZED)) {
> + if (ctx.lastTouch + ctx.getTimeout() <
> System.currentTimeMillis()) {
> + for (final AsyncListener listener : ctx.listeners) {
> + try {
> + listener.onTimeout(ctx.event);
> + } catch (final IOException t) {
> + throw new OpenEJBRuntimeException(t);
> + }
> + }
> + ctx.complete();
> + }
> + }
> + INITIALIZED.clear();
> + }
> +
> + public static void init() {
> + if
> (!"true".equalsIgnoreCase(SystemInstance.get().getProperty("openejb.http.async.eviction",
> "true"))) {
> + return;
> + }
> + es = Executors.newScheduledThreadPool(1, new
> DaemonThreadFactory(OpenEJBAsyncContext.class));
> + es.scheduleWithFixedDelay(new Runnable() {
> + @Override
> + public void run() {
> + for (final OpenEJBAsyncContext ctx : new
> ArrayList<>(INITIALIZED)) {
> + if (ctx.lastTouch + ctx.getTimeout() <
> System.currentTimeMillis()) {
> + INITIALIZED.remove(ctx);
> + for (final AsyncListener listener :
> ctx.listeners) {
> + try {
> + listener.onTimeout(ctx.event);
> + } catch (final IOException t) {
> + throw new OpenEJBRuntimeException(t);
> + }
> + }
> + ctx.complete();
> + }
> + }
> + }
> + }, 1, 1, TimeUnit.MINUTES);
> + }
> +
> + private final List<AsyncListener> listeners = new ArrayList<>();
> + private final ServletResponse response;
> + private final HttpRequestImpl request;
> + private final Socket socket;
> + private final AsyncEvent event;
> + private WebContext context = null;
> + private volatile boolean started = false;
> + private volatile boolean committed = false;
> + private long timeout = 30000;
> + private long lastTouch = System.currentTimeMillis();
> +
> + public OpenEJBAsyncContext(final HttpRequestImpl request, final
> ServletResponse response, final String contextPath) {
> + if (es == null) {
> + synchronized (OpenEJBAsyncContext.class) { // we don't care
> since impl is not really thread safe, just here for testing
> + if (es == null) {
> + init();
> + }
> + }
> + }
> +
> + this.request = request;
> + if (contextPath != null) {
> + for (final AppContext app :
> SystemInstance.get().getComponent(ContainerSystem.class).getAppContexts()) {
> + for (final WebContext web : app.getWebContexts()) {
> + if (web.getContextRoot().replace("/",
> "").equals(contextPath.replace("/", ""))) {
> + this.context = web;
> + break;
> + }
> + }
> + }
> + }
> + this.response = response;
> + this.socket =
> Socket.class.cast(request.getAttribute("openejb_socket"));
> + this.event = new AsyncEvent(this, request, response);
> + INITIALIZED.add(this);
> + }
> +
> + @Override
> + public void complete() {
> + for (final AsyncListener listener : listeners) {
> + try {
> + listener.onComplete(event);
> + } catch (final IOException t) {
> + throw new OpenEJBRuntimeException(t);
> + }
> + }
> +
> + commit();
> + }
> +
> + private void onError(final Throwable ignored) {
> + for (final AsyncListener listener : listeners) {
> + try {
> + listener.onError(event);
> + } catch (final IOException t) {
> + throw new OpenEJBRuntimeException(t);
> + }
> + }
> + try {
> +
> HttpServletResponse.class.cast(response).sendError(HttpURLConnection.HTTP_INTERNAL_ERROR);
> + commit();
> + } catch (final IOException e) {
> + // no-op
> + }
> + }
> +
> + private void commit() {
> + if (committed) { // avoid to commit it twice on errors (often a
> listener will do it, we just force it in case of)
> + return;
> + }
> + committed = true;
> + if (HttpResponseImpl.class.isInstance(response) && socket !=
> null) {
> + try {
> +
> HttpResponseImpl.class.cast(response).writeMessage(socket.getOutputStream(),
> false);
> + } catch (final IOException e) {
> + // no-op
> + }
> + } // else TODO
> +
> + if (socket != null) {
> + try {
> + socket.getInputStream().close();
> + } catch (final IOException e) {
> + // no-op
> + }
> + try {
> + socket.getOutputStream().close();
> + } catch (final IOException e) {
> + // no-op
> + }
> + try {
> + socket.close();
> + } catch (final IOException e) {
> + // no-op
> + }
> + }
> + }
> +
> + @Override
> + public void dispatch() {
> + String path;
> + final String pathInfo;
> + ServletRequest servletRequest = getRequest();
> + if (servletRequest instanceof HttpServletRequest) {
> + HttpServletRequest sr = (HttpServletRequest) servletRequest;
> + path = sr.getServletPath();
> + pathInfo = sr.getPathInfo();
> + } else {
> + path = request.getServletPath();
> + pathInfo = request.getPathInfo();
> + }
> + if (pathInfo != null) {
> + path += pathInfo;
> + }
> + dispatch(path);
> + }
> +
> + @Override
> + public void dispatch(final String path) {
> + dispatch(request.getServletContext(), path);
> + }
> +
> + @Override
> + public void dispatch(final ServletContext context, final String path)
> {
> + final HttpListenerRegistry registry =
> SystemInstance.get().getComponent(HttpListenerRegistry.class);
> + try {
> + final String contextPath =
> this.context.getContextRoot().startsWith("/") ?
> this.context.getContextRoot() : ('/' + this.context.getContextRoot());
> + final HttpRequestImpl req = new
> HttpRequestImpl(request.getSocketURI()) {
> + @Override
> + public String getContextPath() {
> + return contextPath;
> + }
> +
> + @Override
> + public String getServletPath() {
> + return path;
> + }
> +
> + @Override
> + public String getRequestURI() {
> + return contextPath + path;
> + }
> + };
> + registry.onMessage(req,
> HttpResponse.class.isInstance(response) ? HttpResponse.class.cast(response)
> : new ServletResponseAdapter(HttpServletResponse.class.cast(response)));
> + complete();
> + } catch (final Exception e) {
> + onError(e);
> + }
> + }
> +
> + @Override
> + public ServletRequest getRequest() {
> + return request;
> + }
> +
> + @Override
> + public ServletResponse getResponse() {
> + if (response == null) {
> + throw new IllegalStateException("no response");
> + }
> + return response;
> + }
> +
> + @Override
> + public void start(final Runnable run) {
> + internalStartAsync();
> + // TODO: another thread
> + run.run();
> + }
> +
> + public void internalStartAsync() {
> + started = true;
> + for (final AsyncListener listener : listeners) {
> + try {
> + listener.onStartAsync(event);
> + } catch (final IOException t) {
> + throw new OpenEJBRuntimeException(t);
> + }
> + }
> + }
> +
> + @Override
> + public void addListener(final AsyncListener listener) {
> + listeners.add(listener);
> + if (started) {
> + try {
> + listener.onStartAsync(event);
> + } catch (final IOException e) {
> + throw new OpenEJBRuntimeException(e);
> + }
> + }
> + }
> +
> + @Override
> + public void addListener(final AsyncListener listener,
> + final ServletRequest servletRequest,
> + final ServletResponse servletResponse) {
> + addListener(listener);
> + }
> +
> + @Override
> + public <T extends AsyncListener> T createListener(final Class<T>
> clazz)
> + throws ServletException {
> + try {
> + return (T) context.inject(clazz.newInstance());
> + } catch (final Exception e) {
> + throw new ServletException(e);
> + }
> + }
> +
> + @Override
> + public boolean hasOriginalRequestAndResponse() {
> + return true;
> + }
> +
> + @Override
> + public long getTimeout() {
> + return timeout;
> + }
> +
> + @Override
> + public void setTimeout(long timeout) {
> + this.timeout = timeout;
> + }
> +}
>
>
> http://git-wip-us.apache.org/repos/asf/tomee/blob/ce3ee00b/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/AsyncHttpTest.java
> ----------------------------------------------------------------------
> diff --git
> a/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/AsyncHttpTest.java
> b/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/AsyncHttpTest.java
> new file mode 100644
> index 0000000..41c8117
> --- /dev/null
> +++
> b/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/AsyncHttpTest.java
> @@ -0,0 +1,171 @@
> +/*
> + * Licensed to the Apache Software Foundation (ASF) under one or more
> + * contributor license agreements. See the NOTICE file distributed with
> + * this work for additional information regarding copyright ownership.
> + * The ASF licenses this file to You under the Apache License, Version 2.0
> + * (the "License"); you may not use this file except in compliance with
> + * the License. You may obtain a copy of the License at
> + *
> + * http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> implied.
> + * See the License for the specific language governing permissions and
> + * limitations under the License.
> + */
> +package org.apache.openejb.server.httpd;
> +
> +import org.apache.openejb.junit.ApplicationComposerRule;
> +import org.apache.openejb.loader.IO;
> +import org.apache.openejb.testing.Classes;
> +import org.apache.openejb.testing.ContainerProperties;
> +import org.apache.openejb.testing.EnableServices;
> +import org.apache.openejb.testing.RandomPort;
> +import org.junit.Rule;
> +import org.junit.Test;
> +
> +import javax.inject.Inject;
> +import javax.servlet.AsyncContext;
> +import javax.servlet.AsyncEvent;
> +import javax.servlet.AsyncListener;
> +import javax.servlet.ServletException;
> +import javax.servlet.annotation.WebServlet;
> +import javax.servlet.http.HttpServlet;
> +import javax.servlet.http.HttpServletRequest;
> +import javax.servlet.http.HttpServletResponse;
> +import java.io.IOException;
> +import java.net.URL;
> +import java.util.concurrent.ExecutorService;
> +import java.util.concurrent.Executors;
> +
> +import static org.junit.Assert.assertEquals;
> +import static org.junit.Assert.assertTrue;
> +
> +@EnableServices("http")
> +@Classes(cdi = true, innerClassesAsBean = true)
> +@ContainerProperties(@ContainerProperties.Property(name =
> "httpejbd.useJetty", value = "fase"))
> +public class AsyncHttpTest {
> + @Rule
> + public final ApplicationComposerRule container = new
> ApplicationComposerRule(this);
> +
> + @RandomPort("http")
> + private URL context;
> +
> + @Test
> + public void async() throws IOException {
> + SimpleAsyncListener.started = false;
> + assertEquals("OK", IO.slurp(new URL(context.toExternalForm() +
> "openejb/AsyncServlet")));
> + assertTrue(SimpleAsyncListener.started);
> + }
> +
> + @Test
> + public void asyncDispatch() throws IOException {
> + assertEquals("OK2", IO.slurp(new URL(context.toExternalForm() +
> "openejb/DispatchAsyncServlet")));
> + }
> +
> + @WebServlet(name = "AsyncServlet", urlPatterns = "/AsyncServlet",
> asyncSupported = true)
> + public static class AsyncServlet extends HttpServlet {
> + private ExecutorService executorService;
> +
> + @Override
> + public void init() throws ServletException {
> + executorService = Executors.newSingleThreadExecutor();
> + }
> +
> + @Override
> + protected void service(final HttpServletRequest req, final
> HttpServletResponse resp) throws ServletException, IOException {
> + final AsyncContext actx = req.startAsync();
> +
> actx.addListener(actx.createListener(SimpleAsyncListener.class));
> + resp.setContentType("text/plain");
> + executorService.execute(new AsyncHandler(actx));
> + }
> +
> + @Override
> + public void destroy() {
> + executorService.shutdownNow();
> + }
> + }
> +
> + @WebServlet(name = "DispatchAsyncServlet", urlPatterns =
> "/DispatchAsyncServlet", asyncSupported = true)
> + public static class DispatchAsyncServlet extends HttpServlet {
> + private ExecutorService executorService;
> +
> + @Override
> + public void init() throws ServletException {
> + executorService = Executors.newSingleThreadExecutor();
> + }
> +
> + @Override
> + protected void service(final HttpServletRequest req, final
> HttpServletResponse resp) throws ServletException, IOException {
> + final AsyncContext actx = req.startAsync();
> + resp.setContentType("text/plain");
> + actx.dispatch("/ok");
> + }
> +
> + @Override
> + public void destroy() {
> + executorService.shutdownNow();
> + }
> + }
> +
> + public static class ABean {}
> +
> + public static class SimpleAsyncListener implements AsyncListener {
> + private static boolean started;
> +
> + @Inject
> + private ABean bean;
> +
> + @Override
> + public void onComplete(final AsyncEvent event) throws IOException
> {
> + // no-op
> + }
> +
> + @Override
> + public void onTimeout(AsyncEvent event) throws IOException {
> + // no-op
> + }
> +
> + @Override
> + public void onError(AsyncEvent event) throws IOException {
> + // no-op
> + }
> +
> + @Override
> + public void onStartAsync(final AsyncEvent event) throws
> IOException {
> + started = bean != null;
> + }
> + }
> +
> + @WebServlet("/ok")
> + public static class SimpleServlet extends HttpServlet {
> + @Override
> + protected void service(final HttpServletRequest req, final
> HttpServletResponse resp) throws ServletException, IOException {
> + resp.getWriter().write("OK2");
> + }
> + }
> +
> + private static class AsyncHandler implements Runnable {
> + private final AsyncContext actx;
> +
> + public AsyncHandler(final AsyncContext ctx) {
> + this.actx = ctx;
> + }
> +
> + @Override
> + public void run() {
> + try {
> + actx.getResponse().getWriter().write("OK");
> + } catch (final IOException e) {
> + try {
> +
> HttpServletResponse.class.cast(actx.getResponse()).sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
> + } catch (final IOException e1) {
> + // no-op
> + }
> + actx.complete();
> + }
> + actx.complete();
> + }
> + }
> +}
>
>
--
Daniel Cunha (soro)