-
-
Save mkarg/a38a68f6025f1ef6ddb4916022bd150d to your computer and use it in GitHub Desktop.
/* | |
* Copyright (c) 2018 Markus KARG. All rights reserved. | |
* | |
* This program and the accompanying materials are made available under the | |
* terms of the Eclipse Public License v. 2.0, which is available at | |
* http://www.eclipse.org/legal/epl-2.0. | |
* | |
* This Source Code may also be made available under the following Secondary | |
* Licenses when the conditions for such availability set forth in the | |
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License, | |
* version 2 with the GNU Classpath Exception, which is available at | |
* https://www.gnu.org/software/classpath/license.html. | |
* | |
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 | |
*/ | |
package jaxrs.examples.bootstrap; | |
import java.io.IOException; | |
import java.util.concurrent.CompletableFuture; | |
import java.util.concurrent.ExecutionException; | |
import javax.ws.rs.JAXRS; | |
import javax.ws.rs.JAXRS.Instance; | |
/** | |
* Minimum Java SE Bootstrap Example | |
* | |
* @author Markus KARG ([email protected]) | |
*/ | |
public class MinimumSeBootstrapExample { | |
public void main(final String[] args) throws IOException, InterruptedException, ExecutionException { | |
final CompletableFuture<Instance> boot = JAXRS.start(new HelloWorld(), JAXRS.Configuration.builder().build()).toCompletableFuture(); | |
final Instance instance = boot.get(); | |
System.out.println("Press any key to shutdown."); | |
System.in.read(); | |
instance.stop().toCompletableFuture().join(); | |
} | |
} |
@spericas To keep the threads together, I just answered on your proposal on stop
not being asynchronous anymore in the original PR.
@RogerGL Updated structure of minimal example, see https://gist.github.com/mkarg/a38a68f6025f1ef6ddb4916022bd150d#gistcomment-2600889.
@spericas Regarding the example you had in mind I do not understand why you catch exceptions?
@mkark probably I misconfigured something but now I get:
Error:(54, 43) java: cannot find symbol
symbol: variable HTTP_SERVER_ANNIHILATOR
location: class org.glassfish.jersey.server.ServerProperties
Error:(52, 43) java: cannot find symbol
symbol: variable HTTP_SERVER_PROVIDER
location: class org.glassfish.jersey.server.ServerProperties
Ok, got the wrong commit. Now I'm only having some problems with the IDE to recognize the new Jersey version.
Ok, almost there. Now I get (running on Mac OS X):
Exception in thread "main" java.util.concurrent.CompletionException: javax.ws.rs.ProcessingException: Failed to start Grizzly HTTP server: Permission denied
at java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:273)
at java.util.concurrent.CompletableFuture.completeThrowable(CompletableFuture.java:280)
at java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1592)
at java.util.concurrent.CompletableFuture$AsyncSupply.exec(CompletableFuture.java:1582)
at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
Caused by: javax.ws.rs.ProcessingException: Failed to start Grizzly HTTP server: Permission denied
at org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory.createHttpServer(GrizzlyHttpServerFactory.java:270)
at org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory.createHttpServer(GrizzlyHttpServerFactory.java:93)
at org.glassfish.jersey.server.internal.RuntimeDelegateImpl.lambda$0(RuntimeDelegateImpl.java:107)
at java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1590)
... 5 more
Caused by: java.net.SocketException: Permission denied
at sun.nio.ch.Net.bind0(Native Method)
at sun.nio.ch.Net.bind(Net.java:433)
at sun.nio.ch.Net.bind(Net.java:425)
at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:223)
at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74)
at org.glassfish.grizzly.nio.transport.TCPNIOBindingHandler.bindToChannelAndAddress(TCPNIOBindingHandler.java:131)
at org.glassfish.grizzly.nio.transport.TCPNIOBindingHandler.bind(TCPNIOBindingHandler.java:88)
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.bind(TCPNIOTransport.java:239)
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.bind(TCPNIOTransport.java:219)
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.bind(TCPNIOTransport.java:210)
at org.glassfish.grizzly.http.server.NetworkListener.start(NetworkListener.java:735)
at org.glassfish.grizzly.http.server.HttpServer.start(HttpServer.java:280)
at org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory.createHttpServer(GrizzlyHttpServerFactory.java:267)
... 8 more
Ok this one is working now. BTW: The @ApplicationPath("helloworld") seems to be ignored.
JAXRS.start(new HelloWorld(), JAXRS.Configuration.builder()
.property(ServerProperties.HTTP_SERVER_PROVIDER,
(BiFunction<URI, ResourceConfig, HttpServer>) GrizzlyHttpServerFactory::createHttpServer)
.property(ServerProperties.HTTP_SERVER_ANNIHILATOR, (Consumer<HttpServer>) HttpServer::shutdownNow)
.property(JAXRS.Configuration.PORT, 8080)
.build())
.thenCompose((JAXRS.Instance instance) -> {
try {
System.out.println("Press any key to shutdown.");
System.in.read();
return instance.stop();
} catch (final IOException e) {
throw new CompletionException(e);
}
}).toCompletableFuture().join();
I would like to have more separate building blocks in the examples. What do you think ?
/**
* Starts the example.
*
* @param args Command line arguments
*/
public static void main(final String[] args) {
CompletionStage<JAXRS.Instance> startedInstance = JAXRS.start(new HelloWorld(), createConfiguration());
startedInstance.thenCompose((JAXRS.Instance instance) -> {
try {
System.out.println("Press any key to shutdown.");
System.in.read();
return instance.stop();
} catch (final IOException e) {
throw new CompletionException(e);
}
}).toCompletableFuture().join();
}
private static JAXRS.Configuration createConfiguration() {
return JAXRS.Configuration.builder()
.property(ServerProperties.HTTP_SERVER_PROVIDER,
(BiFunction<URI, ResourceConfig, HttpServer>) GrizzlyHttpServerFactory::createHttpServer)
.property(ServerProperties.HTTP_SERVER_ANNIHILATOR, (Consumer<HttpServer>) HttpServer::shutdownNow)
.property(JAXRS.Configuration.PORT, 8080)
.build();
}
On some operating system port 80 can only be used by root; use explicitly 8080 there.
"startedIntance" is semantically wrong; it is the process that currently is starting, not necessarily an instance that was already started.
There is no need to give explicitly "(JAXRS.Instance instance)"; Java already knows the type.
Separate blocks is fine for me, but not necessarily better than inline code, as this is just an example that shall outline the steps to perform.
"startedIntance" is semantically wrong;
Than how is the flow ?
-> stage completes (instance started) -> callback called with (JAXRS.Instance instance))
And the first completed stage joins the main thread ? Or what is the purpose of 'toCompletableFuture().join()' ?
There is no need to give explicitly "(JAXRS.Instance instance)"; Java already knows the type.
I know that, but I like examples to be more explicit. But I can remove it...
Separate blocks is fine for me, but not necessarily better than inline code, as this is just an example that shall outline the steps to perform.
Just judging from the discussion regarding 'startedIntance' it may at least help to understand the concepts more clearly ;-)
BTW: I think this one is wrong;
default Builder port(String port) {
return property(PORT, port);
}
Shouldn't that be an Integer? At least I get : java.lang.String cannot be cast to java.lang.Integer when using the builder.
@mkarg I'm OK with keep stop async, gives it a nice symmetry even if not as useful IMO.
@mkarg Newer versions of example are much nicer. I still find System.in.read() unrealistic; process should stop on a signal.
@RogerGL See https://github.com/mkarg/jersey/tree/wip-poc-javase-bootstrap. Using this branch you can run your examples. At least the following works for me using that Jersey patch: