Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: Update to Jetty 12 #6037

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def testRuntimeVersion = Integer.parseInt((String)project.findProperty('testRunt
def testRuntimeVendor = project.hasProperty('testRuntimeVendor') ? JvmVendorSpec.matching((String)project.property('testRuntimeVendor')): null

if (languageLevel > compilerVersion) {
throw new IllegalArgumentException("languageLevel must be less than or equal to compileVersion")
throw new IllegalArgumentException("languageLevel must be less than or equal to compilerVersion")
}
if (languageLevel < 8) {
throw new IllegalArgumentException("languageLevel must be greater than or equal to 8")
Expand Down
24 changes: 18 additions & 6 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ javax-inject = "1"
javax-validation = "1.0.0.GA"
jdom2 = "2.0.6.1"
jetbrains = "24.1.0"
jetty = "11.0.20"
jetty = "12.0.13"
jetty11 = "11.0.20"
jpy = "0.18.0"
jsinterop = "2.0.2"
# google is annoying, and have different versions released for the same groupId
Expand Down Expand Up @@ -224,14 +225,25 @@ jdom2 = { module = "org.jdom:jdom2", version.ref = "jdom2" }

jetbrains-annotations = { module = "org.jetbrains:annotations", version.ref = "jetbrains" }


jetty-alpn-java-server = { module = "org.eclipse.jetty:jetty-alpn-java-server" }
jetty-alpn-server = { module = "org.eclipse.jetty:jetty-alpn-server" }
jetty-bom = { module = "org.eclipse.jetty:jetty-bom", version.ref = "jetty" }
jetty-http2-server = { module = "org.eclipse.jetty.http2:http2-server" }
jetty-servlet = { module = "org.eclipse.jetty:jetty-servlet" }
jetty-servlets = { module = "org.eclipse.jetty:jetty-servlets" }
jetty-webapp = { module = "org.eclipse.jetty:jetty-webapp" }
jetty-websocket-jakarta-server = { module = "org.eclipse.jetty.websocket:websocket-jakarta-server" }
jetty-http2-server = { module = "org.eclipse.jetty.http2:jetty-http2-server" }
jetty-ee10-bom = { module = "org.eclipse.jetty.ee10:jetty-ee10-bom", version.ref = "jetty" }
jetty-webapp = { module = "org.eclipse.jetty.ee10:jetty-ee10-webapp" }
jetty-servlet = { module = "org.eclipse.jetty.ee10:jetty-ee10-servlet" }
jetty-servlets = { module = "org.eclipse.jetty.ee10:jetty-ee10-servlets" }
jetty-websocket-jakarta-server = { module = "org.eclipse.jetty.ee10.websocket:jetty-ee10-websocket-jakarta-server" }

jetty11-alpn-java-server = { module = "org.eclipse.jetty:jetty-alpn-java-server" }
jetty11-alpn-server = { module = "org.eclipse.jetty:jetty-alpn-server" }
jetty11-bom = { module = "org.eclipse.jetty:jetty-bom", version.ref = "jetty11" }
jetty11-http2-server = { module = "org.eclipse.jetty.http2:http2-server" }
jetty11-servlet = { module = "org.eclipse.jetty:jetty-servlet" }
jetty11-servlets = { module = "org.eclipse.jetty:jetty-servlets" }
jetty11-webapp = { module = "org.eclipse.jetty:jetty-webapp" }
jetty11-websocket-jakarta-server = { module = "org.eclipse.jetty.websocket:websocket-jakarta-server" }

jpy = { module = "org.jpyconsortium:jpy", version.ref = "jpy" }

Expand Down
5 changes: 5 additions & 0 deletions py/embedded-server/java-runtime/gradle.properties
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
io.deephaven.project.ProjectType=JAVA_LOCAL
compilerVersion=17
runtimeVersion=17
languageLevel=17
testRuntimeVersion=17
testLanguageLevel=17
58 changes: 58 additions & 0 deletions server/jetty-11/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
plugins {
id 'java-library'
id 'io.deephaven.project.register'
}

dependencies {
api project(':authentication')
api project(':authorization')
api project(':server')
api(project(':Integrations')) {
because 'downstream dagger compile'
}
runtimeOnly(project(':web'))

implementation libs.dagger
annotationProcessor libs.dagger.compiler

testImplementation libs.dagger
testAnnotationProcessor libs.dagger.compiler

implementation platform(libs.grpc.bom)
implementation platform(libs.jetty11.bom)

api libs.jakarata.servlet.api
implementation libs.jetty11.servlet
implementation libs.jetty11.servlets
implementation libs.jetty11.webapp
implementation libs.jetty11.http2.server
implementation libs.jetty11.alpn.server
// TODO(deephaven-core#2506): Support for alternative ALPN implementations
runtimeOnly libs.jetty11.alpn.java.server

// implementation 'io.grpc:grpc-servlet-jakarta'
api(project(':grpc-java:grpc-servlet-jakarta')) {
because 'downstream dagger compile'
}
implementation project(':grpc-java:grpc-servlet-websocket-jakarta')
implementation libs.jetty11.websocket.jakarta.server

compileOnly project(':util-immutables')
annotationProcessor libs.immutables.value

implementation project(':ssl-kickstart')
implementation libs.sslcontext.kickstart.jetty

implementation project(':grpc-java:grpc-mtls')

testImplementation project(':server-test-utils')
testImplementation libs.junit4
testImplementation libs.assertj

testRuntimeOnly project(':log-to-slf4j')
testRuntimeOnly libs.slf4j.simple
}

test.systemProperty "PeriodicUpdateGraph.allowUnitTestMode", false

apply plugin: 'io.deephaven.java-open-nio'
1 change: 1 addition & 0 deletions server/jetty-11/gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
io.deephaven.project.ProjectType=JAVA_PUBLIC
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//
// Copyright (c) 2016-2024 Deephaven Data Labs and Patent Pending
//
package io.deephaven.server.jetty11;

import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.util.Calendar;
import java.util.Date;

public class CacheFilter implements Filter {
public static final int YEAR_IN_SECONDS = 365 * 24 * 60 * 60;

@Override
public void doFilter(final ServletRequest request,
final ServletResponse response,
final FilterChain filterChain)
throws IOException, ServletException {
final HttpServletResponse httpResponse = (HttpServletResponse) response;

// set expiry to one year in the future
final Calendar calendar = Calendar.getInstance();
calendar.setTime(new Date());
calendar.add(Calendar.YEAR, 1);
httpResponse.setDateHeader("Expires", calendar.getTime().getTime());
// Note: immutable tells firefox to never revalidate as data will never change
httpResponse.setHeader("Cache-control", "max-age=" + YEAR_IN_SECONDS + ", public, immutable");
httpResponse.setHeader("Pragma", "");

filterChain.doFilter(request, response);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
//
// Copyright (c) 2016-2024 Deephaven Data Labs and Patent Pending
//
package io.deephaven.server.jetty11;

import dagger.Component;
import dagger.Module;
import io.deephaven.configuration.Configuration;
import io.deephaven.server.auth.CommunityAuthorizationModule;
import io.deephaven.server.runner.CommunityDefaultsModule;
import io.deephaven.server.runner.ComponentFactoryBase;

import javax.inject.Singleton;
import java.io.PrintStream;

/**
* The out-of-the-box {@link CommunityComponent} factory for the Deephaven community server.
*
* <p>
* To use this directly, a main class can be configured as follows:
*
* <pre>
* public final class MyMainClass {
* public static void main(String[] args)
* throws IOException, InterruptedException, ClassNotFoundException, TimeoutException {
* final Configuration configuration = MainHelper.init(args, MyMainClass.class);
* new CommunityComponentFactory()
* .build(configuration)
* .getServer()
* .run()
* .join();
* }
* }
* </pre>
*
* Advanced integrators should prefer to create their own component factory that extends {@link ComponentFactoryBase}.
*/
public final class CommunityComponentFactory
extends ComponentFactoryBase<CommunityComponentFactory.CommunityComponent> {

@Override
public CommunityComponent build(Configuration configuration, PrintStream out, PrintStream err) {
final JettyConfig jettyConfig = JettyConfig.buildFromConfig(configuration).build();
return DaggerCommunityComponentFactory_CommunityComponent.builder()
.withOut(out)
.withErr(err)
.withJettyConfig(jettyConfig)
.build();
}

/**
* The out-of-the-box community {@link Component}. Includes the {@link CommunityModule}.
*/
@Singleton
@Component(modules = CommunityModule.class)
public interface CommunityComponent extends JettyServerComponent {

@Component.Builder
interface Builder extends JettyServerComponent.Builder<Builder, CommunityComponent> {
}
}

/**
* The out-of-the-box community {@link Module}.
*
* @see JettyServerModule
* @see CommunityAuthorizationModule
* @see CommunityDefaultsModule
*/
@Module(includes = {
JettyServerModule.class,
JettyClientChannelFactoryModule.class,
CommunityAuthorizationModule.class,
CommunityDefaultsModule.class,
// Implementation note: when / if modules are migrated out of CommunityDefaultsModule, they will need to be
// re-added here.
})
public interface CommunityModule {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
//
// Copyright (c) 2016-2024 Deephaven Data Labs and Patent Pending
//
package io.deephaven.server.jetty11;

import org.eclipse.jetty.util.resource.Resource;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URI;
import java.nio.channels.ReadableByteChannel;

/**
* Simple wrapper around the Jetty Resource type, to grant us control over caching features. The current implementation
* only removes the last-modified value, but a future version could provide a "real" weak/strong etag.
*/
public class ControlledCacheResource extends Resource {
public static ControlledCacheResource wrap(Resource wrapped) {
if (wrapped instanceof ControlledCacheResource) {
return (ControlledCacheResource) wrapped;
}
return new ControlledCacheResource(wrapped);
}

private final Resource wrapped;

private ControlledCacheResource(Resource wrapped) {
this.wrapped = wrapped;
}

@Override
public boolean isContainedIn(Resource r) throws MalformedURLException {
return wrapped.isContainedIn(r);
}

@Override
public void close() {
wrapped.close();
}

@Override
public boolean exists() {
return wrapped.exists();
}

@Override
public boolean isDirectory() {
return wrapped.isDirectory();
}

@Override
public long lastModified() {
// Always return -1, so that we don't get the build system timestamp. In theory we could return the app startup
// time as well, so that clients that connect don't need to revalidate quite as often, but this could have other
// side effects such as in load balancing with a short-lived old build against a seconds-older new build.
return -1;
}

@Override
public long length() {
return wrapped.length();
}

@Override
public URI getURI() {
return wrapped.getURI();
}

@Override
public File getFile() throws IOException {
return wrapped.getFile();
}

@Override
public String getName() {
return wrapped.getName();
}

@Override
public InputStream getInputStream() throws IOException {
return wrapped.getInputStream();
}

@Override
public ReadableByteChannel getReadableByteChannel() throws IOException {
return wrapped.getReadableByteChannel();
}

@Override
public boolean delete() throws SecurityException {
return wrapped.delete();
}

@Override
public boolean renameTo(Resource dest) throws SecurityException {
return wrapped.renameTo(dest);
}

@Override
public String[] list() {
return wrapped.list();
}

@Override
public Resource addPath(String path) throws IOException, MalformedURLException {
// Re-wrap any instance that might be returned
return wrap(wrapped.addPath(path));
}

@Override
public String toString() {
// Jetty's CachedContentFactory.CachedHttpContent requires that toString return the underlying URL found on
// disk, or else the mime lookup from content type won't resolve anything.
return wrapped.toString();
}

@Override
public int hashCode() {
// As with toString, delegating this to the wrapped instance, just in case there is some specific, expected
// behavior
return wrapped.hashCode();
}

@Override
public boolean equals(Object obj) {
// As with toString, delegating this to the wrapped instance, just in case there is some specific, expected
// behavior
return wrapped.equals(obj);
}
}
Loading