1 package org
.argeo
.eclipse
.ui
.jetty
;
3 import java
.io
.IOException
;
4 import java
.lang
.management
.ManagementFactory
;
5 import java
.nio
.file
.Files
;
6 import java
.nio
.file
.Path
;
8 import javax
.servlet
.ServletContextEvent
;
9 import javax
.servlet
.ServletContextListener
;
11 import org
.eclipse
.jetty
.server
.Connector
;
12 import org
.eclipse
.jetty
.server
.Server
;
13 import org
.eclipse
.jetty
.server
.ServerConnector
;
14 import org
.eclipse
.jetty
.servlet
.DefaultServlet
;
15 import org
.eclipse
.jetty
.servlet
.ServletContextHandler
;
16 import org
.eclipse
.jetty
.servlet
.ServletHolder
;
17 import org
.eclipse
.jetty
.util
.resource
.Resource
;
18 import org
.eclipse
.jetty
.util
.thread
.QueuedThreadPool
;
19 import org
.eclipse
.rap
.rwt
.application
.AbstractEntryPoint
;
20 import org
.eclipse
.rap
.rwt
.application
.ApplicationRunner
;
21 import org
.eclipse
.rap
.rwt
.engine
.RWTServlet
;
22 import org
.eclipse
.swt
.SWT
;
23 import org
.eclipse
.swt
.widgets
.Composite
;
24 import org
.eclipse
.swt
.widgets
.Control
;
25 import org
.eclipse
.swt
.widgets
.Label
;
27 /** A minimal RWT runner based on embedded Jetty. */
28 public class RwtRunner
{
30 private final Server server
;
31 private final ServerConnector serverConnector
;
35 server
= new Server(new QueuedThreadPool(10, 1));
36 serverConnector
= new ServerConnector(server
);
37 serverConnector
.setPort(0);
38 server
.setConnectors(new Connector
[] { serverConnector
});
41 protected Control
createUi(Composite parent
, Object context
) {
42 return new Label(parent
, SWT
.NONE
);
46 ServletContextHandler context
= new ServletContextHandler(ServletContextHandler
.SESSIONS
);
47 context
.setContextPath("/");
48 server
.setHandler(context
);
50 String entryPoint
= "app";
52 // rwt-resources requires a file system
54 tempDir
= Files
.createTempDirectory("argeo-rwtRunner");
55 context
.setBaseResource(Resource
.newResource(tempDir
.resolve("www").toString()));
56 } catch (IOException e
) {
57 throw new IllegalStateException("Cannot create temporary directory", e
);
59 context
.addEventListener(new ServletContextListener() {
60 ApplicationRunner applicationRunner
;
63 public void contextInitialized(ServletContextEvent sce
) {
64 applicationRunner
= new ApplicationRunner(
65 (application
) -> application
.addEntryPoint("/" + entryPoint
, () -> new AbstractEntryPoint() {
66 private static final long serialVersionUID
= 5678385921969090733L;
69 protected void createContents(Composite parent
) {
70 createUi(parent
, null);
72 }, null), sce
.getServletContext());
73 applicationRunner
.start();
77 public void contextDestroyed(ServletContextEvent sce
) {
78 applicationRunner
.stop();
82 context
.addServlet(new ServletHolder(new RWTServlet()), "/" + entryPoint
);
84 // Required to serve rwt-resources. It is important that this is last.
85 ServletHolder holderPwd
= new ServletHolder("default", DefaultServlet
.class);
86 context
.addServlet(holderPwd
, "/");
90 } catch (Exception e
) {
91 throw new IllegalStateException("Cannot start Jetty server", e
);
95 public void destroy() {
97 serverConnector
.close();
99 // TODO delete temp dir
100 } catch (Exception e
) {
105 public Integer
getEffectivePort() {
106 return serverConnector
.getLocalPort();
109 public void waitFor() throws InterruptedException
{
113 public static void main(String
[] args
) throws Exception
{
114 RwtRunner rwtRunner
= new RwtRunner() {
117 protected Control
createUi(Composite parent
, Object context
) {
118 Label label
= new Label(parent
, SWT
.NONE
);
119 label
.setText("Hello world!");
124 Runtime
.getRuntime().addShutdownHook(new Thread(() -> rwtRunner
.destroy(), "Jetty shutdown"));
126 long jvmUptime
= ManagementFactory
.getRuntimeMXBean().getUptime();
127 System
.out
.println("App available in " + jvmUptime
+ " ms, on port " + rwtRunner
.getEffectivePort());
129 // open browser in app mode
130 Thread
.sleep(2000);// wait for RWT to be ready
131 Runtime
.getRuntime().exec("google-chrome --app=http://localhost:" + rwtRunner
.getEffectivePort() + "/app");