Skip to content

Instantly share code, notes, and snippets.

@tobias
Created July 9, 2015 14:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tobias/dc9712afc126400e9cea to your computer and use it in GitHub Desktop.
Save tobias/dc9712afc126400e9cea to your computer and use it in GitHub Desktop.
@Override
public void contextInitialized(ServletContextEvent sce) {
ServletContext sc = sce.getServletContext();
WunderBoss.putOption("servlet-context-path", sc.getContextPath());
final BlockingQueue<Runnable> addServletActions = new LinkedBlockingQueue<>();
final CompletableFuture<Void> initDone = new CompletableFuture<>();
try {
WunderBoss.registerComponentProvider(Web.class, new ServletWebProvider(sc, addServletActions));
} catch (LinkageError ignored) {
// Ignore - perhaps the user isn't using our web
}
applicationRunner = new ApplicationRunner(getName(sc)) {
@Override
protected void updateClassPath() throws Exception {
super.updateClassPath();
// TODO: Is this still needed? Things seem to work with it commented out
ModuleUtils.addToModuleClasspath(Module.forClass(MSCService.class), classPathAdditions);
}
@Override
protected URL jarURL() {
String mainPath = ApplicationRunner.class.getName().replace(".", "/") + ".class";
String mainUrl = ApplicationRunner.class.getClassLoader().getResource(mainPath).toString();
String marker = ".jar";
int to = mainUrl.lastIndexOf(marker);
try {
return new URL(mainUrl.substring(0, to + marker.length()));
} catch (MalformedURLException e) {
throw new RuntimeException("Error determining jar url", e);
}
}
@Override
public void start(String[] args) {
try {
super.start(args);
initDone.complete(null);
} catch (Exception e) {
initDone.completeExceptionally(e);
}
}
};
WunderBoss.workerPool().submit(new Runnable() {
@Override
public void run() {
try {
applicationRunner.start(null);
} catch (Exception ffs) {}
}
});
String timeoutProp = System.getProperty(TIMEOUT_PROPERTY);
long totalTimeout = DEFAULT_TIMEOUT_SECONDS;
if (timeoutProp != null) {
totalTimeout = Long.parseLong(timeoutProp);
}
long timeout = totalTimeout * 1000;
while (timeout > 0 &&
!initDone.isDone()) {
Runnable action = null;
try {
action = addServletActions.poll(10, TimeUnit.MILLISECONDS);
} catch (InterruptedException ignored) {}
if (action != null) {
action.run();
} else {
timeout -= 10;
}
}
try {
initDone.get(timeout, TimeUnit.MILLISECONDS);
} catch (ExecutionException e) {
throw new RuntimeException("Application initialization failed", e.getCause());
} catch (CancellationException | InterruptedException e) {
//should never happen, but...
e.printStackTrace();
} catch (TimeoutException e) {
String message = String.format("Timed out waiting for initialization to complete after %d seconds. If you need more time, use the %s sysprop.",
totalTimeout, TIMEOUT_PROPERTY);
throw new RuntimeException(message);
}
}
@Override
public boolean registerServlet(final Servlet servlet, Map<RegisterOption, Object> opts) {
final Options<RegisterOption> options = new Options<>(opts);
final String context = options.getString(PATH);
final String servletName = options.getString(SERVLET_NAME, context);
// TODO: Take mapping instead of path for servlets?
final String mapping = context.endsWith("/") ? context + "*" : context + "/*";
final CompletableFuture<Boolean> servletFuture = new CompletableFuture<>();
this.actionQueue.add(new Runnable() {
@Override
public void run() {
try {
ServletRegistration.Dynamic servletRegistration = servletContext.addServlet(servletName, servlet);
servletRegistration.addMapping(mapping);
servletRegistration.setLoadOnStartup(1);
servletRegistration.setAsyncSupported(true);
servletRegistration.setInitParameter(ORIGINAL_CONTEXT, context);
// TODO: add this to UndertowWeb as well?
Map<String, Filter> filterMap = (Map<String, Filter>) options.get(RegisterOption.FILTER_MAP);
if (filterMap != null) {
for (Map.Entry<String, Filter> entry : filterMap.entrySet()) {
FilterRegistration.Dynamic filter = servletContext.addFilter(entry.getKey() + servletName, entry.getValue());
filter.setAsyncSupported(true);
filter.addMappingForUrlPatterns(null, false, mapping);
}
}
//TODO: return true if we actually replace a servlet at that context
servletFuture.complete(false);
} catch (Exception e) {
servletFuture.completeExceptionally(e);
}
}
});
try {
// TODO: better/configurable timeout
return servletFuture.get(10, TimeUnit.SECONDS);
} catch (InterruptedException | TimeoutException | ExecutionException e) {
log.error("Registering servlet failed:", e);
throw new RuntimeException(e instanceof ExecutionException ? e.getCause() : e);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment