Jetty Server blocks when setting handler - java

I am trying to setup a Jetty Server with Servlet Contexts and it blocks when calling server.setHandler(context). If I run the code snippet from below, which is actually following the example from http://www.eclipse.org/jetty/documentation/9.3.x/embedding-jetty.html#_embedding_servletcontexts , it only prints one "a" and then blocks.
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
Server server = new Server(8070);
log.info("a");
server.setHandler(context);
log.info("a");
context.addServlet(EventServer.class, "/response");
context.addServlet(NotificationServer.class, "/notification");
log.info("a");
context.addEventListener(new ConfigureService());
context.addEventListener(new NotificationService());
try {
server.start();
log.info("Jetty-Server Started");
server.join();
} catch (Exception e) {
log.error(ExceptionUtils.getFullStackTrace(e));
} finally {
server.destroy();
}
Any idea why it does not execute the rest of the code and blocks when setting the handler?

It turns out that you can't actually run the jetty-server and jetty-servlet while them being different versions and this will cause the block when setting the handler.

Related

two contexts one server jetty

i have two jetty embedded servers,
localhost:9001/WebApp1 and localhost:9002/WebApp2,
as you can see they're on different ports.
I'd like them to share the same port during creation of server
is it possible? (BTW they are two separate jar files as well).
so can i do something like this instead
localhost:9001/WebApp1 and localhost:9001/WebApp2
or am I stuck with producing war files then having them
contained by a tomcat/glassfish server
during creation of server i usually see this
ContextHandler context = new ContextHandler();
context.setContextPath("/WebApp1");
context.setHandler(new WebApp1());
Server server = new Server(9001);
server.setHandler(context);
server.start();
server.join();
on second app i'd like to have something that looks like this
ContextHandler context = new ContextHandler();
context.setContextPath("/WebApp2");
context.setHandler(new WebApp2());
Server server = getExistingServer(9001);
server.addHandler(context);
i see that there is such method server.getHandlers(); which returns an array of handlers how do i add new handler to the existing list, or get the existing jetty server running at port 9001
Jetty is a standard servlet container and can of course handle different contexts.
See section Embedding Contexts in Chapter 24 of the Jetty documentation.
Here is the ManyContexts example (part of Jetty docs):
public class ManyContexts
{
public static void main( String[] args ) throws Exception
{
Server server = new Server(8080);
ContextHandler context = new ContextHandler("/");
context.setContextPath("/");
context.setHandler(new HelloHandler("Root Hello"));
ContextHandler contextFR = new ContextHandler("/fr");
contextFR.setHandler(new HelloHandler("Bonjoir"));
ContextHandler contextIT = new ContextHandler("/it");
contextIT.setHandler(new HelloHandler("Bongiorno"));
ContextHandler contextV = new ContextHandler("/");
contextV.setVirtualHosts(new String[] { "127.0.0.2" });
contextV.setHandler(new HelloHandler("Virtual Hello"));
ContextHandlerCollection contexts = new ContextHandlerCollection();
contexts.setHandlers(new Handler[] { context, contextFR, contextIT, contextV });
server.setHandler(contexts);
server.start();
server.join();
}
}

How to gracefully shutdown embeded jetty

I have an application runs on an embedded jetty server. Now i want to start/stop the server as a service.
I use a script to start the server.
java $JAVA_OPTS -DREQ_JAVA_VERSION=$JAVA_VERSION -jar myjetty.jar
Main Class
Server server = new Server();
SelectChannelConnector connector = new SelectChannelConnector();
connector.setPort(PORT);
server.addConnector(connector);
HandlerCollection handlers = new HandlerCollection();
NCSARequestLog requestLog = new NCSARequestLog();
requestLog.setFilename(home + "/logs/access_" + logFileDateFormat
+ ".log");
requestLog.setFilenameDateFormat(logFileDateFormat);
requestLog.setRetainDays(10);
requestLog.setAppend(true);
requestLog.setExtended(false);
requestLog.setLogCookies(false);
requestLog.setLogTimeZone(TimeZone.getDefault().getID());
RequestLogHandler requestLogHandler = new RequestLogHandler();
requestLogHandler.setRequestLog(requestLog);
handlers.addHandler(requestLogHandler);
server.setHandler(handlers);
server.start();
server.join();
This starts the server.Stopping and/or Restarting an embedded Jetty instance via web call can be used to stop server but,
How to stop the server from the script? and what changes should i make to shout down server in the main class.
Since Jetty 7.5.x you can use org.eclipse.jetty.server.handler.ShutdownHandler in your code:
Server server = new Server(8080);
HandlerList handlers = new HandlerList();
handlers.setHandlers(new Handler[]
{ someOtherHandler, new ShutdownHandler("secret_password", false, true) });
server.setHandler(handlers);
server.start();
... which will allow you to shut down your jetty by issuing the following http POST request:
curl -X POST http://localhost:8080/shutdown?token=secret_password
You can call setStopTimeout(long timeout) to shutdown Jetty in a relatively graceful way. A statisticsHandler must be configured when calling this method.
Referencing: Jetty Server.class setStopTimeout(long)
e.g.
YourServletHandler servletHandler = new YourServletHandler();
StatisticsHandler statsHandler = new StatisticsHandler();
statsHandler.setHandler(servletHandler);
Server server = new Server(80);
server.setHandler(statsHandler);
server.setStopTimeout(3000L);
//...
server.start();
//...
server.stop();
There is no predefined solution to shut-down the Jetty server. The only ordered way to shut-down the Jetty server is to call the method stop() on the running server instance. You must implement the way how this method is called yourself.
You could achieve this (for example) by...
implementing an RMI server thread and invoke the method from a RMI client
implementing a JMX MBean and from a client call a method on that MBean
implementing a custom handler like described in the link you have posted
If you only want to find a way which does not depend on additional tools like curl, than you could solve it for example like below (it's your own code with small modifications)
public class MyJetty {
public static void main(String[] args) throws Exception {
int PORT = 9103;
String home = System.getProperty("user.home");
String logFileDateFormat = "yyyy_MM_dd";
// execute a request to http://localhost:9103/stop
// instead of `curl -v http://localhost:9103/stop`
if (args.length == 1 && "stop".equalsIgnoreCase(args[0])) {
URL url = new URL("http", "localhost", PORT, "/stop");
try (InputStream in = url.openStream()) {
int r;
while ((r = in.read()) != -1) {
System.out.write(r);
}
return;
} catch (IOException ex) {
System.err.println("stop Jetty failed: " + ex.getMessage());
}
}
Server server = new Server();
SelectChannelConnector connector = new SelectChannelConnector();
connector.setPort(PORT);
server.addConnector(connector);
HandlerCollection handlers = new HandlerCollection();
NCSARequestLog requestLog = new NCSARequestLog();
requestLog.setFilename(home + "/logs/access_" + logFileDateFormat + ".log");
requestLog.setFilenameDateFormat(logFileDateFormat);
requestLog.setRetainDays(10);
requestLog.setAppend(true);
requestLog.setExtended(false);
requestLog.setLogCookies(false);
requestLog.setLogTimeZone(TimeZone.getDefault().getID());
RequestLogHandler requestLogHandler = new RequestLogHandler();
requestLogHandler.setRequestLog(requestLog);
handlers.addHandler(requestLogHandler);
// the class YourHandler is the one from your link
handlers.addHandler(new YourHandler(server));
server.setHandler(handlers);
server.start();
server.join();
}
}
start the server with java MyJetty
stop the server with java MyJetty stop
I don't know why (or if it is a bug) but in my case I had to set shutdownAtStart argument to false to get it working. If I set it as true the Server connector never starts, so it doesn't attend external requests like http://localhost:8888/shutdown?token=secret
new ShutdownHandler("secret", false, false);

Apache Mina + SSL + Android not working

I'm developing an Android app using Apache Mina for network IO. Non-SSL connections (reading, writing) work fine, but as soon as I add an SSL filter things stop working.
I also tried pure SSL sockets and they work fine.
This is my Mina connection code (in a separate networking thread):
IoConnector connector = new NioSocketConnector();
connector.getSessionConfig().setReadBufferSize(2048);
SocketSessionConfig cfg = (SocketSessionConfig)connector.getSessionConfig();
cfg.setTcpNoDelay(true);
SslContextFactory f = new SslContextFactory();
f.setTrustManagerFactory(new BogusTrustManagerFactory());
f.setProtocol("SSL");
try {
filter = new SslFilter(f.newInstance(), true);
} catch (Exception e) {
Log.d(TAG, "Exception: ", e);
return;
}
filter.setUseClientMode(true);
connector.getFilterChain().addLast("sslFilter", filter);
connector.getFilterChain().addLast("logger", new LoggingFilter());
connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("ASCII"))));
connector.setHandler(new MinaClientHandler());
ConnectFuture future = connector.connect(new InetSocketAddress("10.0.1.9", 7072));
future.awaitUninterruptibly();
if (!future.isConnected())
{
Log.d(TAG, "not connected, return");
return;
}
IoSession session = future.getSession();
session.getConfig().setUseReadOperation(true);
session.getCloseFuture().awaitUninterruptibly();
//System.out.println(session.read().getMessage());
Log.d(TAG, "after writting");
connector.dispose();
In my IoHandlerAdapter I have the following override:
#Override
public void sessionOpened(IoSession session)
{
session.write(IoBuffer.wrap(data)); // byte array
}
Not my actual code, but it reproduces the problem.
On the server side I see that the connection is accepted an the handshake succeeds. But on the client side nothing is sent over the socket. I have tried the same code in a desktop Java application and it also works.
Also if I move the write call just after IoSession session = future.getSession(); the same thing happens.
Has anyone had similar issues? Are there known issues with Mina on Android? Am I missing some session config options?
Since normal SSL sockets work, that is a workaround, but I would rather not rewrite all my networking code.

How to Set Timeout for JAX-WS WebService Call

I'm working on a WebService Client and I want to set a Timeout for my WebService Call. I have tried different approaches but still I'm not able to achieve this. I'm using JAX-WS for code generation from WSDL. I'm using JBoss-eap-5.1 as App Server and JDK1.6.0_27. I found these diff approaches for setting timeout but none of them is working for me.
URL mbr_service_url = new URL(null,GlobalVars.MemberService_WSDL, new URLStreamHandler() {
#Override
protected URLConnection openConnection(URL url) throws IOException {
URL clone_url = new URL(url.toString());
HttpURLConnection clone_urlconnection = (HttpURLConnection) clone_url.openConnection();
// TimeOut settings
clone_urlconnection.setConnectTimeout(10000);
clone_urlconnection.setReadTimeout(10000);
return (clone_urlconnection);
}
});
MemberService service = new MemberService(mbr_service_url);
MemberPortType soap = service.getMemberPort();
ObjectFactory factory = new ObjectFactory();
MemberEligibilityWithEnrollmentSourceRequest request = factory.createMemberEligibilityWithEnrollmentSourceRequest();
request.setMemberId(GlobalVars.MemberId);
request.setEligibilityDate(value);
((BindingProvider) soap).getRequestContext().put(com.sun.xml.ws.client.BindingProviderProperties.REQUEST_TIMEOUT, 10000);
((BindingProvider) soap).getRequestContext().put(com.sun.xml.ws.client.BindingProviderProperties.CONNECT_TIMEOUT, 10000);
((BindingProvider) soap).getRequestContext().put(com.sun.xml.internal.ws.client.BindingProviderProperties.REQUEST_TIMEOUT, 10000);
((BindingProvider) soap).getRequestContext().put(com.sun.xml.internal.ws.client.BindingProviderProperties.CONNECT_TIMEOUT, 10000);
((BindingProvider) soap).getRequestContext().put(com.sun.xml.ws.developer.JAXWSProperties.REQUEST_TIMEOUT, 10000);
((BindingProvider) soap).getRequestContext().put(com.sun.xml.ws.developer.JAXWSProperties.CONNECT_TIMEOUT, 10000);
((BindingProvider) soap).getRequestContext().put(com.sun.xml.internal.ws.developer.JAXWSProperties.REQUEST_TIMEOUT, 10000);
((BindingProvider) soap).getRequestContext().put(com.sun.xml.internal.ws.developer.JAXWSProperties.CONNECT_TIMEOUT, 10000);
System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
System.setProperty("sun.net.client.defaultReadTimeout", "10000");
MemberEligibilityWithEnrollmentSourceResponse response = soap.getMemberEligibilityWithEnrollmentSource(request);
logger.log("Call to member service finished.");
For now what I have done is, I have called my webservice method from inside an executor. I know its not a good approach, but its working for me. Guys please help me to do it in a proper way.
logger.log("Parameters set for createorUpdateContact call.\nGoing in Executor Service.");
ExecutorService executorService = Executors.newSingleThreadExecutor();
executorService.execute(new Runnable() {
#Override
public void run() {
try {
response = soap.getMemberEligibilityWithEnrollmentSource(request);
} catch (MemberServiceException ex) {
logger.log("Exception in call to WebService", ex.fillInStackTrace());
}
}
});
executorService.shutdown();
try {
executorService.awaitTermination(GlobalVars.WSCallTimeOut, TimeUnit.SECONDS);
} catch (InterruptedException ex) {
logger.log("Thread Interrupted!", ex);
executorService.shutdownNow();
}
You could try these settings (they are paired to be used in pairs)
BindingProviderProperties.REQUEST_TIMEOUT
BindingProviderProperties.CONNECT_TIMEOUT
BindingProviderProperties should be from com.sun.xml.internal.WS.client
Or the strings for JBoss:
javax.xml.ws.client.connectionTimeout
javax.xml.ws.client.receiveTimeout
All properties to be put on getRequestContext() in milliseconds.
(BindingProvider)wsPort).getRequestContext().put(BindingProviderProperties.REQUEST_TIMEOUT, yourTimeoutInMillisec);
For JBoss specifically, you might want to use the property StubExt.PROPERTY_CLIENT_TIMEOUT from org.jboss.ws.core.StubExt. See this thread for details.
Like kolossus said you should use:
com.sun.xml.internal.ws.client.BindingProviderProperties
And String values are:
com.sun.xml.internal.ws.connect.timeout
com.sun.xml.internal.ws.request.timeout
Although internal packages shouldn't be used, this is the only way if you work with default JDK6. So, in this case setting receive and connect timeout should be done with:
bindingProvider.getRequestContext().put(BindingProviderProperties.REQUEST_TIMEOUT,requestTimeoutMs);
bindingProvider.getRequestContext().put(BindingProviderProperties.CONNECT_TIMEOUT,connectTimeoutMs);
But beware, constant values are different if you are using other JAXWS reference implementation, i.e. JAXWS-RT 2.1.4 BindingProviderProperties:
com.sun.xml.ws.client.BindingProviderProperties
you will have different String values for REQUEST_TIMEOUT and CONNECT_TIMEOUT:
com.sun.xml.ws.request.timeout
com.sun.xml.ws.connect.timeout
For me setting javax.xml.ws.client.connectionTimeout and javax.xml.ws.client.receiveTimeout solved the problem.
((BindingProvider)port).getRequestContext().put("javax.xml.ws.client.connectionTimeout", timeout);
((BindingProvider)port).getRequestContext().put("javax.xml.ws.client.receiveTimeout", timeout);
refer link
Setting the following options works for me. I am using the Metro JAXWS implementation.
((BindingProvider)portType).getRequestContext().put(JAXWSProperties.CONNECT_TIMEOUT, 10000);
((BindingProvider) portType).getRequestContext().put(JAXWSProperties.REQUEST_TIMEOUT, 50000);
portType is the Web Service endpoint interface.
Values of the above fields from the com.sun.xml.internal.ws.developer.JAXWSProperties
public static final java.lang.String CONNECT_TIMEOUT = "com.sun.xml.internal.ws.connect.timeout";
public static final java.lang.String REQUEST_TIMEOUT = "com.sun.xml.internal.ws.request.timeout";
Upgrade jbossws-native library and use StubExt.PROPERTY_CLIENT_TIMEOUT
For upgrading jbossws-native, follow this link.
*jbossws-native-3.4.0 is the latest supported version for Jboss 5.1.0GA. You can see JBossWS - Supported Target Containers
This worked for me
I have a old installation runtime that have this environment:
Jdk-1.5, Jboss-4.2.3.GA and the WSClient was created by JAX-WS specification 2.0.
to activate Soap Request Timeout I use the follow code
((BindingProvider)port).getRequestContext().put(org.jboss.ws.core.StubExt.PROPERTY_CLIENT_TIMEOUT, String.valueOf(readTimeout));
and the jar jbossws-client.jar copied in jboss-4.2.3.GA\server\default\lib\

Jetty server allow all cross origins

I use jetty as java lib to run my local server, that has static content. How can I configure this server to allow all cross origins?
This is the code of my server:
Server server = new Server(8087);
Context staticContext = new Context(server, "/", 0);
staticContext.setHandler(new ResourceHandler());
staticContext.setResourceBase("./static");
staticContext.setContextPath("/");
try {
server.start();
} catch (Exception e1) {
e1.printStackTrace();
}

Categories