[prev in list] [next in list] [prev in thread] [next in thread]
List: tomcat-dev
Subject: [tomcat] branch master updated: Add an experimental minimal distribution to be published
From: fhanik () apache ! org
Date: 2020-07-27 22:32:10
Message-ID: 159588913074.21965.10833711308660466648 () gitbox ! apache ! org
[Download RAW message or body]
This is an automated email from the ASF dual-hosted git repository.
fhanik pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/master by this push:
new a9eae94 Add an experimental minimal distribution to be published
a9eae94 is described below
commit a9eae944f0f906b9b5375ac25a796404a1f51095
Author: Filip Hanik <fhanik@pivotal.io>
AuthorDate: Mon Jul 27 13:35:03 2020 -0700
Add an experimental minimal distribution to be published
- For usage with optimized for size Java and GraalVM native compilation images
- Maven groupId is set to org.apache.tomcat.experimental to classify it during \
evaluation of viability
- Does not ship as part of the standard Apache Tomcat library and sources
---
build.xml | 343 +++++++++++++++-
.../org/apache/tomcat/util/IntrospectionUtils.java | 7 +
.../tomcat/util/XReflectionIntrospectionUtils.java | 33 ++
res/graal/build-tomcat-native-image.sh | 3 +-
.../ObjectReflectionPropertyInspector.java | 281 +++++++++++++
.../xreflection/ReflectionLessCodeGenerator.java | 273 +++++++++++++
.../util/xreflection/ReflectionProperty.java | 119 ++++++
.../tomcat/util/xreflection/SetPropertyClass.java | 436 +++++++++++++++++++++
.../native-image/native-image.properties | 16 +
.../native-image/tomcat-reflection.json | 2 +
.../native-image/tomcat-resource.json | 51 +++
res/maven/mvn-pub.xml | 10 +
res/maven/tomcat-embed-programmatic.pom | 35 ++
.../apache/catalina/startup/EmbeddedTomcat.java | 4 +-
14 files changed, 1609 insertions(+), 4 deletions(-)
diff --git a/build.xml b/build.xml
index cf79946..41441e4 100644
--- a/build.xml
+++ b/build.xml
@@ -157,11 +157,13 @@
<!-- Embedded JARs & source JARs -->
<property name="tomcat-embed-core.jar" \
value="${tomcat.embed}/tomcat-embed-core.jar"/> + <property \
name="tomcat-embed-programmatic.jar" \
value="${tomcat.embed}/tomcat-embed-programmatic.jar"/> <property \
name="tomcat-embed-jasper.jar" value="${tomcat.embed}/tomcat-embed-jasper.jar"/> \
<property name="tomcat-embed-el.jar" value="${tomcat.embed}/tomcat-embed-el.jar"/> \
<property name="tomcat-embed-websocket.jar" \
value="${tomcat.embed}/tomcat-embed-websocket.jar"/>
<property name="tomcat-embed-core-sources.jar" \
value="${tomcat.embed.sources}/tomcat-embed-core-src.jar"/> + <property \
name="tomcat-embed-programmatic-sources.jar" \
value="${tomcat.embed.sources}/tomcat-embed-programmatic-src.jar"/> <property \
name="tomcat-embed-jasper-sources.jar" \
value="${tomcat.embed.sources}/tomcat-embed-jasper-src.jar"/> <property \
name="tomcat-embed-el-sources.jar" \
value="${tomcat.embed.sources}/tomcat-embed-el-src.jar"/> <property \
name="tomcat-embed-websocket-sources.jar" \
value="${tomcat.embed.sources}/tomcat-embed-websocket-src.jar"/> @@ -431,6 +433,268 \
@@ <exclude name="org/apache/catalina/ssi/**" />
</patternset>
+ <patternset id="files.tomcat-embed-programmatic">
+ <patternset refid="files.jaspic-api" />
+ <patternset refid="files.tomcat-juli" />
+
+ <!-- Servlet -->
+ <include name="jakarta/servlet/**" />
+ <include name="jakarta/servlet/annotation/**" />
+ <include name="jakarta/servlet/http/**" />
+ <exclude name="jakarta/servlet/descriptor/**" />
+ <exclude name="jakarta/servlet/jsp/**"/>
+ <exclude name="jakarta/servlet/resources/**" />
+
+ <!-- AprLifecycleListener is configured by default -->
+ <include name="**/AprLifecycleListener.*"/>
+ <include name="**/AprStatus.*"/>
+
+ <!-- Remove dynamic mbean descriptors -->
+ <exclude name="**/mbeans-descriptors.xml"/>
+ <exclude name="**/mbeans-descriptors.dtd"/>
+ <!-- No JMX Support - But we can't remove the classes -->
+ <include name="org/apache/tomcat/util/modeler/LocalStrings.properties" />
+ <include name="org/apache/tomcat/util/modeler/AttributeInfo*" />
+ <include name="org/apache/tomcat/util/modeler/BaseModelMBean*" />
+ <include name="org/apache/tomcat/util/modeler/FeatureInfo*" />
+ <include name="org/apache/tomcat/util/modeler/ManagedBean*" />
+ <include name="org/apache/tomcat/util/modeler/NoDescriptorRegistry*" />
+ <include name="org/apache/tomcat/util/modeler/NotificationInfo*" />
+ <include name="org/apache/tomcat/util/modeler/Registry*" />
+ <include name="org/apache/tomcat/util/modeler/RegistryMBean*" />
+ <include name="org/apache/tomcat/util/modeler/Util*" />
+ <include name="org/apache/tomcat/util/modeler/modules/ModelerSource*" />
+
+ <!-- Apache Tomcat Core Code -->
+ <include name="org/apache/catalina/*"/>
+ <include name="org/apache/catalina/authenticator/**"/>
+ <include name="org/apache/catalina/connector/**"/>
+ <include name="org/apache/catalina/core/**"/>
+ <include name="org/apache/catalina/deploy/**"/>
+ <include name="org/apache/catalina/filters/**"/>
+ <include name="org/apache/catalina/loader/**"/>
+ <include name="org/apache/catalina/mapper/**"/>
+ <include name="org/apache/catalina/mbeans/**"/>
+ <include name="org/apache/catalina/realm/**"/>
+ <include name="org/apache/catalina/security/**"/>
+ <include name="org/apache/catalina/session/**"/>
+ <include name="org/apache/catalina/startup/**"/>
+ <include name="org/apache/catalina/util/**"/>
+ <include name="org/apache/catalina/valves/*"/>
+ <include name="org/apache/catalina/webresources/**"/>
+ <include name="org/apache/coyote/**" />
+ <include name="org/apache/naming/**" />
+ <include name="org/apache/tomcat/*" />
+ <include name="org/apache/tomcat/util/*" />
+ <include name="org/apache/tomcat/util/bcel/**" />
+ <include name="org/apache/tomcat/util/buf/**" />
+ <include name="org/apache/tomcat/util/codec/**" />
+ <include name="org/apache/tomcat/util/collections/**" />
+ <include name="org/apache/tomcat/util/compat/**" />
+ <include name="org/apache/tomcat/util/descriptor/**" />
+ <include name="org/apache/tomcat/util/file/**" />
+ <include name="org/apache/tomcat/util/http/**" />
+ <include name="org/apache/tomcat/util/json/**" />
+ <include name="org/apache/tomcat/util/log/**" />
+ <include name="org/apache/tomcat/util/net/**" />
+ <include name="org/apache/tomcat/util/res/**" />
+ <include name="org/apache/tomcat/util/security/**" />
+ <include name="org/apache/tomcat/util/threads/**" />
+
+ <!-- Some of the core code depends on the jar scanner -->
+ <include name="org/apache/tomcat/util/scan/StandardJarScan*" />
+ <include name="org/apache/tomcat/util/scan/LocalStrings.properties" />
+
+ <!-- Minimize JNI to what doesn't throw an error -->
+ <include name="org/apache/tomcat/jni/Library.class" />
+ <include name="org/apache/tomcat/jni/LibraryNotFoundError*" />
+ <exclude name="org/apache/tomcat/jni" />
+
+ <!-- Remove connectors that are not default -->
+ <exclude name="**/AbstractAjpProtocol.class"/>
+ <exclude name="**/Ajp*.class"/>
+ <exclude name="**/AjpApr*.class"/>
+ <exclude name="**/Http11Apr*.class"/>
+ <exclude name="**/Http11Nio2*.class"/>
+ <exclude name="**/JniLifecycleListener.class"/>
+ <exclude name="org/apache/tomcat/**/*Nio2*.class"/>
+ <exclude name="org/apache/tomcat/**/Apr*.class"/>
+
+ <!-- Minimize bundles to the default set -->
+ <exclude name="org/apache/**/LocalStrings_*.properties"/>
+
+ <!-- Remove digester support -->
+ <exclude name="org/apache/catalina/**/*Rule.class" />
+ <exclude name="org/apache/catalina/**/*RuleSet*.class" />
+ <exclude name="org/apache/tomcat/**/*RuleSet*.class" />
+
+ <!-- Remove various Apache Tomcat modules not used by default in an embedded \
setting --> + <exclude name="org/apache/catalina/ant/**" />
+ <exclude name="org/apache/catalina/ha/**" />
+ <exclude name="org/apache/catalina/manager/**" />
+ <exclude name="org/apache/catalina/ssi/**" />
+ <exclude name="org/apache/catalina/storeconfig/**" />
+ <exclude name="org/apache/catalina/tribes/**" />
+ <exclude name="org/apache/catalina/valves/rewrite/**" />
+ <exclude name="org/apache/tomcat/buildutil" />
+ <exclude name="org/apache/tomcat/dbcp" />
+
+ <!-- Remove authenticator classes -->
+ <exclude name="org/apache/catalina/authenticator/BasicAuthenticator*" />
+ <exclude name="org/apache/catalina/authenticator/DigestAuthenticator*" />
+ <exclude name="org/apache/catalina/authenticator/FormAuthenticator*" />
+ <exclude name="org/apache/catalina/authenticator/SingleSignOnE*" />
+ <exclude name="org/apache/catalina/authenticator/SingleSignOnL*" />
+ <exclude name="org/apache/catalina/authenticator/SingleSignOnS*" />
+ <exclude name="org/apache/catalina/authenticator/Spnego*" />
+ <exclude name="org/apache/catalina/authenticator/SSLAuthenticator*" />
+ <exclude name="org/apache/catalina/authenticator/jaspcic/Simple*" />
+
+ <!-- Remove optional filter classes -->
+ <exclude name="org/apache/catalina/filters/**" />
+
+ <!-- Remove Realm classes -->
+ <exclude name="org/apache/catalina/realm/AuthenticatedUserRealm.class" />
+ <exclude name="org/apache/catalina/realm/CombinedRealm.class" />
+ <exclude name="org/apache/catalina/realm/DataSourceRealm.class" />
+ <exclude name="org/apache/catalina/realm/JAASCallbackHandler.class" />
+ <exclude name="org/apache/catalina/realm/JAASMemoryLoginModule.class" />
+ <exclude name="org/apache/catalina/realm/JAASRealm.class" />
+ <exclude name="org/apache/catalina/realm/JDBCRealm.class" />
+ <exclude name="org/apache/catalina/realm/JNDIRealm$User.class" />
+ <exclude name="org/apache/catalina/realm/JNDIRealm.class" />
+ <exclude name="org/apache/catalina/realm/LockOutRealm*" />
+ <exclude name="org/apache/catalina/realm/MemoryRealm.class" />
+ <exclude name="org/apache/catalina/realm/NestedCredentialHandler.class" />
+ <exclude name="org/apache/catalina/realm/UserDatabaseRealm.class" />
+
+ <!-- Remove optional servlets -->
+ <exclude name="org/apache/catalina/servlets/**" />
+
+ <!-- Remove all but the standard session management -->
+ <exclude name="org/apache/catalina/session/JDBC*" />
+ <exclude name="org/apache/catalina/session/File*" />
+ <exclude name="org/apache/catalina/session/Persistent*" />
+ <exclude name="org/apache/catalina/session/StoreBase*" />
+
+ <!-- Remove users -->
+ <exclude name="org/apache/catalina/users/**" />
+
+ <!-- Remove optional valves -->
+ <exclude name="org/apache/catalina/valves/Crawler*" />
+ <exclude name="org/apache/catalina/valves/ExtendedAccessLogValve*" />
+ <exclude name="org/apache/catalina/valves/ExtendedAccessLogValve*" />
+ <exclude name="org/apache/catalina/valves/HealthCheckValve*" />
+ <exclude name="org/apache/catalina/valves/JDBCAccessLogValve*" />
+ <exclude name="org/apache/catalina/valves/LoadBalancerDrainingValve*" />
+ <exclude name="org/apache/catalina/valves/PersistentValve*" />
+
+ <!-- Remove web resources classes, default is the EmptyResourceSet -->
+ <exclude name="org/apache/catalina/webresources/AbstractArchiveResource*" />
+ <exclude name="org/apache/catalina/webresources/AbstractSingleArchiveResource*" \
/> + <exclude name="org/apache/catalina/webresources/ExtractingRoot*" />
+ <exclude name="org/apache/catalina/webresources/FileResource*" />
+ <exclude name="org/apache/catalina/webresources/JarResource*" />
+ <exclude name="org/apache/catalina/webresources/JarWarResource*" />
+ <exclude name="org/apache/catalina/webresources/TomcatJarInputStream*" />
+ <exclude name="org/apache/catalina/webresources/TrackedInputStream*" />
+ <exclude name="org/apache/catalina/webresources/VirtualResource*" />
+ <exclude name="org/apache/catalina/webresources/WarResource*" />
+ <exclude name="org/apache/catalina/webresources/WarResource*" />
+ <exclude name="org/apache/catalina/webresources/war/WarURLConnection*" />
+
+ <!-- Remove most JNDI stuff -->
+ <exclude name="org/apache/naming/EjbRef*" />
+ <exclude name="org/apache/naming/factory/BeanFactory*" />
+ <exclude name="org/apache/naming/factory/DataSourceLinkFactory*" />
+ <exclude name="org/apache/naming/factory/EjbFactory*" />
+ <exclude name="org/apache/naming/factory/LookupFactory*" />
+ <exclude name="org/apache/naming/factory/MailSessionFactory*" />
+ <exclude name="org/apache/naming/factory/OpenEjbFactory*" />
+ <exclude name="org/apache/naming/factory/ResourceEnvFactory*" />
+ <exclude name="org/apache/naming/factory/ResourceFactory*" />
+ <exclude name="org/apache/naming/factory/ResourceLinkFactory*" />
+ <exclude name="org/apache/naming/factory/SendMailFactory*" />
+ <exclude name="org/apache/naming/factory/TransactionFactory*" />
+ <exclude name="org/apache/naming/factory/webservices/*" />
+ <exclude name="org/apache/naming/LookupRef*" />
+ <exclude name="org/apache/naming/NameParserImpl*" />
+ <exclude name="org/apache/naming/NamingContextBindingsEnumeration*" />
+ <exclude name="org/apache/naming/NamingContext*" />
+ <exclude name="org/apache/naming/NamingContextEnumeration*" />
+ <exclude name="org/apache/naming/NamingEntry*" />
+ <exclude name="org/apache/naming/ResourceEnvRef*" />
+ <exclude name="org/apache/naming/ResourceLinkRef*" />
+ <exclude name="org/apache/naming/ResourceRef*" />
+ <exclude name="org/apache/naming/SelectorContext*" />
+ <exclude name="org/apache/naming/ServiceRef*" />
+ <exclude name="org/apache/naming/TransactionRef*" />
+
+ <!-- remove BCEL support -->
+ <exclude name="org/apache/tomcat/util/bcel/**" />
+
+ <!-- remove web descriptor elements -->
+ <exclude name="org/apache/tomcat/util/descriptor/DigesterFactory*" />
+ <exclude name="org/apache/tomcat/util/descriptor/InputSourceUtil*" />
+ <exclude name="org/apache/tomcat/util/descriptor/LocalResolver*" />
+ <exclude name="org/apache/tomcat/util/descriptor/web/AbsoluteOrderingRule*" />
+ <exclude name="org/apache/tomcat/util/descriptor/web/CallMethodMultiRule*" />
+ <exclude name="org/apache/tomcat/util/descriptor/web/CallParamMultiRule*" />
+ <exclude name="org/apache/tomcat/util/descriptor/web/ContextHandler*" />
+ <exclude name="org/apache/tomcat/util/descriptor/web/ContextResourceLink*" />
+ <exclude name="org/apache/tomcat/util/descriptor/web/ContextTransaction*" />
+ <exclude name="org/apache/tomcat/util/descriptor/web/FragmentJarScannerCallback*" \
/> + <exclude name="org/apache/tomcat/util/descriptor/web/IgnoreAnnotationsRule*" \
/> + <exclude name="org/apache/tomcat/util/descriptor/web/InjectionTarget*" />
+ <exclude name="org/apache/tomcat/util/descriptor/web/JspConfigDescriptorImpl*" \
/> + <exclude name="org/apache/tomcat/util/descriptor/web/JspPropertyGroup*" />
+ <exclude name="org/apache/tomcat/util/descriptor/web/JspPropertyGroupDescriptorImpl*" \
/> + <exclude name="org/apache/tomcat/util/descriptor/web/LifecycleCallbackRule*" \
/> + <exclude name="org/apache/tomcat/util/descriptor/web/MappedNameRule*" />
+ <exclude name="org/apache/tomcat/util/descriptor/web/MultipartDef*" />
+ <exclude name="org/apache/tomcat/util/descriptor/web/NameRule*" />
+ <exclude name="org/apache/tomcat/util/descriptor/web/RelativeOrderingRule*" />
+ <exclude name="org/apache/tomcat/util/descriptor/web/SecurityCollection*" />
+ <exclude name="org/apache/tomcat/util/descriptor/web/SecurityRoleRef*" />
+ <exclude name="org/apache/tomcat/util/descriptor/web/ServiceQnameRule*" />
+ <exclude name="org/apache/tomcat/util/descriptor/web/ServletDef*" />
+ <exclude name="org/apache/tomcat/util/descriptor/web/ServletDefCreateRule*" />
+ <exclude name="org/apache/tomcat/util/descriptor/web/SessionConfig*" />
+ <exclude name="org/apache/tomcat/util/descriptor/web/SetAuthConstraintRule*" />
+ <exclude name="org/apache/tomcat/util/descriptor/web/SetDenyUncoveredHttpMethodsRule*" \
/> + <exclude name="org/apache/tomcat/util/descriptor/web/SetDistributableRule*" \
/> + <exclude name="org/apache/tomcat/util/descriptor/web/SetJspConfig*" />
+ <exclude name="org/apache/tomcat/util/descriptor/web/SetLoginConfig*" />
+ <exclude name="org/apache/tomcat/util/descriptor/web/SetOverrideRule*" />
+ <exclude name="org/apache/tomcat/util/descriptor/web/SetPublicIdRule*" />
+ <exclude name="org/apache/tomcat/util/descriptor/web/SetSessionConfig*" />
+ <exclude name="org/apache/tomcat/util/descriptor/web/SoapHeaderRule*" />
+ <exclude name="org/apache/tomcat/util/descriptor/web/TaglibDescriptorImpl*" />
+ <exclude name="org/apache/tomcat/util/descriptor/web/TaglibLocationRule*" />
+ <exclude name="org/apache/tomcat/util/descriptor/web/VersionRule*" />
+ <exclude name="org/apache/tomcat/util/descriptor/web/WebXml*" />
+ <exclude name="org/apache/tomcat/util/descriptor/web/WebXmlParser*" />
+ <exclude name="org/apache/tomcat/util/descriptor/XmlErrorHandler*" />
+ <exclude name="org/apache/tomcat/util/descriptor/XmlIdentifiers*" />
+
+ <!-- remove taglibrary support -->
+ <exclude name="org/apache/tomcat/util/descriptor/tagplugin/**"/>
+ <exclude name="org/apache/tomcat/util/descriptor/tld/**"/>
+
+ <!-- Remove Digester Support -->
+ <exclude name="org/apache/tomcat/util/digester/**"/>
+
+ <!-- TODO - For now, remove SSL until we have an example -->
+ <exclude name="org/apache/tomcat/util/net/jsse/**"/>
+ <exclude name="org/apache/tomcat/util/net/openssl/**"/>
+
+ <!-- Remove without-reflection code generator -->
+ <exclude name="org/apache/tomcat/util/xreflection/**" />
+
+ <!-- Remove DefaultServlet -->
+ <exclude name="org/apache/catalina/servlets/DefaultServlet*.*" />
+ </patternset>
+
<patternset id="files.catalina-tribes">
<include name="org/apache/catalina/tribes/**" />
</patternset>
@@ -1445,9 +1709,86 @@
</target>
+ <target name="embed-programmatic-jar" description="Create non reflection embedded \
jar" + depends="embed-jars,embed-sources">
+
+ <!-- temporary directory to store the generated code -->
+ <tempfile property="xreflect.directory" destDir="${java.io.tmpdir}" \
prefix="apache-tomcat-xreflect-"/> + <echo>Generating Reflection Less \
Introspection to: ${xreflect.directory}</echo> + <mkdir \
dir="${xreflect.directory}"/> + <copy todir="${xreflect.directory}/sources">
+ <fileset dir="java"/>
+ <fileset dir="res/graal/java"/>
+ </copy>
+ <copy todir="${xreflect.directory}/classes">
+ <fileset dir="${tomcat.classes}"/>
+ </copy>
+
+ <!-- Compile the sources needed to generate XReflectionIntrospectionUtils -->
+ <javac includes="org/apache/tomcat/util/xreflection/*.java"
+ srcdir="${xreflect.directory}/sources"
+ destdir="${xreflect.directory}/classes"
+ debug="${compile.debug}"
+ deprecation="${compile.deprecation}"
+ source="${compile.source}"
+ target="${compile.target}"
+ encoding="ISO-8859-1"
+ includeAntRuntime="true" >
+ <compilerarg value="-XDignore.symbol.file"/>
+ <classpath refid="compile.classpath" />
+ </javac>
+
+ <!-- Generate the reflection less XReflectionIntrospectionUtils .java file -->
+ <java classname="org.apache.tomcat.util.xreflection.ObjectReflectionPropertyInspector"
+ classpath="${xreflect.directory}/classes">
+ <arg value="${xreflect.directory}/sources"/>
+ </java>
+
+ <!-- Compile the generated XReflectionIntrospectionUtils.java class -->
+ <delete file="${xreflect.directory}/classes/org/apache/tomcat/util/XReflectionIntrospectionUtils.class"/>
+ <javac includes="org/apache/tomcat/util/XReflectionIntrospectionUtils.java"
+ srcdir="${xreflect.directory}/sources"
+ destdir="${xreflect.directory}/classes"
+ debug="${compile.debug}"
+ deprecation="${compile.deprecation}"
+ source="${compile.source}"
+ target="${compile.target}"
+ encoding="ISO-8859-1"
+ includeAntRuntime="true" >
+ <compilerarg value="-XDignore.symbol.file"/>
+ <classpath refid="compile.classpath" />
+ </javac>
+
+ <!-- Create the binary JAR file -->
+ <jarIt jarfile="${tomcat-embed-programmatic.jar}"
+ filesDir="${xreflect.directory}/classes"
+ filesId="files.tomcat-embed-programmatic"
+ notice="${tomcat.manifests}/servlet-api.jar.notice"
+ license="${tomcat.manifests}/servlet-api.jar.license"
+ addOSGi="false"
+ addGraal="true"
+ graalPrefix="org.apache.tomcat.embed/tomcat-embed-programmatic"
+ graalFiles="res/graal/tomcat-embed-programmatic/native-image"
+ libs="embed/*.jar"/>
+
+ <!-- Create the source JAR file -->
+ <jarIt jarfile="${tomcat-embed-programmatic-sources.jar}"
+ filesDir="${xreflect.directory}/sources"
+ filesId="files.tomcat-embed-programmatic"
+ notice="${tomcat.manifests}/servlet-api.jar.notice"
+ license="${tomcat.manifests}/servlet-api.jar.license"/>
+
+ <!-- Leave generated code in an easy place for review -->
+ <copy todir="${java.io.tmpdir}"
+ file="${xreflect.directory}/sources/org/apache/tomcat/util/XReflectionIntrospectionUtils.java"
+ overwrite="true"/>
+ <!-- Delete our temporary compilation directory -->
+ <delete dir="${xreflect.directory}"/>
+ </target>
+
<target name="embed"
description="Creates the experimental embedded release"
- depends="embed-jars,embed-sources" >
+ depends="embed-jars,embed-sources,embed-programmatic-jar" >
<fixcrlf srcdir="${tomcat.embed}" eol="crlf"
encoding="ISO-8859-1" fixlast="false" >
diff --git a/java/org/apache/tomcat/util/IntrospectionUtils.java \
b/java/org/apache/tomcat/util/IntrospectionUtils.java index 78ab66f..a6bc510 100644
--- a/java/org/apache/tomcat/util/IntrospectionUtils.java
+++ b/java/org/apache/tomcat/util/IntrospectionUtils.java
@@ -60,6 +60,10 @@ public final class IntrospectionUtils {
log.debug("IntrospectionUtils: setProperty(" +
o.getClass() + " " + name + "=" + value + ")");
+ if (actualMethod == null && XReflectionIntrospectionUtils.isEnabled()) {
+ return XReflectionIntrospectionUtils.setPropertyInternal(o, name, value, \
invokeSetProperty); + }
+
String setter = "set" + capitalize(name);
try {
@@ -222,6 +226,9 @@ public final class IntrospectionUtils {
}
public static Object getProperty(Object o, String name) {
+ if (XReflectionIntrospectionUtils.isEnabled()) {
+ return XReflectionIntrospectionUtils.getPropertyInternal(o, name);
+ }
String getter = "get" + capitalize(name);
String isGetter = "is" + capitalize(name);
diff --git a/java/org/apache/tomcat/util/XReflectionIntrospectionUtils.java \
b/java/org/apache/tomcat/util/XReflectionIntrospectionUtils.java new file mode 100644
index 0000000..88de048
--- /dev/null
+++ b/java/org/apache/tomcat/util/XReflectionIntrospectionUtils.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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 org.apache.tomcat.util;
+
+final class XReflectionIntrospectionUtils {
+
+ static boolean isEnabled() {
+ return false;
+ }
+
+ static Object getPropertyInternal(Object o, String name) {
+ throw new UnsupportedOperationException();
+ }
+
+ static boolean setPropertyInternal(Object o, String name, String value, boolean \
invokeSetProperty) { + throw new UnsupportedOperationException();
+ }
+
+}
diff --git a/res/graal/build-tomcat-native-image.sh \
b/res/graal/build-tomcat-native-image.sh index cbc0db1..ec99d53 100755
--- a/res/graal/build-tomcat-native-image.sh
+++ b/res/graal/build-tomcat-native-image.sh
@@ -51,11 +51,12 @@ native-image \
--initialize-at-run-time=org.apache,jakarta.servlet \
-H:+TraceClassInitialization \
-H:+PrintClassInitialization \
+-H:+PrintAnalysisCallTree \
-H:Name=tc-graal-image \
-H:+ReportExceptionStackTraces \
--allow-incomplete-classpath \
--no-fallback \
--cp ../embed/tomcat-embed-core.jar:../embed/tomcat-embed-websocket.jar:../embed/tomcat-embed-el.jar:tomcat-embedded-sample.jar:../embed/annotations-api.jar \
\ +-cp ../embed/tomcat-embed-programmatic.jar:tomcat-embedded-sample.jar \
org.apache.catalina.startup.EmbeddedTomcat
cd $CURDIR
\ No newline at end of file
diff --git a/res/graal/java/org/apache/tomcat/util/xreflection/ObjectReflectionPropertyInspector.java \
b/res/graal/java/org/apache/tomcat/util/xreflection/ObjectReflectionPropertyInspector.java
new file mode 100644
index 0000000..5f2ebb3
--- /dev/null
+++ b/res/graal/java/org/apache/tomcat/util/xreflection/ObjectReflectionPropertyInspector.java
@@ -0,0 +1,281 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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 org.apache.tomcat.util.xreflection;
+
+
+import java.io.File;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.net.InetAddress;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import org.apache.tomcat.util.IntrospectionUtils;
+
+public final class ObjectReflectionPropertyInspector {
+
+ public static void main(String... args) throws Exception {
+ if (args.length == 0) {
+ System.err.println("Usage:\n\t"+
+ "org.apache.tomcat.util.xreflection.ObjectReflectionPropertyInspector" \
+ + " <destination directory>"
+ );
+ System.exit(1);
+ }
+
+ File outputDir = new File(args[0]);
+ if (!outputDir.exists() || !outputDir.isDirectory()) {
+ System.err.println("Invalid output directory: "+ \
outputDir.getAbsolutePath()); + System.exit(1);
+ }
+
+
+ Set<SetPropertyClass> baseClasses = getKnownClasses()
+ .stream()
+ .map(c -> processClass(c))
+ .collect(Collectors.toSet());
+ generateCode(
+ baseClasses,
+ "org.apache.tomcat.util",
+ outputDir,
+ "XReflectionIntrospectionUtils"
+ );
+ }
+
+ private static final Set<Class<?>> getKnownClasses() throws \
ClassNotFoundException { + return
+ Collections.unmodifiableSet(new HashSet<>(
+ Arrays.asList(
+ \
Class.forName("org.apache.catalina.authenticator.jaspic.SimpleAuthConfigProvider"), + \
Class.forName("org.apache.catalina.authenticator.jaspic.PersistentProviderRegistrations$Property"),
+ \
Class.forName("org.apache.catalina.authenticator.jaspic.PersistentProviderRegistrations$Provider"),
+ Class.forName("org.apache.catalina.connector.Connector"),
+ \
Class.forName("org.apache.catalina.core.AprLifecycleListener"), + \
Class.forName("org.apache.catalina.core.ContainerBase"), + \
Class.forName("org.apache.catalina.core.StandardContext"), + \
Class.forName("org.apache.catalina.core.StandardEngine"), + \
Class.forName("org.apache.catalina.core.StandardHost"), + \
Class.forName("org.apache.catalina.core.StandardServer"), + \
Class.forName("org.apache.catalina.core.StandardService"), + \
Class.forName("org.apache.catalina.filters.AddDefaultCharsetFilter"), + \
Class.forName("org.apache.catalina.filters.RestCsrfPreventionFilter"), + \
Class.forName("org.apache.catalina.loader.ParallelWebappClassLoader"), + \
Class.forName("org.apache.catalina.loader.WebappClassLoaderBase"), + \
Class.forName("org.apache.catalina.realm.UserDatabaseRealm"), + \
Class.forName("org.apache.catalina.valves.AccessLogValve"), + \
Class.forName("org.apache.coyote.AbstractProtocol"), + \
Class.forName("org.apache.coyote.ajp.AbstractAjpProtocol"), + \
Class.forName("org.apache.coyote.ajp.AjpAprProtocol"), + \
Class.forName("org.apache.coyote.ajp.AjpNio2Protocol"), + \
Class.forName("org.apache.coyote.ajp.AjpNioProtocol"), + \
Class.forName("org.apache.coyote.http11.AbstractHttp11JsseProtocol"), + \
Class.forName("org.apache.coyote.http11.AbstractHttp11Protocol"), + \
Class.forName("org.apache.coyote.http11.Http11AprProtocol"), + \
Class.forName("org.apache.coyote.http11.Http11Nio2Protocol"), + \
Class.forName("org.apache.coyote.http11.Http11NioProtocol"), + \
Class.forName("org.apache.tomcat.util.descriptor.web.ContextResource"), + \
Class.forName("org.apache.tomcat.util.descriptor.web.ResourceBase"), + \
Class.forName("org.apache.tomcat.util.modeler.AttributeInfo"), + \
Class.forName("org.apache.tomcat.util.modeler.FeatureInfo"), + \
Class.forName("org.apache.tomcat.util.modeler.ManagedBean"), + \
Class.forName("org.apache.tomcat.util.modeler.OperationInfo"), + \
Class.forName("org.apache.tomcat.util.modeler.ParameterInfo"), + \
Class.forName("org.apache.tomcat.util.net.AbstractEndpoint"), + \
Class.forName("org.apache.tomcat.util.net.AprEndpoint"), + \
Class.forName("org.apache.tomcat.util.net.Nio2Endpoint"), + \
Class.forName("org.apache.tomcat.util.net.NioEndpoint"), + \
Class.forName("org.apache.tomcat.util.net.SocketProperties") + )
+ )
+ );
+ }
+
+ //types of properties that IntrospectionUtils.setProperty supports
+ private static final Set<Class<?>> ALLOWED_TYPES = \
Collections.unmodifiableSet(new HashSet<>( + Arrays.asList(
+ Boolean.TYPE,
+ Integer.TYPE,
+ Long.TYPE,
+ String.class,
+ InetAddress.class
+ )
+ ));
+ private static Map<Class<?>, SetPropertyClass> classes = new HashMap<>();
+
+ public static void generateCode(Set<SetPropertyClass> baseClasses, String \
packageName, File location, String className) throws Exception { + String \
packageDirectory = packageName.replace('.','/'); + File sourceFileLocation = \
new File(location, packageDirectory); + \
ReflectionLessCodeGenerator.generateCode(sourceFileLocation, className, packageName, \
baseClasses); + }
+
+
+ private static boolean isAllowedField(Field field) {
+ return ALLOWED_TYPES.contains(field.getType()) && \
!Modifier.isFinal(field.getModifiers()); + }
+
+ private static boolean isAllowedSetMethod(Method method) {
+ return method.getName().startsWith("set") &&
+ method.getParameterTypes() != null &&
+ method.getParameterTypes().length == 1 &&
+ ALLOWED_TYPES.contains(method.getParameterTypes()[0]) &&
+ !Modifier.isPrivate(method.getModifiers());
+ }
+
+ private static boolean isAllowedGetMethod(Method method) {
+ return (method.getName().startsWith("get") || \
method.getName().startsWith("is")) && + (method.getParameterTypes() == \
null || + method.getParameterTypes().length == 0) &&
+ ALLOWED_TYPES.contains(method.getReturnType()) &&
+ !Modifier.isPrivate(method.getModifiers());
+ }
+
+
+ private static SetPropertyClass getOrCreateSetPropertyClass(Class<?> clazz) {
+ boolean base = (clazz.getSuperclass() == null || clazz.getSuperclass() == \
Object.class); + SetPropertyClass spc = classes.get(clazz);
+ if (spc == null) {
+ spc = new SetPropertyClass(clazz, base ? null : \
getOrCreateSetPropertyClass(clazz.getSuperclass())); + classes.put(clazz, \
spc); + }
+ return spc;
+ }
+
+ static Method findGetter(Class<?> declaringClass, String propertyName) {
+ for (String getterName : Arrays.asList("get" + \
IntrospectionUtils.capitalize(propertyName), "is" + propertyName)) { + try \
{ + Method method = declaringClass.getMethod(getterName);
+ if (!Modifier.isPrivate(method.getModifiers())) {
+ return method;
+ }
+ } catch (NoSuchMethodException e) {
+ }
+ }
+ try {
+ Method method = declaringClass.getMethod("getProperty", String.class, \
String.class); + if (!Modifier.isPrivate(method.getModifiers())) {
+ return method;
+ }
+ } catch (NoSuchMethodException e) {
+ }
+
+ return null;
+ }
+
+ static Method findSetter(Class<?> declaringClass, String propertyName, Class<?> \
propertyType) { + try {
+ Method method = declaringClass.getMethod("set" + \
IntrospectionUtils.capitalize(propertyName), propertyType); + if \
(!Modifier.isPrivate(method.getModifiers())) { + return method;
+ }
+ } catch (NoSuchMethodException e) {
+ }
+ try {
+ Method method = declaringClass.getMethod("setProperty", String.class, \
String.class); + if (!Modifier.isPrivate(method.getModifiers())) {
+ return method;
+ }
+ } catch (NoSuchMethodException e) {
+ }
+ return null;
+ }
+
+ static String decapitalize(String name) {
+ if (name == null || name.length() == 0) {
+ return name;
+ }
+ if (name.length() > 1 && Character.isUpperCase(name.charAt(1)) &&
+ Character.isUpperCase(name.charAt(0))) {
+ return name;
+ }
+ char chars[] = name.toCharArray();
+ chars[0] = Character.toLowerCase(chars[0]);
+ return new String(chars);
+ }
+
+
+ static SetPropertyClass processClass(Class<?> clazz) {
+ SetPropertyClass spc = getOrCreateSetPropertyClass(clazz);
+ final Method[] methods = clazz.getDeclaredMethods();
+ for (Method method : methods) {
+ if (isAllowedSetMethod(method)) {
+ String propertyName = decapitalize(method.getName().substring(3));
+ Class<?> propertyType = method.getParameterTypes()[0];
+ Method getter = findGetter(clazz, propertyName);
+ Method setter = findSetter(clazz, propertyName, propertyType);
+ ReflectionProperty property = new ReflectionProperty(
+ spc.getClazz().getName(),
+ propertyName,
+ propertyType,
+ setter,
+ getter
+ );
+ spc.addProperty(property);
+ } else if (isAllowedGetMethod(method)) {
+ boolean startsWithIs = method.getName().startsWith("is");
+ String propertyName = \
decapitalize(method.getName().substring(startsWithIs ? 2 : 3)); + \
Class<?> propertyType = method.getReturnType(); + Method getter = \
findGetter(clazz, propertyName); + Method setter = findSetter(clazz, \
propertyName, propertyType); + ReflectionProperty property = new \
ReflectionProperty( + spc.getClazz().getName(),
+ propertyName,
+ propertyType,
+ setter,
+ getter
+ );
+ spc.addProperty(property);
+ }
+ }
+
+ final Field[] fields = clazz.getDeclaredFields();
+ for (Field field : fields) {
+ if (isAllowedField(field)) {
+ Method getter = findGetter(
+ field.getDeclaringClass(),
+ IntrospectionUtils.capitalize(field.getName())
+ );
+ Method setter = findSetter(
+ field.getDeclaringClass(),
+ IntrospectionUtils.capitalize(field.getName()),
+ field.getType()
+ );
+ ReflectionProperty property = new ReflectionProperty(
+ spc.getClazz().getName(),
+ field.getName(),
+ field.getType(),
+ setter,
+ getter
+ );
+ spc.addProperty(property);
+ }
+ }
+
+ if (!spc.isBaseClass()) {
+ SetPropertyClass parent = \
getOrCreateSetPropertyClass(spc.getClazz().getSuperclass()); + \
parent.addSubClass(spc); + return processClass(parent.getClazz());
+ } else {
+ return spc;
+ }
+ }
+}
diff --git a/res/graal/java/org/apache/tomcat/util/xreflection/ReflectionLessCodeGenerator.java \
b/res/graal/java/org/apache/tomcat/util/xreflection/ReflectionLessCodeGenerator.java \
new file mode 100644 index 0000000..a06d78d
--- /dev/null
+++ b/res/graal/java/org/apache/tomcat/util/xreflection/ReflectionLessCodeGenerator.java
@@ -0,0 +1,273 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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 org.apache.tomcat.util.xreflection;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.Set;
+
+final class ReflectionLessCodeGenerator {
+ private static final String INDENT = " ";
+
+ static StringBuilder getIndent(int multiplier) {
+ StringBuilder indent = new StringBuilder();
+ while ((multiplier--) > 0) {
+ indent.append(INDENT);
+ }
+ return indent;
+ }
+
+ static void generateCode(
+ File directory,
+ String className,
+ String packageName,
+ Set<SetPropertyClass> baseClasses
+ ) throws IOException {
+ //begin - class
+ StringBuilder code = new StringBuilder(AL20_HEADER)
+ .append("package ")
+ .append(packageName)
+ .append(";")
+ .append(System.lineSeparator())
+ .append(System.lineSeparator())
+ .append("final class ")
+ .append(className)
+ .append(" {")
+ .append(System.lineSeparator())
+ .append(System.lineSeparator());
+
+ //begin - isEnabled method
+ code.append(getIndent(1))
+ .append("static boolean isEnabled() {")
+ .append(System.lineSeparator())
+ .append(getIndent(2))
+ .append("return true;")
+ .append(System.lineSeparator())
+ .append(getIndent(1))
+ .append("}")
+ .append(System.lineSeparator())
+ .append(System.lineSeparator())
+ ;
+ //end - isEnabled method
+
+ //begin - getInetAddress method
+ code.append(getIndent(1))
+ .append("private static java.net.InetAddress getInetAddress(String \
value) {") + .append(System.lineSeparator())
+ .append(getIndent(2))
+ .append("try {")
+ .append(System.lineSeparator())
+ .append(getIndent(3))
+ .append("return java.net.InetAddress.getByName(value);")
+ .append(System.lineSeparator())
+ .append(getIndent(2))
+ .append("} catch (java.net.UnknownHostException x) { throw new \
RuntimeException(x); }") + .append(System.lineSeparator())
+ .append(getIndent(1))
+ .append("}")
+ .append(System.lineSeparator())
+ .append(System.lineSeparator())
+ ;
+ //end - getInetAddress method
+
+ //begin - getPropertyInternal method
+ code.append(getIndent(1))
+ .append("static Object getPropertyInternal(Object ")
+ .append(SetPropertyClass.OBJECT_VAR_NAME)
+ .append(", String ")
+ .append(SetPropertyClass.NAME_VAR_NAME)
+ .append(") {")
+ .append(System.lineSeparator())
+ .append(getIndent(2))
+ .append("Class<?> checkThisClass = o.getClass();")
+ .append(System.lineSeparator())
+ .append(getIndent(2))
+ .append("Object result = null;")
+ .append(System.lineSeparator())
+ .append(getIndent(2))
+ .append("while (checkThisClass != Object.class && result == null) {")
+ .append(System.lineSeparator())
+ .append(getIndent(3))
+ .append("switch (checkThisClass.getName()) {")
+ .append(System.lineSeparator());
+
+ //generate case statements for getPropertyInternal
+ generateCaseStatementsForGetPropertyInternal(baseClasses, code);
+
+
+ code
+ .append(getIndent(3))
+ .append("}")
+ .append(System.lineSeparator())
+ .append(getIndent(3))
+ .append("checkThisClass = checkThisClass.getSuperclass();")
+ .append(System.lineSeparator())
+ .append(getIndent(2))
+ .append("}")
+ .append(System.lineSeparator())
+ .append(getIndent(2))
+ .append("return result;")
+ .append(System.lineSeparator())
+ .append(getIndent(1))
+ .append("}")
+ .append(System.lineSeparator());
+ //end - getPropertyInternal method
+
+ //begin - getPropertyForXXX methods
+ generateGetPropertyForMethods(baseClasses, code);
+ //end - getPropertyForXXX methods
+
+ //begin - setPropertyInternal method
+ code.append(getIndent(1))
+ .append("static boolean setPropertyInternal(Object ")
+ .append(SetPropertyClass.OBJECT_VAR_NAME)
+ .append(", String ")
+ .append(SetPropertyClass.NAME_VAR_NAME)
+ .append(", String ")
+ .append(SetPropertyClass.VALUE_VAR_NAME)
+ .append(", boolean ")
+ .append(SetPropertyClass.SETP_VAR_NAME)
+ .append(") {")
+ .append(System.lineSeparator())
+ .append(getIndent(2))
+ .append("Class<?> checkThisClass = o.getClass();")
+ .append(System.lineSeparator())
+ .append(getIndent(2))
+ .append("while (checkThisClass != Object.class) {")
+ .append(System.lineSeparator())
+ .append(getIndent(3))
+ .append("switch (checkThisClass.getName()) {")
+ .append(System.lineSeparator());
+
+ //generate case statements for setPropertyInternal
+ generateCaseStatementsForSetPropertyInternal(baseClasses, code);
+
+
+ code
+ .append(getIndent(3))
+ .append("}")
+ .append(System.lineSeparator())
+ .append(getIndent(3))
+ .append("checkThisClass = checkThisClass.getSuperclass();")
+ .append(System.lineSeparator())
+ .append(getIndent(2))
+ .append("}")
+ .append(System.lineSeparator())
+ .append(getIndent(2))
+ .append("return false;")
+ .append(System.lineSeparator())
+ .append(getIndent(1))
+ .append("}")
+ .append(System.lineSeparator());
+ //end - setPropertyInternal method
+
+ //begin - setPropertyForXXX methods
+ generateSetPropertyForMethods(baseClasses, code);
+ //end - setPropertyForXXX methods
+
+ code.append("}")
+ .append(System.lineSeparator());
+ //end - class
+ File destination = new File(directory, className+".java");
+ BufferedWriter writer = new BufferedWriter(new FileWriter(destination, \
false)); + writer.write(code.toString());
+ writer.flush();
+ writer.close();
+
+ }
+
+ private static void generateCaseStatementForSetPropertyInternal(SetPropertyClass \
clazz, StringBuilder code) { + for (SetPropertyClass child : \
clazz.getChildren()) { + \
generateCaseStatementForSetPropertyInternal(child, code); + }
+ if (!clazz.isAbstract()) {
+ code.append(clazz.generateInvocationSetForPropertyCaseStatement(4));
+ }
+ }
+
+ private static void \
generateCaseStatementsForSetPropertyInternal(Set<SetPropertyClass> baseClasses, \
StringBuilder code) { + for (SetPropertyClass clazz : baseClasses) {
+ generateCaseStatementForSetPropertyInternal(clazz, code);
+ }
+ }
+
+ private static void generateSetPropertyForMethod(SetPropertyClass clazz, \
StringBuilder code) { + for (SetPropertyClass child : clazz.getChildren()) {
+ generateSetPropertyForMethod(child, code);
+ }
+ code.append(clazz.generateSetPropertyForMethod())
+ .append(System.lineSeparator())
+ .append(System.lineSeparator());
+ }
+
+ private static void generateSetPropertyForMethods(Set<SetPropertyClass> \
baseClasses, StringBuilder code) { + for (SetPropertyClass clazz : \
baseClasses) { + generateSetPropertyForMethod(clazz, code);
+ }
+ }
+
+
+
+ private static void generateCaseStatementForGetPropertyInternal(SetPropertyClass \
clazz, StringBuilder code) { + for (SetPropertyClass child : \
clazz.getChildren()) { + \
generateCaseStatementForGetPropertyInternal(child, code); + }
+ if (!clazz.isAbstract()) {
+ code.append(clazz.generateInvocationGetForPropertyCaseStatement(4));
+ }
+ }
+
+ private static void \
generateCaseStatementsForGetPropertyInternal(Set<SetPropertyClass> baseClasses, \
StringBuilder code) { + for (SetPropertyClass clazz : baseClasses) {
+ generateCaseStatementForGetPropertyInternal(clazz, code);
+ }
+ }
+
+ private static void generateGetPropertyForMethod(SetPropertyClass clazz, \
StringBuilder code) { + for (SetPropertyClass child : clazz.getChildren()) {
+ generateGetPropertyForMethod(child, code);
+ }
+ code.append(clazz.generateGetPropertyForMethod())
+ .append(System.lineSeparator())
+ .append(System.lineSeparator());
+ }
+
+ private static void generateGetPropertyForMethods(Set<SetPropertyClass> \
baseClasses, StringBuilder code) { + for (SetPropertyClass clazz : \
baseClasses) { + generateGetPropertyForMethod(clazz, code);
+ }
+ }
+
+ private static final String AL20_HEADER = "/*\n" +
+ " * Licensed to the Apache Software Foundation (ASF) under one or more\n" +
+ " * contributor license agreements. See the NOTICE file distributed with\n" \
+ + " * this work for additional information regarding copyright ownership.\n" \
+ + " * The ASF licenses this file to You under the Apache License, Version \
2.0\n" + + " * (the \"License\"); you may not use this file except in \
compliance with\n" + + " * the License. You may obtain a copy of the License \
at\n" + + " *\n" +
+ " * http://www.apache.org/licenses/LICENSE-2.0\n" +
+ " *\n" +
+ " * Unless required by applicable law or agreed to in writing, software\n" +
+ " * distributed under the License is distributed on an \"AS IS\" BASIS,\n" +
+ " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or \
implied.\n" + + " * See the License for the specific language governing \
permissions and\n" + + " * limitations under the License.\n" +
+ " */\n";
+}
diff --git a/res/graal/java/org/apache/tomcat/util/xreflection/ReflectionProperty.java \
b/res/graal/java/org/apache/tomcat/util/xreflection/ReflectionProperty.java new file \
mode 100644 index 0000000..f74f7c0
--- /dev/null
+++ b/res/graal/java/org/apache/tomcat/util/xreflection/ReflectionProperty.java
@@ -0,0 +1,119 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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 org.apache.tomcat.util.xreflection;
+
+import java.lang.reflect.Method;
+import java.net.InetAddress;
+
+final class ReflectionProperty {
+ private final String clazz;
+ private final String propertyName;
+ private final Class<?> propertyType;
+ private final Method setMethod;
+ private final Method getMethod;
+
+ ReflectionProperty(String clazz, String propertyName, Class<?> propertyType, \
Method setMethod, Method getMethod) { + this.clazz = clazz;
+ this.propertyName = propertyName;
+ this.propertyType = propertyType;
+ this.setMethod = setMethod;
+ this.getMethod = getMethod;
+ }
+
+ public String getPropertyName() {
+ return propertyName;
+ }
+
+ public Class<?> getPropertyType() {
+ return propertyType;
+ }
+
+ public boolean hasSetPropertySetter() {
+ return hasSetter() && "setProperty".equals(setMethod.getName());
+ }
+
+ public boolean hasGetPropertyGetter() {
+ return hasGetter() && "getProperty".equals(getMethod.getName());
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ ReflectionProperty property1 = (ReflectionProperty) o;
+
+ if (!clazz.equals(property1.clazz)) return false;
+ return propertyName.equals(property1.propertyName);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = clazz.hashCode();
+ result = 31 * result + propertyName.hashCode();
+ return result;
+ }
+
+ public String getClazz() {
+ return clazz;
+ }
+
+ public Method getGetMethod() {
+ return getMethod;
+ }
+
+ public String getConversion(String valueVarName) {
+ if (getPropertyType() == String.class) {
+ return valueVarName;
+ }
+ if (getPropertyType() == Boolean.TYPE) {
+ return "Boolean.valueOf(" + valueVarName + ")";
+ }
+ if (getPropertyType() == Long.TYPE) {
+ return "Long.valueOf(" + valueVarName + ")";
+ }
+ if (getPropertyType() == Integer.TYPE) {
+ return "Integer.valueOf(" + valueVarName + ")";
+ }
+ if (getPropertyType() == InetAddress.class) {
+ return "getInetAddress(" + valueVarName + ")";
+ }
+ throw new IllegalStateException("Unexpected Type:" + getPropertyType());
+
+ }
+
+ public boolean hasSetter() {
+ return setMethod != null;
+ }
+
+ public boolean hasGetter() {
+ return getMethod != null;
+ }
+
+ public Method getSetMethod() {
+ return setMethod;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuffer sb = new StringBuffer("ReflectionProperty{");
+ sb.append("name='").append(propertyName).append('\'');
+ sb.append(", type=").append(propertyType);
+ sb.append('}');
+ return sb.toString();
+ }
+}
diff --git a/res/graal/java/org/apache/tomcat/util/xreflection/SetPropertyClass.java \
b/res/graal/java/org/apache/tomcat/util/xreflection/SetPropertyClass.java new file \
mode 100644 index 0000000..55a68c4
--- /dev/null
+++ b/res/graal/java/org/apache/tomcat/util/xreflection/SetPropertyClass.java
@@ -0,0 +1,436 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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 org.apache.tomcat.util.xreflection;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.tomcat.util.IntrospectionUtils;
+
+final class SetPropertyClass {
+
+ static final String OBJECT_VAR_NAME = "o";
+ static final String NAME_VAR_NAME = "name";
+ static final String VALUE_VAR_NAME = "value";
+ static final String SETP_VAR_NAME = "invokeSetProperty";
+
+ private final SetPropertyClass parent;
+ private final Class<?> clazz;
+ private Set<SetPropertyClass> children = new HashSet<>();
+ private Set<ReflectionProperty> properties = new HashSet<>();
+ private final boolean isAbstract;
+ private final Method genericSetPropertyMethod;
+ private final Method genericGetPropertyMethod;
+
+ SetPropertyClass(Class<?> clazz, SetPropertyClass parent) {
+ this.clazz = clazz;
+ this.parent = parent;
+ this.isAbstract = Modifier.isAbstract(clazz.getModifiers());
+ Method classSetter, classGetter;
+ try {
+ classSetter = clazz.getDeclaredMethod("setProperty", String.class, \
String.class); + } catch (NoSuchMethodException e) {
+ try {
+ classSetter = clazz.getDeclaredMethod("setProperty", String.class, \
Object.class); + } catch (NoSuchMethodException x) {
+ classSetter = null;
+ }
+ }
+ try {
+ classGetter = clazz.getDeclaredMethod("getProperty", String.class);
+ } catch (NoSuchMethodException e) {
+ classGetter = null;
+ }
+ genericSetPropertyMethod = classSetter;
+ genericGetPropertyMethod = classGetter;
+ }
+
+ boolean isAbstract() {
+ return isAbstract;
+ }
+
+ void addSubClass(SetPropertyClass clazz) {
+ this.children.add(clazz);
+ }
+
+ boolean isBaseClass() {
+ return parent == null;
+ }
+
+ public Set<SetPropertyClass> getChildren() {
+ return children;
+ }
+
+ public Set<ReflectionProperty> getProperties() {
+ return properties;
+ }
+
+ public Method getGenericSetPropertyMethod() {
+ return genericSetPropertyMethod;
+ }
+
+ public Method getGenericGetPropertyMethod() {
+ return genericGetPropertyMethod;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ SetPropertyClass that = (SetPropertyClass) o;
+
+ return clazz.equals(that.clazz);
+ }
+
+ @Override
+ public int hashCode() {
+ return clazz.hashCode();
+ }
+
+ public SetPropertyClass getParent() {
+ return parent;
+ }
+
+ public Class<?> getClazz() {
+ return clazz;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuffer sb = new StringBuffer("SetPropertyClass{");
+ sb.append("clazz=").append(clazz.getName());
+ sb.append('}');
+ return sb.toString();
+ }
+
+ public void addProperty(ReflectionProperty property) {
+ properties.add(property);
+ }
+
+
+
+ public String generateSetPropertyMethod(ReflectionProperty property) {
+ //this property has a setProperty method
+ if (property.hasSetPropertySetter()) {
+ return "((" + this.getClazz().getName().replace('$','.') + ")" + \
OBJECT_VAR_NAME + ")." + + property.getSetMethod().getName() + "(" + \
NAME_VAR_NAME + ", " + VALUE_VAR_NAME + ");"; + }
+
+ //direct setter
+ if (property.hasSetter()) {
+ return "((" + this.getClazz().getName().replace('$','.') + ")" + \
OBJECT_VAR_NAME + ")." + + property.getSetMethod().getName() + "(" + \
property.getConversion(VALUE_VAR_NAME) + ");"; + }
+ return null;
+ }
+
+ public String generateGetPropertyMethod(ReflectionProperty property) {
+ //this property has a getProperty method
+ if (property.hasGetPropertyGetter()) {
+ return "result = ((" + this.getClazz().getName().replace('$','.') + ")" \
+ OBJECT_VAR_NAME + ")." + + property.getGetMethod().getName() + "(" + \
NAME_VAR_NAME + ");"; + }
+
+ //direct getter
+ if (property.hasGetter()) {
+ return "result = ((" + this.getClazz().getName().replace('$','.') + ")" \
+ OBJECT_VAR_NAME + ")." + + property.getGetMethod().getName() + \
"();"; + }
+ return null;
+ }
+
+ public String generateSetPropertyForMethod() {
+ StringBuilder code = new \
StringBuilder(ReflectionLessCodeGenerator.getIndent(1)) + \
.append(generatesSetPropertyForMethodHeader()) + \
.append(System.lineSeparator()) + \
.append(ReflectionLessCodeGenerator.getIndent(2)) + .append("switch (")
+ .append(NAME_VAR_NAME)
+ .append(") {")
+ .append(System.lineSeparator());
+
+ //case statements for each property
+ for (ReflectionProperty property : getProperties()) {
+ String invocation = generateSetPropertyMethod(property);
+ if (invocation != null) {
+ code.append(ReflectionLessCodeGenerator.getIndent(3))
+ .append("case \"")
+ .append(property.getPropertyName())
+ .append("\" : ")
+ .append(System.lineSeparator());
+
+ code.append(ReflectionLessCodeGenerator.getIndent(4))
+ .append(invocation)
+ .append(System.lineSeparator())
+ .append(ReflectionLessCodeGenerator.getIndent(4))
+ .append("return true;")
+ .append(System.lineSeparator())
+ ;
+
+ } else {
+ code.append(ReflectionLessCodeGenerator.getIndent(3))
+ .append("//no set" + \
IntrospectionUtils.capitalize(property.getPropertyName())+ " method found on this \
class") + .append(System.lineSeparator())
+ ;
+ }
+ }
+
+
+
+ //end switch statement
+ code.append(ReflectionLessCodeGenerator.getIndent(2))
+ .append("}")
+ .append(System.lineSeparator());
+
+ //we have a generic setProperty(String, String) method, invoke it
+ if (getGenericSetPropertyMethod() != null) {
+ ReflectionProperty p = new ReflectionProperty(
+ clazz.getName(),
+ "property",
+ String.class,
+ getGenericSetPropertyMethod(),
+ null
+ );
+ code.append(ReflectionLessCodeGenerator.getIndent(2))
+ .append("if (")
+ .append(SETP_VAR_NAME)
+ .append(") {")
+ .append(System.lineSeparator())
+ .append(ReflectionLessCodeGenerator.getIndent(3))
+ .append(generateSetPropertyMethod(p))
+ .append(System.lineSeparator())
+ .append(ReflectionLessCodeGenerator.getIndent(3))
+ .append("return true;")
+ .append(System.lineSeparator())
+ .append(ReflectionLessCodeGenerator.getIndent(2))
+ .append("}")
+ .append(System.lineSeparator());
+ }
+
+ //invoke parent or return false
+ code.append(ReflectionLessCodeGenerator.getIndent(2))
+ .append("return ")
+ .append(getSetPropertyForExitStatement())
+ .append(System.lineSeparator())
+ .append(ReflectionLessCodeGenerator.getIndent(1))
+ .append("}");
+
+ return code.toString();
+ }
+
+ private String getSetPropertyForExitStatement() {
+
+ return (getParent() != null) ?
+ //invoke the parent if we have one
+ getParent().generateParentSetPropertyForMethodInvocation() :
+ //if we invoke setProperty, return true, return false otherwise
+ getGenericSetPropertyMethod() != null ? "true;" : "false;";
+ }
+
+ public String generateInvocationSetForPropertyCaseStatement(int level) {
+ StringBuilder code = new \
StringBuilder(ReflectionLessCodeGenerator.getIndent(level)) + \
.append("case \"") + .append(getClazz().getName())
+ .append("\" : ")
+ .append(System.lineSeparator())
+ .append(ReflectionLessCodeGenerator.getIndent(level+1))
+ .append("return ")
+ .append(generateParentSetPropertyForMethodInvocation())
+ .append(System.lineSeparator());
+ return code.toString();
+ }
+
+ public String generateParentSetPropertyForMethodInvocation() {
+ String[] classParts = clazz.getName().split("\\.|\\$");
+ StringBuilder methodInvocation = new StringBuilder("setPropertyFor");
+ for (String s : classParts) {
+ methodInvocation.append(IntrospectionUtils.capitalize(s));
+ }
+ methodInvocation.append("(")
+ .append(OBJECT_VAR_NAME)
+ .append(", ")
+ .append(NAME_VAR_NAME)
+ .append(", ")
+ .append(VALUE_VAR_NAME)
+ .append(", ")
+ .append(SETP_VAR_NAME)
+ .append(");");
+ return methodInvocation.toString();
+ }
+
+ public String generatesSetPropertyForMethodHeader() {
+ String[] classParts = clazz.getName().split("\\.|\\$");
+ StringBuilder methodInvocation = new StringBuilder("private static boolean \
setPropertyFor"); + for (String s : classParts) {
+ methodInvocation.append(IntrospectionUtils.capitalize(s));
+ }
+ methodInvocation.append("(Object ")
+ .append(OBJECT_VAR_NAME)
+ .append(", String ")
+ .append(NAME_VAR_NAME)
+ .append(", String ")
+ .append(VALUE_VAR_NAME)
+ .append(", boolean ")
+ .append(SETP_VAR_NAME)
+ .append(") {");
+ return methodInvocation.toString();
+ }
+
+ public String generateInvocationGetForPropertyCaseStatement(int level) {
+ StringBuilder code = new \
StringBuilder(ReflectionLessCodeGenerator.getIndent(level)) + \
.append("case \"") + .append(getClazz().getName())
+ .append("\" : ")
+ .append(System.lineSeparator())
+ .append(ReflectionLessCodeGenerator.getIndent(level+1))
+ .append("result = ")
+ .append(generateParentGetPropertyForMethodInvocation())
+ .append(System.lineSeparator())
+ .append(ReflectionLessCodeGenerator.getIndent(level+1))
+ .append("break;")
+ .append(System.lineSeparator())
+ ;
+ return code.toString();
+ }
+
+ public String generateParentGetPropertyForMethodInvocation() {
+ String[] classParts = clazz.getName().split("\\.|\\$");
+ StringBuilder methodInvocation = new StringBuilder("getPropertyFor");
+ for (String s : classParts) {
+ methodInvocation.append(IntrospectionUtils.capitalize(s));
+ }
+ methodInvocation.append("(")
+ .append(OBJECT_VAR_NAME)
+ .append(", ")
+ .append(NAME_VAR_NAME)
+ .append(");");
+ return methodInvocation.toString();
+ }
+
+ public String generatesGetPropertyForMethodHeader() {
+ String[] classParts = clazz.getName().split("\\.|\\$");
+ StringBuilder methodInvocation = new StringBuilder("private static Object \
getPropertyFor"); + for (String s : classParts) {
+ methodInvocation.append(IntrospectionUtils.capitalize(s));
+ }
+ methodInvocation.append("(Object ")
+ .append(OBJECT_VAR_NAME)
+ .append(", String ")
+ .append(NAME_VAR_NAME)
+ .append(") {");
+ return methodInvocation.toString();
+ }
+
+ private String getGetPropertyForExitStatement() {
+ if (getParent() != null) {
+ return getParent().generateParentGetPropertyForMethodInvocation();
+ }
+ return "null;";
+ }
+
+
+ public String generateGetPropertyForMethod() {
+ StringBuilder code = new \
StringBuilder(ReflectionLessCodeGenerator.getIndent(1)) + \
.append(generatesGetPropertyForMethodHeader()) + \
.append(System.lineSeparator()) + \
.append(ReflectionLessCodeGenerator.getIndent(2)) + .append("Object result \
= null;") + .append(System.lineSeparator())
+ .append(ReflectionLessCodeGenerator.getIndent(2))
+ .append("switch (")
+ .append(NAME_VAR_NAME)
+ .append(") {")
+ .append(System.lineSeparator());
+
+ //case statements for each property
+ for (ReflectionProperty property : getProperties()) {
+ String invocation = generateGetPropertyMethod(property);
+ if (invocation != null) {
+ code.append(ReflectionLessCodeGenerator.getIndent(3))
+ .append("case \"")
+ .append(property.getPropertyName())
+ .append("\" : ")
+ .append(System.lineSeparator());
+
+ code.append(ReflectionLessCodeGenerator.getIndent(4))
+ .append(invocation)
+ .append(System.lineSeparator())
+ .append(ReflectionLessCodeGenerator.getIndent(4))
+ .append("break;")
+ .append(System.lineSeparator())
+ ;
+
+ } else {
+ code.append(ReflectionLessCodeGenerator.getIndent(3))
+ .append("//no get" + \
IntrospectionUtils.capitalize(property.getPropertyName())+ " method found on this \
class") + .append(System.lineSeparator())
+ ;
+ }
+ }
+
+ //end switch statement
+ code.append(ReflectionLessCodeGenerator.getIndent(2))
+ .append("}")
+ .append(System.lineSeparator());
+
+ //invoke parent or return null
+ code.append(ReflectionLessCodeGenerator.getIndent(2))
+ .append("if (result == null) {")
+ .append(System.lineSeparator())
+ .append(ReflectionLessCodeGenerator.getIndent(3))
+ .append("result = ")
+ .append(getGetPropertyForExitStatement())
+ .append(System.lineSeparator())
+ .append(ReflectionLessCodeGenerator.getIndent(2))
+ .append("}")
+ .append(System.lineSeparator())
+ ;
+
+ //we have a generic getProperty(String, String) method, invoke it
+ if (getGenericGetPropertyMethod() != null) {
+ ReflectionProperty p = new ReflectionProperty(
+ clazz.getName(),
+ "property",
+ String.class,
+ null,
+ getGenericGetPropertyMethod()
+ );
+ code.append(ReflectionLessCodeGenerator.getIndent(2))
+ .append("if (result == null) {")
+ .append(System.lineSeparator())
+ .append(ReflectionLessCodeGenerator.getIndent(3))
+ .append(generateGetPropertyMethod(p))
+ .append(System.lineSeparator())
+ .append(ReflectionLessCodeGenerator.getIndent(2))
+ .append("}")
+ .append(System.lineSeparator());
+ }
+ code.append(ReflectionLessCodeGenerator.getIndent(2))
+ .append("return result;")
+ .append(System.lineSeparator())
+ .append(ReflectionLessCodeGenerator.getIndent(1))
+ .append("}")
+ .append(System.lineSeparator());
+
+
+
+ return code.toString();
+ }
+}
diff --git a/res/graal/tomcat-embed-programmatic/native-image/native-image.properties \
b/res/graal/tomcat-embed-programmatic/native-image/native-image.properties new file \
mode 100644 index 0000000..29b501f
--- /dev/null
+++ b/res/graal/tomcat-embed-programmatic/native-image/native-image.properties
@@ -0,0 +1,16 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF 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=${.}/tomcat-reflection.json \
-H:ResourceConfigurationResources=${.}/tomcat-resource.json \ No newline at end of \
file
diff --git a/res/graal/tomcat-embed-programmatic/native-image/tomcat-reflection.json \
b/res/graal/tomcat-embed-programmatic/native-image/tomcat-reflection.json new file \
mode 100644 index 0000000..0d4f101
--- /dev/null
+++ b/res/graal/tomcat-embed-programmatic/native-image/tomcat-reflection.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/res/graal/tomcat-embed-programmatic/native-image/tomcat-resource.json \
b/res/graal/tomcat-embed-programmatic/native-image/tomcat-resource.json new file mode \
100644 index 0000000..1ac95cf
--- /dev/null
+++ b/res/graal/tomcat-embed-programmatic/native-image/tomcat-resource.json
@@ -0,0 +1,51 @@
+{
+ "bundles":[
+ {"name":"jakarta.servlet.LocalStrings"},
+ {"name":"jakarta.servlet.http.LocalStrings"},
+ {"name":"org.apache.catalina.authenticator.LocalStrings"},
+ {"name":"org.apache.catalina.authenticator.jaspic.LocalStrings"},
+ {"name":"org.apache.catalina.connector.LocalStrings"},
+ {"name":"org.apache.catalina.core.LocalStrings"},
+ {"name":"org.apache.catalina.deploy.LocalStrings"},
+ {"name":"org.apache.catalina.loader.LocalStrings"},
+ {"name":"org.apache.catalina.mapper.LocalStrings"},
+ {"name":"org.apache.catalina.realm.LocalStrings"},
+ {"name":"org.apache.catalina.security.LocalStrings"},
+ {"name":"org.apache.catalina.session.LocalStrings"},
+ {"name":"org.apache.catalina.startup.LocalStrings"},
+ {"name":"org.apache.catalina.util.LocalStrings"},
+ {"name":"org.apache.catalina.valves.LocalStrings"},
+ {"name":"org.apache.catalina.webresources.LocalStrings"},
+ {"name":"org.apache.coyote.LocalStrings"},
+ {"name":"org.apache.coyote.http11.LocalStrings"},
+ {"name":"org.apache.coyote.http11.filters.LocalStrings"},
+ {"name":"org.apache.coyote.http11.upgrade.LocalStrings"},
+ {"name":"org.apache.coyote.http2.LocalStrings"},
+ {"name":"org.apache.naming.LocalStrings"},
+ {"name":"org.apache.naming.factory.LocalStrings"},
+ {"name":"org.apache.tomcat.util.LocalStrings"},
+ {"name":"org.apache.tomcat.util.buf.LocalStrings"},
+ {"name":"org.apache.tomcat.util.codec.binary.LocalStrings"},
+ {"name":"org.apache.tomcat.util.compat.LocalStrings"},
+ {"name":"org.apache.tomcat.util.http.LocalStrings"},
+ {"name":"org.apache.tomcat.util.http.parser.LocalStrings"},
+ {"name":"org.apache.tomcat.util.json.LocalStrings"},
+ {"name":"org.apache.tomcat.util.modeler.LocalStrings"},
+ {"name":"org.apache.tomcat.util.net.LocalStrings"},
+ {"name":"org.apache.tomcat.util.scan.LocalStrings"},
+ {"name":"org.apache.tomcat.util.security.LocalStrings"},
+ {"name":"org.apache.tomcat.util.threads.res.LocalStrings"}
+ ],
+ "resources":[
+ {"pattern":".*/Authenticators.properties$"},
+ {"pattern":".*/MimeTypeMappings.properties$"},
+ {"pattern":".*/catalina.properties$"},
+ {"pattern":".*/CharsetMapperDefault.properties$"},
+ {"pattern":".*/ServerInfo.properties$"},
+ {"pattern":".*/RestrictedServlets.properties$"},
+ {"pattern":".*/RestrictedListeners.properties$"},
+ {"pattern":".*/RestrictedFilters.properties$"},
+ {"pattern":".*/*.dtd$"},
+ {"pattern":".*/*.xsd$"}
+ ]
+}
diff --git a/res/maven/mvn-pub.xml b/res/maven/mvn-pub.xml
index 0f5d6d2..887578b 100644
--- a/res/maven/mvn-pub.xml
+++ b/res/maven/mvn-pub.xml
@@ -347,6 +347,11 @@
file="${tomcat.embed.path}/tomcat-embed-core.jar"
pom="tomcat-embed-core.pom"
src="${tomcat.embed.src.path}/tomcat-embed-core-src.jar"/>
+ <doMavenInstall artifactId="tomcat-embed-programmatic"
+ groupId="org.apache.tomcat.experimental"
+ file="${tomcat.embed.path}/tomcat-embed-programmatic.jar"
+ pom="tomcat-embed-programmatic.pom"
+ src="${tomcat.embed.src.path}/tomcat-embed-programmatic-src.jar"/>
<doMavenInstall artifactId="tomcat-embed-jasper"
groupId="org.apache.tomcat.embed"
file="${tomcat.embed.path}/tomcat-embed-jasper.jar"
@@ -455,6 +460,11 @@
file="${tomcat.embed.path}/tomcat-embed-core.jar"
pom="tomcat-embed-core.pom"
src="${tomcat.embed.src.path}/tomcat-embed-core-src.jar"/>
+ <doMavenDeploy artifactId="tomcat-embed-programmatic"
+ groupId="org.apache.tomcat.experimental"
+ file="${tomcat.embed.path}/tomcat-embed-programmatic.jar"
+ pom="tomcat-embed-programmatic.pom"
+ src="${tomcat.embed.src.path}/tomcat-embed-programmatic-src.jar"/>
<doMavenDeploy artifactId="tomcat-embed-jasper"
groupId="org.apache.tomcat.embed"
file="${tomcat.embed.path}/tomcat-embed-jasper.jar"
diff --git a/res/maven/tomcat-embed-programmatic.pom \
b/res/maven/tomcat-embed-programmatic.pom new file mode 100644
index 0000000..84fe088
--- /dev/null
+++ b/res/maven/tomcat-embed-programmatic.pom
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF 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/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.tomcat.experimental</groupId>
+ <artifactId>tomcat-embed-programmatic</artifactId>
+ <version>@MAVEN.DEPLOY.VERSION@</version>
+ <description>Exerimental Minimal Tomcat for Programmatic Use</description>
+ <url>https://tomcat.apache.org/</url>
+ <licenses>
+ <license>
+ <name>Apache License, Version 2.0</name>
+ <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
+ <distribution>repo</distribution>
+ </license>
+ </licenses>
+</project>
diff --git a/test/org/apache/catalina/startup/EmbeddedTomcat.java \
b/test/org/apache/catalina/startup/EmbeddedTomcat.java index 5658291..8b5c12c 100644
--- a/test/org/apache/catalina/startup/EmbeddedTomcat.java
+++ b/test/org/apache/catalina/startup/EmbeddedTomcat.java
@@ -35,7 +35,6 @@ import org.apache.catalina.connector.Connector;
import org.apache.juli.logging.LogFactory;
import org.apache.tomcat.util.scan.StandardJarScanFilter;
import org.apache.tomcat.util.scan.StandardJarScanner;
-import org.apache.tomcat.websocket.server.WsContextListener;
@Ignore
public class EmbeddedTomcat {
@@ -67,7 +66,7 @@ public class EmbeddedTomcat {
CounterServlet counterServlet = new CounterServlet();
Tomcat.addServlet(ctx, "counterServlet", counterServlet);
ctx.addServletMappingDecoded("/", "counterServlet");
- ctx.addApplicationListener(WsContextListener.class.getName());
+ //ctx.addApplicationListener(new WsContextListener());
tomcat.start();
Thread.sleep(60*1000);
@@ -88,6 +87,7 @@ public class EmbeddedTomcat {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
+ req.getSession(true);
resp.setContentType("text/plain");
resp.getWriter().print("OK: " + req.getRequestURL() + "[" + \
callCount.incrementAndGet()+ "]"); }
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic