Add SVM metadata and minimal substitutions to build graalvm native image applications. (#8963)
Motivation: GraalVM native images are a new way to deliver java applications. Netty is one of the most popular libraries however there are a few limitations that make it impossible to use with native images out of the box. Adding a few metadata (in specific modules will allow the compilation to success and produce working binaries) Modification: Added properties files in `META-INF` and substitutions classes (under `internal.svm`) will solve the compilation issues. The substitutions classes are not visible and do not have a public constructor so they are not visible to end users. Result: Fixes #8959 This fix is very conservative as it applies the minimum config required to build: * pure netty servers * vert.x applications * grpc applications The build is having trouble due to checkstyle which does not seem to be able to find the copyright notice on property files.
This commit is contained in:
parent
fb6f8f513a
commit
f1495e1945
@ -0,0 +1,15 @@
|
|||||||
|
# Copyright 2019 The Netty Project
|
||||||
|
#
|
||||||
|
# The Netty Project licenses this file to you under the Apache License,
|
||||||
|
# version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
# with the License. You may obtain a copy of the License at:
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
Args = --delay-class-initialization-to-runtime=io.netty.handler.codec.http.HttpObjectEncoder,io.netty.handler.codec.http.websocketx.WebSocket00FrameEncoder
|
@ -0,0 +1,16 @@
|
|||||||
|
# Copyright 2019 The Netty Project
|
||||||
|
#
|
||||||
|
# The Netty Project licenses this file to you under the Apache License,
|
||||||
|
# version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
# with the License. You may obtain a copy of the License at:
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
Args = --rerun-class-initialization-at-runtime=io.netty.handler.codec.http2.Http2CodecUtil \
|
||||||
|
--delay-class-initialization-to-runtime=io.netty.handler.codec.http2.DefaultHttp2FrameWriter
|
@ -38,6 +38,13 @@
|
|||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.oracle.substratevm</groupId>
|
||||||
|
<artifactId>svm</artifactId>
|
||||||
|
<version>${graalvm.version}</version>
|
||||||
|
<!-- Provided scope as it is only needed for compiling the SVM substitution classes -->
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.jctools</groupId>
|
<groupId>org.jctools</groupId>
|
||||||
<artifactId>jctools-core</artifactId>
|
<artifactId>jctools-core</artifactId>
|
||||||
|
@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 The Netty Project
|
||||||
|
*
|
||||||
|
* The Netty Project licenses this file to you under the Apache License,
|
||||||
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package io.netty.util.internal.svm;
|
||||||
|
|
||||||
|
import com.oracle.svm.core.annotate.Alias;
|
||||||
|
import com.oracle.svm.core.annotate.RecomputeFieldValue;
|
||||||
|
import com.oracle.svm.core.annotate.TargetClass;
|
||||||
|
|
||||||
|
@TargetClass(className = "io.netty.util.internal.CleanerJava6")
|
||||||
|
final class CleanerJava6Substitution {
|
||||||
|
private CleanerJava6Substitution() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Alias
|
||||||
|
@RecomputeFieldValue(
|
||||||
|
kind = RecomputeFieldValue.Kind.FieldOffset,
|
||||||
|
declClassName = "java.nio.DirectByteBuffer",
|
||||||
|
name = "cleaner")
|
||||||
|
private static long CLEANER_FIELD_OFFSET;
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 The Netty Project
|
||||||
|
*
|
||||||
|
* The Netty Project licenses this file to you under the Apache License,
|
||||||
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package io.netty.util.internal.svm;
|
||||||
|
|
||||||
|
import com.oracle.svm.core.annotate.Alias;
|
||||||
|
import com.oracle.svm.core.annotate.RecomputeFieldValue;
|
||||||
|
import com.oracle.svm.core.annotate.TargetClass;
|
||||||
|
|
||||||
|
@TargetClass(className = "io.netty.util.internal.PlatformDependent0")
|
||||||
|
final class PlatformDependent0Substitution {
|
||||||
|
private PlatformDependent0Substitution() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Alias
|
||||||
|
@RecomputeFieldValue(
|
||||||
|
kind = RecomputeFieldValue.Kind.FieldOffset,
|
||||||
|
declClassName = "java.nio.Buffer",
|
||||||
|
name = "address")
|
||||||
|
private static long ADDRESS_FIELD_OFFSET;
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 The Netty Project
|
||||||
|
*
|
||||||
|
* The Netty Project licenses this file to you under the Apache License,
|
||||||
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package io.netty.util.internal.svm;
|
||||||
|
|
||||||
|
import com.oracle.svm.core.annotate.Alias;
|
||||||
|
import com.oracle.svm.core.annotate.RecomputeFieldValue;
|
||||||
|
import com.oracle.svm.core.annotate.TargetClass;
|
||||||
|
|
||||||
|
@TargetClass(className = "io.netty.util.internal.PlatformDependent")
|
||||||
|
final class PlatformDependentSubstitution {
|
||||||
|
private PlatformDependentSubstitution() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The class PlatformDependent caches the byte array base offset by reading the
|
||||||
|
* field from PlatformDependent0. The automatic recomputation of Substrate VM
|
||||||
|
* correctly recomputes the field in PlatformDependent0, but since the caching
|
||||||
|
* in PlatformDependent happens during image building, the non-recomputed value
|
||||||
|
* is cached.
|
||||||
|
*/
|
||||||
|
@Alias
|
||||||
|
@RecomputeFieldValue(
|
||||||
|
kind = RecomputeFieldValue.Kind.ArrayBaseOffset,
|
||||||
|
declClass = byte[].class)
|
||||||
|
private static long BYTE_ARRAY_BASE_OFFSET;
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 The Netty Project
|
||||||
|
*
|
||||||
|
* The Netty Project licenses this file to you under the Apache License,
|
||||||
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package io.netty.util.internal.svm;
|
||||||
|
|
||||||
|
import com.oracle.svm.core.annotate.Alias;
|
||||||
|
import com.oracle.svm.core.annotate.RecomputeFieldValue;
|
||||||
|
import com.oracle.svm.core.annotate.TargetClass;
|
||||||
|
|
||||||
|
@TargetClass(className = "io.netty.util.internal.shaded.org.jctools.util.UnsafeRefArrayAccess")
|
||||||
|
final class UnsafeRefArrayAccessSubstitution {
|
||||||
|
private UnsafeRefArrayAccessSubstitution() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Alias
|
||||||
|
@RecomputeFieldValue(
|
||||||
|
kind = RecomputeFieldValue.Kind.ArrayIndexShift,
|
||||||
|
declClass = Object[].class)
|
||||||
|
public static int REF_ELEMENT_SHIFT;
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 The Netty Project
|
||||||
|
*
|
||||||
|
* The Netty Project licenses this file to you under the Apache License,
|
||||||
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SVM substitutions for classes that will cause trouble while compiling
|
||||||
|
* into native image.
|
||||||
|
*/
|
||||||
|
package io.netty.util.internal.svm;
|
17
pom.xml
17
pom.xml
@ -68,6 +68,19 @@
|
|||||||
</developers>
|
</developers>
|
||||||
|
|
||||||
<profiles>
|
<profiles>
|
||||||
|
<!-- Detect if we use GraalVM and if so enable the native image testsuite -->
|
||||||
|
<profile>
|
||||||
|
<id>graal</id>
|
||||||
|
<activation>
|
||||||
|
<file>
|
||||||
|
<!-- GraalVM Component Updater should exists when using GraalVM-->
|
||||||
|
<exists>${java.home}/bin/native-image</exists>
|
||||||
|
</file>
|
||||||
|
</activation>
|
||||||
|
<properties>
|
||||||
|
<skipNativeImageTestsuite>false</skipNativeImageTestsuite>
|
||||||
|
</properties>
|
||||||
|
</profile>
|
||||||
<!-- JDK13 -->
|
<!-- JDK13 -->
|
||||||
<profile>
|
<profile>
|
||||||
<id>java13</id>
|
<id>java13</id>
|
||||||
@ -299,6 +312,9 @@
|
|||||||
<skipAutobahnTestsuite>false</skipAutobahnTestsuite>
|
<skipAutobahnTestsuite>false</skipAutobahnTestsuite>
|
||||||
<skipHttp2Testsuite>false</skipHttp2Testsuite>
|
<skipHttp2Testsuite>false</skipHttp2Testsuite>
|
||||||
<skipJapicmp>false</skipJapicmp>
|
<skipJapicmp>false</skipJapicmp>
|
||||||
|
<graalvm.version>1.0.0-rc15</graalvm.version>
|
||||||
|
<!-- By default skip native testsuite as it requires a custom environment with graalvm installed -->
|
||||||
|
<skipNativeImageTestsuite>true</skipNativeImageTestsuite>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
@ -337,6 +353,7 @@
|
|||||||
<module>testsuite-http2</module>
|
<module>testsuite-http2</module>
|
||||||
<module>testsuite-osgi</module>
|
<module>testsuite-osgi</module>
|
||||||
<module>testsuite-shading</module>
|
<module>testsuite-shading</module>
|
||||||
|
<module>testsuite-native-image</module>
|
||||||
<module>microbench</module>
|
<module>microbench</module>
|
||||||
<module>bom</module>
|
<module>bom</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
122
testsuite-native-image/pom.xml
Normal file
122
testsuite-native-image/pom.xml
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
~ Copyright 2017 The Netty Project
|
||||||
|
~
|
||||||
|
~ The Netty Project licenses this file to you under the Apache License,
|
||||||
|
~ version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
~ with the License. You may obtain a copy of the License at:
|
||||||
|
~
|
||||||
|
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
~
|
||||||
|
~ Unless required by applicable law or agreed to in writing, software
|
||||||
|
~ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
~ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
~ License for the specific language governing permissions and limitations
|
||||||
|
~ under the License.
|
||||||
|
-->
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
|
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>io.netty</groupId>
|
||||||
|
<artifactId>netty-parent</artifactId>
|
||||||
|
<version>4.1.36.Final-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>netty-testsuite-native-image</artifactId>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>Netty/Testsuite/NativeImage</name>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<skipJapicmp>true</skipJapicmp>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>netty-common</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>netty-buffer</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>netty-transport</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>netty-handler</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>netty-codec-http</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<profiles>
|
||||||
|
<profile>
|
||||||
|
<id>skipTests</id>
|
||||||
|
<activation>
|
||||||
|
<property>
|
||||||
|
<name>skipTests</name>
|
||||||
|
</property>
|
||||||
|
</activation>
|
||||||
|
<properties>
|
||||||
|
<skipNativeImageTestsuite>true</skipNativeImageTestsuite>
|
||||||
|
</properties>
|
||||||
|
</profile>
|
||||||
|
</profiles>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>com.oracle.substratevm</groupId>
|
||||||
|
<artifactId>native-image-maven-plugin</artifactId>
|
||||||
|
<version>${graalvm.version}</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>native-image</goal>
|
||||||
|
</goals>
|
||||||
|
<phase>package</phase>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
<configuration>
|
||||||
|
<skip>${skipNativeImageTestsuite}</skip>
|
||||||
|
<imageName>${project.artifactId}</imageName>
|
||||||
|
<mainClass>io.netty.testsuite.svm.HttpNativeServer</mainClass>
|
||||||
|
<buildArgs>--report-unsupported-elements-at-runtime --allow-incomplete-classpath</buildArgs>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
|
<artifactId>exec-maven-plugin</artifactId>
|
||||||
|
<version>1.6.0</version>
|
||||||
|
<executions>
|
||||||
|
<!-- This will do a whitesmoke test: if the substitutions are missing the binary will fail to run -->
|
||||||
|
<!-- If the metadata is missing the build above will fail -->
|
||||||
|
<execution>
|
||||||
|
<id>verify-native-image</id>
|
||||||
|
<phase>verify</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>exec</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
<configuration>
|
||||||
|
<skip>${skipNativeImageTestsuite}</skip>
|
||||||
|
<executable>${project.build.directory}/${project.artifactId}</executable>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 The Netty Project
|
||||||
|
*
|
||||||
|
* The Netty Project licenses this file to you under the Apache License,
|
||||||
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package io.netty.testsuite.svm;
|
||||||
|
|
||||||
|
import io.netty.bootstrap.ServerBootstrap;
|
||||||
|
import io.netty.channel.Channel;
|
||||||
|
import io.netty.channel.ChannelOption;
|
||||||
|
import io.netty.channel.EventLoopGroup;
|
||||||
|
import io.netty.channel.nio.NioEventLoopGroup;
|
||||||
|
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
||||||
|
import io.netty.handler.logging.LogLevel;
|
||||||
|
import io.netty.handler.logging.LoggingHandler;
|
||||||
|
import io.netty.handler.ssl.SslContext;
|
||||||
|
import io.netty.handler.ssl.SslContextBuilder;
|
||||||
|
import io.netty.handler.ssl.util.SelfSignedCertificate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An HTTP server that sends back the content of the received HTTP request
|
||||||
|
* in a pretty plaintext form.
|
||||||
|
*/
|
||||||
|
public final class HttpNativeServer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main entry point (not instantiable)
|
||||||
|
*/
|
||||||
|
private HttpNativeServer() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
// Configure the server.
|
||||||
|
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
|
||||||
|
EventLoopGroup workerGroup = new NioEventLoopGroup();
|
||||||
|
// Control status.
|
||||||
|
boolean serverStartSucess = false;
|
||||||
|
try {
|
||||||
|
ServerBootstrap b = new ServerBootstrap();
|
||||||
|
b.option(ChannelOption.SO_BACKLOG, 1024);
|
||||||
|
b.group(bossGroup, workerGroup)
|
||||||
|
.channel(NioServerSocketChannel.class)
|
||||||
|
.handler(new LoggingHandler(LogLevel.INFO))
|
||||||
|
.childHandler(new HttpNativeServerInitializer());
|
||||||
|
|
||||||
|
Channel channel = b.bind(0).sync().channel();
|
||||||
|
System.err.println("Server started, will shutdown now.");
|
||||||
|
channel.close().sync();
|
||||||
|
serverStartSucess = true;
|
||||||
|
} finally {
|
||||||
|
bossGroup.shutdownGracefully();
|
||||||
|
workerGroup.shutdownGracefully();
|
||||||
|
}
|
||||||
|
// return the right system exit code to signal success
|
||||||
|
System.exit(serverStartSucess ? 0 : 1);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013 The Netty Project
|
||||||
|
*
|
||||||
|
* The Netty Project licenses this file to you under the Apache License,
|
||||||
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package io.netty.testsuite.svm;
|
||||||
|
|
||||||
|
import io.netty.buffer.Unpooled;
|
||||||
|
import io.netty.channel.ChannelFutureListener;
|
||||||
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
import io.netty.channel.SimpleChannelInboundHandler;
|
||||||
|
import io.netty.handler.codec.http.DefaultFullHttpResponse;
|
||||||
|
import io.netty.handler.codec.http.FullHttpResponse;
|
||||||
|
import io.netty.handler.codec.http.HttpObject;
|
||||||
|
import io.netty.handler.codec.http.HttpUtil;
|
||||||
|
import io.netty.handler.codec.http.HttpRequest;
|
||||||
|
import io.netty.util.AsciiString;
|
||||||
|
|
||||||
|
import static io.netty.handler.codec.http.HttpHeaderNames.*;
|
||||||
|
import static io.netty.handler.codec.http.HttpResponseStatus.*;
|
||||||
|
import static io.netty.handler.codec.http.HttpVersion.*;
|
||||||
|
|
||||||
|
public class HttpNativeServerHandler extends SimpleChannelInboundHandler<HttpObject> {
|
||||||
|
private static final byte[] CONTENT = { 'H', 'e', 'l', 'l', 'o', ' ', 'N', 'a', 't', 'i', 'v', 'e' };
|
||||||
|
|
||||||
|
private static final AsciiString KEEP_ALIVE = AsciiString.cached("keep-alive");
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void channelReadComplete(ChannelHandlerContext ctx) {
|
||||||
|
ctx.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void channelRead0(ChannelHandlerContext ctx, HttpObject msg) {
|
||||||
|
if (msg instanceof HttpRequest) {
|
||||||
|
HttpRequest req = (HttpRequest) msg;
|
||||||
|
|
||||||
|
boolean keepAlive = HttpUtil.isKeepAlive(req);
|
||||||
|
FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK, Unpooled.wrappedBuffer(CONTENT));
|
||||||
|
response.headers().set(CONTENT_TYPE, "text/plain");
|
||||||
|
response.headers().setInt(CONTENT_LENGTH, response.content().readableBytes());
|
||||||
|
|
||||||
|
if (!keepAlive) {
|
||||||
|
ctx.write(response).addListener(ChannelFutureListener.CLOSE);
|
||||||
|
} else {
|
||||||
|
response.headers().set(CONNECTION, KEEP_ALIVE);
|
||||||
|
ctx.write(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
|
||||||
|
cause.printStackTrace();
|
||||||
|
ctx.close();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 The Netty Project
|
||||||
|
*
|
||||||
|
* The Netty Project licenses this file to you under the Apache License,
|
||||||
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package io.netty.testsuite.svm;
|
||||||
|
|
||||||
|
import io.netty.channel.ChannelInitializer;
|
||||||
|
import io.netty.channel.ChannelPipeline;
|
||||||
|
import io.netty.channel.socket.SocketChannel;
|
||||||
|
import io.netty.handler.codec.http.HttpServerCodec;
|
||||||
|
import io.netty.handler.codec.http.HttpServerExpectContinueHandler;
|
||||||
|
import io.netty.handler.ssl.SslContext;
|
||||||
|
|
||||||
|
public class HttpNativeServerInitializer extends ChannelInitializer<SocketChannel> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initChannel(SocketChannel ch) {
|
||||||
|
ChannelPipeline p = ch.pipeline();
|
||||||
|
p.addLast(new HttpServerCodec());
|
||||||
|
p.addLast(new HttpServerExpectContinueHandler());
|
||||||
|
p.addLast(new HttpNativeServerHandler());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 The Netty Project
|
||||||
|
*
|
||||||
|
* The Netty Project licenses this file to you under the Apache License,
|
||||||
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A hello world server that should be compiled to native.
|
||||||
|
*/
|
||||||
|
package io.netty.testsuite.svm;
|
@ -0,0 +1,15 @@
|
|||||||
|
# Copyright 2019 The Netty Project
|
||||||
|
#
|
||||||
|
# The Netty Project licenses this file to you under the Apache License,
|
||||||
|
# version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
# with the License. You may obtain a copy of the License at:
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
Args = -H:ReflectionConfigurationResources=${.}/reflection-config.json
|
@ -0,0 +1,8 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "io.netty.channel.socket.nio.NioServerSocketChannel",
|
||||||
|
"methods": [
|
||||||
|
{ "name": "<init>", "parameterTypes": [] }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
Loading…
Reference in New Issue
Block a user