Refactor eeX plus.security and plus.annotation classes to core (#11030)

* Refactor eeX plus.security and plus.annotation classes to core
This commit is contained in:
Jan Bartel 2023-12-13 06:34:55 +01:00 committed by GitHub
parent 006f8f75c5
commit d926380651
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
57 changed files with 136 additions and 1784 deletions

View File

@ -14,7 +14,7 @@
[[og-annotations]]
=== Annotations
Enable the `annotations` module if your webapp - or any of its third party libraries - uses any of the following:
Enable the `{ee-all}-annotations` module if your webapp - or any of its third party libraries - uses any of the following:
* Annotations:
** @Resource
@ -30,38 +30,38 @@ Enable the `annotations` module if your webapp - or any of its third party libra
** @WebInitParam
** @ServletSecurity, @HttpConstraint, @HttpMethodConstraint
** @HandlesTypes
* javax.servlet.ServletContainerInitializers
* javax.servlet.ServletContainerInitializers or jakarta.servlet.ServletContainerInitializers
* JSP
[[og-annotations-scanning]]
==== Annotation Scanning
According to more recent versions of the Servlet Specification, the web.xml file can contain the attribute `metadata-complete`.
According to more recent versions of the Jakarta Servlet Specification, the `web.xml` file can contain the attribute `metadata-complete`.
If this is set to `true`, then _no_ annotation scanning takes place, and your descriptor must contain the equivalent xml statements of any annotations.
If it is `metadata-complete=false`, or your web.xml predates the inclusion of this attribute, annotation scanning is required to take place.
If it is `metadata-complete=false`, or your `web.xml` predates the inclusion of this attribute, annotation scanning is required to take place.
To prevent annotation scanning you can use the `WebAppContext.setConfigurationDiscovered(false)` method.
Here's an example context xml file that calls this method:
Here's an example context XML file that calls this method:
[source,xml]
[source,xml,subs="verbatim,attributes"]
----
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<Configure class="org.eclipse.jetty.ee9.webapp.WebAppContext"> <!--1-->
<Configure class="org.eclipse.jetty.{ee-current}.webapp.WebAppContext"> <!--1-->
<Set name="configurationDiscovered">false</Set> <!--2-->
</Configure>
----
<1> Configures a link:{javadoc-url}/org/eclipse/jetty/webapp/WebAppContext.html[`WebAppContext`], which is the Jetty component that represents a standard Servlet web application.
<1> Configures a link:{javadoc-url}/org/eclipse/jetty/{ee-current}/webapp/WebAppContext.html[`WebAppContext`], which is the Jetty component that represents a standard Servlet web application.
<2> Specifies that scanning should not take place.
However, despite `metadata-complete=true`, scanning of classes may _still_ occur because of http://docs.oracle.com/javaee/6/api/javax/servlet/ServletContainerInitializer.html[javax.servlet.ServletContainerInitializer]s.
Classes implementing this interface are found by Jetty using the http://docs.oracle.com/javase/6/docs/api/java/util/ServiceLoader.html[javax.util.ServiceLoader] mechanism, and if one is present _and_ it includes the @HandlesTypes annotation, then Jetty must scan the class hierarchy of the web application.
However, despite `metadata-complete=true`, scanning of classes may _still_ occur because of `ServletContainerInitializer`.
Classes implementing this interface are found by Jetty using the http://docs.oracle.com/javase/6/docs/api/java/util/ServiceLoader.html[javax.util.ServiceLoader] mechanism, and if one is present _and_ it includes the `@HandlesTypes` annotation, then Jetty must scan the class hierarchy of the web application.
This may be very time-consuming if you have many jars.
We will now look at ways to limit the jars that are scanned.
Jetty can reduce the time taken by limiting the jars that are scanned.
===== The container classpath
@ -71,21 +71,21 @@ Sometimes, you may have third party libraries on the container's classpath that
In this case, use the `org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern` context attribute to define which container jars and class directories to scan.
The value of this attribute is a regular expression.
Here's an example from a context xml file that includes any jar whose name starts with "foo-" or "bar-", or a directory named "classes":
Here's an example from a context XML file that includes any jar whose name starts with `foo-` or `bar-`, or a directory named `classes`:
[source,xml]
[source,xml,subs="verbatim,attributes"]
----
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<Configure class="org.eclipse.jetty.ee9.webapp.WebAppContext"> <!--1-->
<Configure class="org.eclipse.jetty.{ee-current}.webapp.WebAppContext"> <!--1-->
<Call name="setAttribute"> <!--2-->
<Arg>org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern</Arg> <!--3-->
<Arg>.*/foo-[^/]*\.jar$|.*/bar-[^/]*\.jar$|.*/classes/.*</Arg> <!--4-->
</Call>
</Configure>
----
<1> Configures a link:{javadoc-url}/org/eclipse/jetty/webapp/WebAppContext.html[`WebAppContext`], which is the Jetty component that represents a standard Servlet web application.
<1> Configures a link:{javadoc-url}/org/eclipse/jetty/{ee-current}/webapp/WebAppContext.html[`WebAppContext`], which is the Jetty component that represents a standard Servlet web application.
<2> Specifies a context attribute.
<3> Specifies the name of the context attribute.
<4> Specifies the value of the context attribute.
@ -94,42 +94,42 @@ Note that the order of the patterns defines the ordering of the scanning of the
===== The webapp classpath
By default Jetty will scan __all__ classes from `WEB-INF/classes` and _all_ jars from `WEB-INF/lib` according to the order, if any, established by absolute or relative ordering clauses in web.xml.
By default, Jetty will scan __all__ classes from `WEB-INF/classes` and _all_ jars from `WEB-INF/lib` according to the order, if any, established by absolute or relative ordering clauses in `web.xml`.
If your webapp contains many jar files that you know do not contain any annotations, you can significantly speed up deployment by omitting them from scanning.
However, be careful if your webapp uses a `ServletContainerInitializer` with an `@HandlesTypes` annotation that you don't exclude jars that contain classes matching the annotation.
However, be careful if your webapp uses a `ServletContainerInitializer` with a `@HandlesTypes` annotation that you don't exclude jars that contain classes matching the annotation.
Use the `org.eclipse.jetty.server.webapp.WebInfIncludeJarPattern` context attribute to define a regular expression for jars and class directories to select for scanning.
Here's an example of a context xml file that sets a pattern that matches any jar on the webapp's classpath that starts with `spring-`:
Here's an example of a context XML file that sets a pattern that matches any jar on the webapp's classpath that starts with `"spring-"`:
[source,xml]
[source,xml,subs="verbatim,attributes"]
----
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<Configure class="org.eclipse.jetty.ee9.webapp.WebAppContext"> <!--1-->
<Configure class="org.eclipse.jetty.{ee-current}.webapp.WebAppContext"> <!--1-->
<Call name="setAttribute"> <!--2-->
<Arg>org.eclipse.jetty.server.webapp.WebInfIncludeJarPattern</Arg> <!--3-->
<Arg>.*/spring-[^/]*\.jar$</Arg> <!--4-->
</Call>
</Configure>
----
<1> Configures a link:{javadoc-url}/org/eclipse/jetty/webapp/WebAppContext.html[`WebAppContext`], which is the Jetty component that represents a standard Servlet web application.
<1> Configures a link:{javadoc-url}/org/eclipse/jetty/{ee-current}/webapp/WebAppContext.html[`WebAppContext`], which is the Jetty component that represents a standard Servlet web application.
<2> Specifies a context attribute.
<3> Specifies the name of the context attribute.
<4> Specifies the value of the context attribute.
===== Multi-threading
By default Jetty performs annotation scanning in a multi-threaded manner in order to complete it in the minimum amount of time.
By default, Jetty performs annotation scanning in a multi-threaded manner in order to complete it in the minimum amount of time.
If you don't want multi-threaded scanning, you can configure Jetty to revert to single-threaded scanning.
There are several options to configure this:
1. Set the context attribute `org.eclipse.jetty.annotations.multiThreaded` to `false`
2. Set the `Server` attribute `org.eclipse.jetty.annotations.multiThreaded` to `false`
3. Set the System property `org.eclipse.jetty.annotations.multiThreaded` to `false`
3. Set the `System` property `org.eclipse.jetty.annotations.multiThreaded` to `false`
Method 1 will only affect the current webapp.
Method 2 will affect all webapps deployed to the same Server instance.
@ -140,7 +140,7 @@ You can set this to a higher or lower number of seconds by doing one of the foll
1. Set the context attribute `org.eclipse.jetty.annotations.maxWait`
2. Set the `Server` attribute `org.eclipse.jetty.annotations.maxWait`
3. Set the System property `org.eclipse.jetty.annotations.maxWait`
3. Set the `System` property `org.eclipse.jetty.annotations.maxWait`
Method 1 will only affect the current webapp.
Method 2 will affect all webapps deployed to the same Server instance.
@ -149,39 +149,39 @@ Method 3 will affect all webapps deployed in the same JVM.
[[og-annotations-scis]]
==== ServletContainerInitializers
The http://docs.oracle.com/javaee/6/api/javax/servlet/ServletContainerInitializer.html[javax.servlet.ServletContainerInitializer] class can exist in: the container's classpath, the webapp's `WEB-INF/classes` directory, the webapp's `WEB-INF/lib` jars, or any external extraClasspath that you have configured on the webapp.
The `ServletContainerInitializer` class can exist in: the container's classpath, the webapp's `WEB-INF/classes` directory, the webapp's `WEB-INF/lib` jars, or any external extraClasspath that you have configured on the webapp.
The Servlet Specification does not define any order in which a `ServletContainerInitializer` must be called when the webapp starts.
By default Jetty will call them in the following order:
The Jakarta Servlet Specification does not define any order in which a `ServletContainerInitializer` must be called when the webapp starts.
By default, Jetty will call them in the following order:
1. ServletContainerInitializers from the container's classpath
2. ServletContainerInitializers from WEB-INF/classes
3. ServletContainerInitializers from WEB-INF/lib jars __in the order established in web.xml__, or in the order that the SCI is returned by the http://docs.oracle.com/javase/6/docs/api/java/util/ServiceLoader.html[javax.util.ServiceLoader] if there is _no_ ordering.
2. ServletContainerInitializers from `WEB-INF/classes`
3. ServletContainerInitializers from `WEB-INF/lib` jars __in the order established in web.xml__, or in the order that the SCI is returned by the http://docs.oracle.com/javase/6/docs/api/java/util/ServiceLoader.html[javax.util.ServiceLoader] if there is _no_ ordering.
===== Exclusions
By default, as according to the Servlet Specification, all `ServletContainerInitializer` that are discovered are invoked.
By default, as according to the Jakarta Servlet Specification, all `ServletContainerInitializer` instances that are discovered are invoked.
Sometimes, depending on your requirements, you may need to prevent some being called at all.
In this case, you can define the `org.eclipse.jetty.containerInitializerExclusionPattern` context attribute.
This is a regular expression that defines http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html[patterns] of classnames that you want to exclude.
Here's an example of setting the context attribute in a context xml file:
Here's an example of setting the context attribute in a context XML file:
[source,xml]
[source,xml,subs="verbatim,attributes"]
----
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<Configure class="org.eclipse.jetty.ee9.webapp.WebAppContext"> <!--1-->
<Configure class="org.eclipse.jetty.{ee-current}.webapp.WebAppContext"> <!--1-->
<Call name="setAttribute"> <!--2-->
<Arg>org.eclipse.jetty.containerInitializerExclusionPattern</Arg> <!--3-->
<Arg>com.acme.*|com.corp.SlowContainerInitializer</Arg> <!--4-->
</Call>
</Configure>
----
<1> Configures a link:{javadoc-url}/org/eclipse/jetty/webapp/WebAppContext.html[`WebAppContext`], which is the Jetty component that represents a standard Servlet web application.
<1> Configures a link:{javadoc-url}/org/eclipse/jetty/{ee-current}/webapp/WebAppContext.html[`WebAppContext`], which is the Jetty component that represents a standard Servlet web application.
<2> Specifies a context attribute.
<3> Specifies the name of the context attribute.
<4> Specifies the value of the context attribute.
@ -193,26 +193,26 @@ It is possible to use exclusion and ordering together to control `ServletContain
===== Ordering
If you need `ServletContainerInitializer` classes called in a specific order, you can use the context attribute `org.eclipse.jetty.containerInitializerOrder`.
Set it to a list of comma separated class names of `ServletContainerInitializers` in the order that you want them applied.
Set it to a list of comma separated `ServletContainerInitializer` class names in the order that you want them applied.
You may optionally use the wildcard character `+*+` *once* in the list.
It will match all `ServletContainerInitializer` classes not explicitly named in the list.
Here is an example context xml file that ensures the `com.example.PrioritySCI` will be called first, followed by the `com.acme.FooSCI`, then all other SCIs:
Here is an example context XML file that ensures the `com.example.PrioritySCI` will be called first, followed by the `com.acme.FooSCI`, then all other SCIs:
[source,xml]
[source,xml,subs="verbatim,attributes"]
----
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<Configure class="org.eclipse.jetty.ee9.webapp.WebAppContext"> <!--1-->
<Configure class="org.eclipse.jetty.{ee-current}.webapp.WebAppContext"> <!--1-->
<Call name="setAttribute"> <!--2-->
<Arg>org.eclipse.jetty.containerInitializerOrder</Arg> <!--3-->
<Arg>org.eclipse.jetty.websocket.javax.server.JavaxWebSocketServletContainerInitializer, com.acme.FooSCI, *</Arg> <!--4-->
</Call>
</Configure>
----
<1> Configures a link:{javadoc-url}/org/eclipse/jetty/webapp/WebAppContext.html[`WebAppContext`], which is the Jetty component that represents a standard Servlet web application.
<1> Configures a link:{javadoc-url}/org/eclipse/jetty/{ee-current}/webapp/WebAppContext.html[`WebAppContext`], which is the Jetty component that represents a standard Servlet web application.
<2> Specifies a context attribute.
<3> Specifies the name of the context attribute.
<4> Specifies the value of the context attribute.

View File

@ -17,6 +17,10 @@
</properties>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-security</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-util</artifactId>

View File

@ -13,11 +13,15 @@
module org.eclipse.jetty.plus
{
requires org.eclipse.jetty.security;
requires org.eclipse.jetty.util;
requires org.slf4j;
requires transitive java.naming;
requires transitive java.sql;
// Only required if using DataSourceLoginService.
requires static java.sql;
exports org.eclipse.jetty.plus.annotation;
exports org.eclipse.jetty.plus.jndi;
exports org.eclipse.jetty.plus.security;
}

View File

@ -11,7 +11,7 @@
// ========================================================================
//
package org.eclipse.jetty.ee9.plus.annotation;
package org.eclipse.jetty.plus.annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Member;

View File

@ -11,7 +11,7 @@
// ========================================================================
//
package org.eclipse.jetty.ee9.plus.annotation;
package org.eclipse.jetty.plus.annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

View File

@ -11,7 +11,7 @@
// ========================================================================
//
package org.eclipse.jetty.ee9.plus.annotation;
package org.eclipse.jetty.plus.annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

View File

@ -11,7 +11,7 @@
// ========================================================================
//
package org.eclipse.jetty.ee9.plus.annotation;
package org.eclipse.jetty.plus.annotation;
import java.util.Collection;
import java.util.Collections;

View File

@ -11,7 +11,7 @@
// ========================================================================
//
package org.eclipse.jetty.ee9.plus.annotation;
package org.eclipse.jetty.plus.annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

View File

@ -11,7 +11,7 @@
// ========================================================================
//
package org.eclipse.jetty.ee9.plus.annotation;
package org.eclipse.jetty.plus.annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

View File

@ -14,4 +14,4 @@
/**
* Jetty Plus : Limited JEE Annotation Support
*/
package org.eclipse.jetty.ee9.plus.annotation;
package org.eclipse.jetty.plus.annotation;

View File

@ -11,7 +11,7 @@
// ========================================================================
//
package org.eclipse.jetty.ee9.plus.security;
package org.eclipse.jetty.plus.security;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
@ -307,12 +307,6 @@ public class DataSourceLoginService extends AbstractLoginService
if (_datasource != null)
return;
@SuppressWarnings("unused")
InitialContext ic = new InitialContext();
assert ic != null;
// TODO Should we try webapp scope too?
// try finding the datasource in the Server scope
if (_server != null)
{

View File

@ -14,4 +14,4 @@
/**
* Jetty Plus : Limited JEE Security Support
*/
package org.eclipse.jetty.ee9.plus.security;
package org.eclipse.jetty.plus.security;

View File

@ -80,7 +80,7 @@
<configuration>
<argLine>@{argLine} ${jetty.surefire.argLine}
--add-reads org.eclipse.jetty.ee10.annotations=org.eclipse.jetty.logging
--add-opens org.eclipse.jetty.ee10.annotations/org.eclipse.jetty.ee10.annotations.resources=org.eclipse.jetty.ee10.plus</argLine>
--add-opens org.eclipse.jetty.ee10.annotations/org.eclipse.jetty.ee10.annotations.resources=org.eclipse.jetty.plus</argLine>
</configuration>
</plugin>
</plugins>

View File

@ -18,11 +18,11 @@ import java.lang.reflect.Modifier;
import jakarta.annotation.PostConstruct;
import org.eclipse.jetty.ee10.annotations.AnnotationIntrospector.AbstractIntrospectableAnnotationHandler;
import org.eclipse.jetty.ee10.plus.annotation.LifeCycleCallbackCollection;
import org.eclipse.jetty.ee10.plus.annotation.PostConstructCallback;
import org.eclipse.jetty.ee10.webapp.MetaData;
import org.eclipse.jetty.ee10.webapp.Origin;
import org.eclipse.jetty.ee10.webapp.WebAppContext;
import org.eclipse.jetty.plus.annotation.LifeCycleCallbackCollection;
import org.eclipse.jetty.plus.annotation.PostConstructCallback;
public class PostConstructAnnotationHandler extends AbstractIntrospectableAnnotationHandler
{

View File

@ -18,11 +18,11 @@ import java.lang.reflect.Modifier;
import jakarta.annotation.PreDestroy;
import org.eclipse.jetty.ee10.annotations.AnnotationIntrospector.AbstractIntrospectableAnnotationHandler;
import org.eclipse.jetty.ee10.plus.annotation.LifeCycleCallbackCollection;
import org.eclipse.jetty.ee10.plus.annotation.PreDestroyCallback;
import org.eclipse.jetty.ee10.webapp.MetaData;
import org.eclipse.jetty.ee10.webapp.Origin;
import org.eclipse.jetty.ee10.webapp.WebAppContext;
import org.eclipse.jetty.plus.annotation.LifeCycleCallbackCollection;
import org.eclipse.jetty.plus.annotation.PreDestroyCallback;
public class PreDestroyAnnotationHandler extends AbstractIntrospectableAnnotationHandler
{

View File

@ -25,11 +25,11 @@ import javax.naming.NamingException;
import jakarta.annotation.Resource;
import org.eclipse.jetty.ee10.annotations.AnnotationIntrospector.AbstractIntrospectableAnnotationHandler;
import org.eclipse.jetty.ee10.plus.annotation.Injection;
import org.eclipse.jetty.ee10.plus.annotation.InjectionCollection;
import org.eclipse.jetty.ee10.servlet.ServletContextHandler;
import org.eclipse.jetty.ee10.webapp.MetaData;
import org.eclipse.jetty.ee10.webapp.WebAppContext;
import org.eclipse.jetty.plus.annotation.Injection;
import org.eclipse.jetty.plus.annotation.InjectionCollection;
import org.eclipse.jetty.plus.jndi.NamingEntryUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

View File

@ -16,12 +16,12 @@ package org.eclipse.jetty.ee10.annotations;
import java.nio.file.Files;
import java.nio.file.Path;
import org.eclipse.jetty.ee10.plus.annotation.LifeCycleCallbackCollection;
import org.eclipse.jetty.ee10.servlet.ServletHolder;
import org.eclipse.jetty.ee10.servlet.Source;
import org.eclipse.jetty.ee10.webapp.MetaData;
import org.eclipse.jetty.ee10.webapp.WebAppContext;
import org.eclipse.jetty.ee10.webapp.WebDescriptor;
import org.eclipse.jetty.plus.annotation.LifeCycleCallbackCollection;
import org.eclipse.jetty.toolchain.test.jupiter.WorkDir;
import org.eclipse.jetty.toolchain.test.jupiter.WorkDirExtension;
import org.eclipse.jetty.util.DecoratedObjectFactory;

View File

@ -21,9 +21,9 @@ import javax.naming.InitialContext;
import org.eclipse.jetty.ee10.annotations.AnnotationIntrospector;
import org.eclipse.jetty.ee10.annotations.ResourceAnnotationHandler;
import org.eclipse.jetty.ee10.annotations.ResourcesAnnotationHandler;
import org.eclipse.jetty.ee10.plus.annotation.Injection;
import org.eclipse.jetty.ee10.plus.annotation.InjectionCollection;
import org.eclipse.jetty.ee10.webapp.WebAppContext;
import org.eclipse.jetty.plus.annotation.Injection;
import org.eclipse.jetty.plus.annotation.InjectionCollection;
import org.eclipse.jetty.plus.jndi.EnvEntry;
import org.eclipse.jetty.server.Server;
import org.junit.jupiter.api.AfterEach;

View File

@ -78,6 +78,13 @@
</instructions>
</configuration>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>@{argLine} ${jetty.surefire.argLine} --add-exports=org.eclipse.jetty.ee10.plus/org.eclipse.jetty.ee10.plus.annotation=org.eclipse.jetty.ee10.servlet --add-opens org.eclipse.jetty.ee10.plus/org.eclipse.jetty.ee10.plus.annotation=org.eclipse.jetty.plus</argLine>
</configuration>
</plugin>
</plugins>
</build>

View File

@ -21,16 +21,10 @@ module org.eclipse.jetty.ee10.plus
requires transitive org.eclipse.jetty.ee10.webapp;
// Only required if using DataSourceLoginService.
requires static java.sql;
// Only required if using Transaction.
requires static jakarta.transaction;
// Only required if using RunAs.
requires static org.eclipse.jetty.ee10.servlet;
exports org.eclipse.jetty.ee10.plus.annotation;
exports org.eclipse.jetty.ee10.plus.jndi;
exports org.eclipse.jetty.ee10.plus.security;
exports org.eclipse.jetty.ee10.plus.webapp;
provides org.eclipse.jetty.ee10.webapp.Configuration with

View File

@ -1,231 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//
package org.eclipse.jetty.ee10.plus.annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.util.Locale;
import java.util.Objects;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import org.eclipse.jetty.util.IntrospectionUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Injection
* <p>
* Represents the injection of a resource into a target (method or field).
* The injection is performed by doing an ENC lookup using the jndi
* name provided, and setting the object obtained on the target.
*/
public class Injection
{
private static final Logger LOG = LoggerFactory.getLogger(Injection.class);
private final Class<?> _targetClass;
private final String _jndiName;
private final String _mappingName;
private final Member _target;
private final Class<?> _paramClass;
private final Class<?> _resourceClass;
public Injection(Class<?> clazz, Field field, Class<?> resourceType, String jndiName, String mappingName)
{
_targetClass = Objects.requireNonNull(clazz);
_target = Objects.requireNonNull(field);
_resourceClass = resourceType;
_paramClass = null;
_jndiName = jndiName;
_mappingName = mappingName;
}
public Injection(Class<?> clazz, Method method, Class<?> arg, Class<?> resourceType, String jndiName, String mappingName)
{
_targetClass = Objects.requireNonNull(clazz);
_target = Objects.requireNonNull(method);
_resourceClass = resourceType;
_paramClass = arg;
_jndiName = jndiName;
_mappingName = mappingName;
}
public Injection(Class<?> clazz, String target, Class<?> resourceType, String jndiName, String mappingName)
{
_targetClass = Objects.requireNonNull(clazz);
Objects.requireNonNull(target);
_resourceClass = resourceType;
_jndiName = jndiName;
_mappingName = mappingName;
Member tmpTarget = null;
Class<?> tmpParamClass = null;
//first look for a javabeans style setter matching the targetName
String setter = "set" + target.substring(0, 1).toUpperCase(Locale.ENGLISH) + target.substring(1);
try
{
if (LOG.isDebugEnabled())
LOG.debug("Looking for method for setter: {} with arg {}", setter, _resourceClass);
tmpTarget = IntrospectionUtil.findMethod(clazz, setter, new Class[]{_resourceClass}, true, false);
tmpParamClass = _resourceClass;
}
catch (NoSuchMethodException nsme)
{
//try as a field
try
{
tmpTarget = IntrospectionUtil.findField(clazz, target, resourceType, true, false);
tmpParamClass = null;
}
catch (NoSuchFieldException nsfe)
{
nsme.addSuppressed(nsfe);
throw new IllegalArgumentException("No such field or method " + target + " on class " + _targetClass, nsme);
}
}
_target = tmpTarget;
_paramClass = tmpParamClass;
}
/**
* @return the _className
*/
public Class<?> getTargetClass()
{
return _targetClass;
}
public Class<?> getParamClass()
{
return _paramClass;
}
public Class<?> getResourceClass()
{
return _resourceClass;
}
public boolean isField()
{
return (Field.class.isInstance(_target));
}
public boolean isMethod()
{
return (Method.class.isInstance(_target));
}
/**
* Get the jndiName.
* @return the jndiName
*/
public String getJndiName()
{
return _jndiName;
}
/**
* @return the mappingName
*/
public String getMappingName()
{
return _mappingName;
}
/**
* Get the target.
* @return the target
*/
public Member getTarget()
{
return _target;
}
/**
* Inject a value for a Resource from JNDI into an object
*
* @param injectable the object to inject
*/
public void inject(Object injectable)
{
if (isField())
injectField((Field)_target, injectable);
else if (isMethod())
injectMethod((Method)_target, injectable);
else
throw new IllegalStateException("Neither field nor method injection");
}
/**
* The Resource must already exist in the ENC of this webapp.
*
* @return the injected valud
* @throws NamingException if unable to lookup value
*/
public Object lookupInjectedValue()
throws NamingException
{
InitialContext context = new InitialContext();
return context.lookup("java:comp/env/" + getJndiName());
}
/**
* Inject value from jndi into a field of an instance
*
* @param field the field to inject into
* @param injectable the value to inject
*/
protected void injectField(Field field, Object injectable)
{
try
{
boolean accessibility = field.isAccessible();
field.setAccessible(true);
field.set(injectable, lookupInjectedValue());
field.setAccessible(accessibility);
}
catch (Exception e)
{
LOG.warn("Unable to inject field {} with {}", field, injectable, e);
throw new IllegalStateException("Inject failed for field " + field.getName());
}
}
/**
* Inject value from jndi into a setter method of an instance
*
* @param method the method to inject into
* @param injectable the value to inject
*/
protected void injectMethod(Method method, Object injectable)
{
try
{
boolean accessibility = method.isAccessible();
method.setAccessible(true);
method.invoke(injectable, new Object[]{lookupInjectedValue()});
method.setAccessible(accessibility);
}
catch (Exception e)
{
LOG.warn("Unable to inject method {} with {}", method, injectable, e);
throw new IllegalStateException("Inject failed for method " + method.getName());
}
}
}

View File

@ -1,139 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//
package org.eclipse.jetty.ee10.plus.annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CopyOnWriteArraySet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* InjectionCollection
* Map of classname to all injections requested on that class,
* whether by declaration in web.xml or via equivalent annotations.
*
* This class is not threadsafe for concurrent modifications, but is
* threadsafe for readers with concurrent modifications.
*/
public class InjectionCollection
{
private static final Logger LOG = LoggerFactory.getLogger(InjectionCollection.class);
public static final String INJECTION_COLLECTION = "org.eclipse.jetty.injectionCollection";
private final ConcurrentMap<String, Set<Injection>> _injectionMap = new ConcurrentHashMap<>(); //map of classname to injections
public void add(Injection injection)
{
if (injection == null)
{
if (LOG.isDebugEnabled())
LOG.debug("Ignoring null Injection");
return;
}
String name = injection.getTargetClass().getName();
Set<Injection> injections = _injectionMap.get(name);
if (injections == null)
{
injections = new CopyOnWriteArraySet<>();
Set<Injection> tmp = _injectionMap.putIfAbsent(name, injections);
if (tmp != null)
injections = tmp;
}
boolean added = injections.add(injection);
if (LOG.isDebugEnabled())
LOG.debug("Adding injection for class={} on {} added={}", name, injection.getTarget().getName(), added);
}
public Set<Injection> getInjections(String className)
{
if (className == null)
return null;
return _injectionMap.get(className);
}
public Injection getInjection(String jndiName, Class<?> clazz, Field field)
{
if (field == null || clazz == null)
return null;
Set<Injection> injections = getInjections(clazz.getName());
if (injections == null)
return null;
Iterator<Injection> itor = injections.iterator();
Injection injection = null;
while (itor.hasNext() && injection == null)
{
Injection i = itor.next();
if (i.isField() && field.getName().equals(i.getTarget().getName()))
injection = i;
}
return injection;
}
public Injection getInjection(String jndiName, Class<?> clazz, Method method, Class<?> paramClass)
{
if (clazz == null || method == null || paramClass == null)
return null;
Set<Injection> injections = getInjections(clazz.getName());
if (injections == null)
return null;
Iterator<Injection> itor = injections.iterator();
Injection injection = null;
while (itor.hasNext() && injection == null)
{
Injection i = itor.next();
if (i.isMethod() && i.getTarget().getName().equals(method.getName()) && paramClass.equals(i.getParamClass()))
injection = i;
}
return injection;
}
public void inject(Object injectable)
{
if (injectable == null)
return;
//Get all injections pertinent to the Object by
//looking at it's class hierarchy
Class<?> clazz = injectable.getClass();
while (clazz != null)
{
Set<Injection> injections = _injectionMap.get(clazz.getName());
if (injections != null)
{
for (Injection i : injections)
{
i.inject(injectable);
}
}
clazz = clazz.getSuperclass();
}
}
}

View File

@ -1,170 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//
package org.eclipse.jetty.ee10.plus.annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Objects;
import org.eclipse.jetty.util.IntrospectionUtil;
import org.eclipse.jetty.util.Loader;
import org.eclipse.jetty.util.TypeUtil;
/**
* LifeCycleCallback
*
* Holds information about a class and method
* that has either been configured in web.xml to have postconstruct or
* predestroy callbacks, or has the equivalent annotations.
*/
public abstract class LifeCycleCallback
{
public static final Object[] __EMPTY_ARGS = new Object[]{};
private Method _target;
private Class<?> _targetClass; //Not final so we can do lazy load
private final String _className;
private final String _methodName;
public LifeCycleCallback(String className, String methodName)
{
_className = Objects.requireNonNull(className);
_methodName = Objects.requireNonNull(methodName);
}
public LifeCycleCallback(Class<?> clazz, String methodName)
{
_targetClass = Objects.requireNonNull(clazz);
_methodName = Objects.requireNonNull(methodName);
try
{
Method method = IntrospectionUtil.findMethod(clazz, methodName, null, true, true);
validate(clazz, method);
_target = method;
_className = clazz.getName();
}
catch (NoSuchMethodException e)
{
throw new IllegalArgumentException("Method " + methodName + " not found on class " + clazz.getName());
}
}
/**
* @return the _targetClass
*/
public Class<?> getTargetClass()
{
return _targetClass;
}
public String getTargetClassName()
{
return _className;
}
public String getMethodName()
{
return _methodName;
}
/**
* Get the target.
* @return the target
*/
public Method getTarget()
{
return _target;
}
public void callback(Object instance)
throws SecurityException, NoSuchMethodException, ClassNotFoundException, IllegalArgumentException, IllegalAccessException, InvocationTargetException
{
if (_target == null) //lazy load the target class
{
if (_targetClass == null)
_targetClass = Loader.loadClass(_className);
_target = _targetClass.getDeclaredMethod(_methodName, TypeUtil.NO_ARGS);
}
if (_target != null)
{
boolean accessibility = getTarget().isAccessible();
getTarget().setAccessible(true);
getTarget().invoke(instance, __EMPTY_ARGS);
getTarget().setAccessible(accessibility);
}
}
/**
* Find a method of the given name either directly in the given
* class, or inherited.
*
* @param pack the package of the class under inspection
* @param clazz the class under inspection
* @param methodName the method to find
* @param checkInheritance false on first entry, true if a superclass is being introspected
* @return the method
*/
public Method findMethod(Package pack, Class<?> clazz, String methodName, boolean checkInheritance)
{
if (clazz == null)
return null;
try
{
Method method = clazz.getDeclaredMethod(methodName);
if (checkInheritance)
{
int modifiers = method.getModifiers();
if (Modifier.isProtected(modifiers) || Modifier.isPublic(modifiers) || (!Modifier.isPrivate(modifiers) && (pack.equals(clazz.getPackage()))))
return method;
else
return findMethod(clazz.getPackage(), clazz.getSuperclass(), methodName, true);
}
return method;
}
catch (NoSuchMethodException e)
{
return findMethod(clazz.getPackage(), clazz.getSuperclass(), methodName, true);
}
}
@Override
public int hashCode()
{
return Objects.hash(_className, _methodName);
}
@Override
public boolean equals(Object o)
{
if (o == null)
return false;
if (this == o)
return true;
if (!LifeCycleCallback.class.isInstance(o))
return false;
LifeCycleCallback callback = (LifeCycleCallback)o;
if (getTargetClassName().equals(callback.getTargetClassName()) && getMethodName().equals(callback.getMethodName()))
return true;
return false;
}
public abstract void validate(Class<?> clazz, Method m);
}

View File

@ -1,197 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//
package org.eclipse.jetty.ee10.plus.annotation;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CopyOnWriteArraySet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* LifeCycleCallbackCollection
*
* This class collects the classes and methods that have been configured
* in web.xml with postconstruct/predestroy callbacks, or that contain the
* equivalent annotations. It is also responsible for calling the
* callbacks.
*
* This class is not threadsafe for concurrent modifications, but is
* threadsafe for reading with concurrent modifications.
*/
public class LifeCycleCallbackCollection
{
private static final Logger LOG = LoggerFactory.getLogger(LifeCycleCallbackCollection.class);
public static final String LIFECYCLE_CALLBACK_COLLECTION = "org.eclipse.jetty.lifecyleCallbackCollection";
private final ConcurrentMap<String, Set<LifeCycleCallback>> postConstructCallbacksMap = new ConcurrentHashMap<>();
private final ConcurrentMap<String, Set<LifeCycleCallback>> preDestroyCallbacksMap = new ConcurrentHashMap<>();
/**
* Add a Callback to the list of callbacks.
*
* @param callback the callback
*/
public void add(LifeCycleCallback callback)
{
if (callback == null)
{
if (LOG.isDebugEnabled())
LOG.debug("Ignoring empty LifeCycleCallback");
return;
}
Map<String, Set<LifeCycleCallback>> map = null;
if (callback instanceof PreDestroyCallback)
map = preDestroyCallbacksMap;
else if (callback instanceof PostConstructCallback)
map = postConstructCallbacksMap;
else
throw new IllegalArgumentException("Unsupported lifecycle callback type: " + callback);
Set<LifeCycleCallback> callbacks = map.get(callback.getTargetClassName());
if (callbacks == null)
{
callbacks = new CopyOnWriteArraySet<LifeCycleCallback>();
Set<LifeCycleCallback> tmp = map.putIfAbsent(callback.getTargetClassName(), callbacks);
if (tmp != null)
callbacks = tmp;
}
boolean added = callbacks.add(callback);
if (LOG.isDebugEnabled())
LOG.debug("Adding callback for class={} on method={} added={}", callback.getTargetClassName(), callback.getMethodName(), added);
}
public Set<LifeCycleCallback> getPreDestroyCallbacks(Object o)
{
if (o == null)
return null;
Class<? extends Object> clazz = o.getClass();
return preDestroyCallbacksMap.get(clazz.getName());
}
/**
* Amalgamate all pre-destroy callbacks and return a read only set
*
* @return the collection of {@link PreDestroyCallback}s
*/
public Collection<LifeCycleCallback> getPreDestroyCallbacks()
{
Set<LifeCycleCallback> set = new HashSet<LifeCycleCallback>();
for (String s : preDestroyCallbacksMap.keySet())
{
set.addAll(preDestroyCallbacksMap.get(s));
}
return Collections.unmodifiableCollection(set);
}
public Set<LifeCycleCallback> getPostConstructCallbacks(Object o)
{
if (o == null)
return null;
Class<? extends Object> clazz = o.getClass();
return postConstructCallbacksMap.get(clazz.getName());
}
/**
* Amalgamate all post-construct callbacks and return a read only set
*
* @return the collection of {@link PostConstructCallback}s
*/
public Collection<LifeCycleCallback> getPostConstructCallbacks()
{
Set<LifeCycleCallback> set = new HashSet<LifeCycleCallback>();
for (String s : postConstructCallbacksMap.keySet())
{
set.addAll(postConstructCallbacksMap.get(s));
}
return Collections.unmodifiableCollection(set);
}
/**
* Call the method, if one exists, that is annotated with <code>&#064;PostConstruct</code>
* or with <code>&lt;post-construct&gt;</code> in web.xml
*
* @param o the object on which to attempt the callback
* @throws Exception if unable to call {@link PostConstructCallback}
*/
public void callPostConstructCallback(Object o)
throws Exception
{
if (o == null)
return;
Class<? extends Object> clazz = o.getClass();
Set<LifeCycleCallback> callbacks = postConstructCallbacksMap.get(clazz.getName());
if (callbacks == null)
return;
for (LifeCycleCallback l : callbacks)
l.callback(o);
}
/**
* Call the method, if one exists, that is annotated with <code>&#064;PreDestroy</code>
* or with <code>&lt;pre-destroy&gt;</code> in web.xml
*
* @param o the object on which to attempt the callback
* @throws Exception if unable to call {@link PreDestroyCallback}
*/
public void callPreDestroyCallback(Object o)
throws Exception
{
if (o == null)
return;
Class<? extends Object> clazz = o.getClass();
Set<LifeCycleCallback> callbacks = preDestroyCallbacksMap.get(clazz.getName());
if (callbacks == null)
return;
for (LifeCycleCallback l : callbacks)
l.callback(o);
}
/**
* Generate a read-only view of the post-construct callbacks
*
* @return the map of {@link PostConstructCallback}s
*/
public Map<String, Set<LifeCycleCallback>> getPostConstructCallbackMap()
{
return Collections.unmodifiableMap(postConstructCallbacksMap);
}
/**
* Generate a read-only view of the pre-destroy callbacks
*
* @return the map of {@link PreDestroyCallback}s
*/
public Map<String, Set<LifeCycleCallback>> getPreDestroyCallbackMap()
{
return Collections.unmodifiableMap(preDestroyCallbacksMap);
}
}

View File

@ -1,80 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//
package org.eclipse.jetty.ee10.plus.annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
/**
* PostConstructCallback
*/
public class PostConstructCallback extends LifeCycleCallback
{
/**
* @param clazz the class object to be injected
* @param methodName the name of the method to be injected
*/
public PostConstructCallback(Class<?> clazz, String methodName)
{
super(clazz, methodName);
}
/**
* @param className the name of the class to be injected
* @param methodName the name of the method to be injected
*/
public PostConstructCallback(String className, String methodName)
{
super(className, methodName);
}
/**
* Commons Annotation Specification section 2.5
* - no params
* - must be void return
* - no checked exceptions
* - cannot be static
*
* @see LifeCycleCallback#validate(java.lang.Class, java.lang.reflect.Method)
*/
@Override
public void validate(Class<?> clazz, Method method)
{
if (method.getExceptionTypes().length > 0)
throw new IllegalArgumentException(clazz.getName() + "." + method.getName() + " cannot not throw a checked exception");
if (!method.getReturnType().equals(Void.TYPE))
throw new IllegalArgumentException(clazz.getName() + "." + method.getName() + " cannot not have a return type");
if (Modifier.isStatic(method.getModifiers()))
throw new IllegalArgumentException(clazz.getName() + "." + method.getName() + " cannot be static");
}
@Override
public void callback(Object instance)
throws SecurityException, IllegalArgumentException, NoSuchMethodException, ClassNotFoundException, IllegalAccessException, InvocationTargetException
{
super.callback(instance);
}
@Override
public boolean equals(Object o)
{
if (super.equals(o) && (o instanceof PostConstructCallback))
return true;
return false;
}
}

View File

@ -1,90 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//
package org.eclipse.jetty.ee10.plus.annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* PreDestroyCallback
*/
public class PreDestroyCallback extends LifeCycleCallback
{
private static final Logger LOG = LoggerFactory.getLogger(PreDestroyCallback.class);
/**
* @param clazz the class object to be injected
* @param methodName the name of the method to inject
*/
public PreDestroyCallback(Class<?> clazz, String methodName)
{
super(clazz, methodName);
}
/**
* @param className the name of the class to inject
* @param methodName the name of the method to inject
*/
public PreDestroyCallback(String className, String methodName)
{
super(className, methodName);
}
/**
* Commons Annotations Specification section 2.6:
* - no params to method
* - returns void
* - no checked exceptions
* - not static
*
* @see LifeCycleCallback#validate(java.lang.Class, java.lang.reflect.Method)
*/
@Override
public void validate(Class<?> clazz, Method method)
{
if (method.getExceptionTypes().length > 0)
throw new IllegalArgumentException(clazz.getName() + "." + method.getName() + " cannot not throw a checked exception");
if (!method.getReturnType().equals(Void.TYPE))
throw new IllegalArgumentException(clazz.getName() + "." + method.getName() + " cannot not have a return type");
if (Modifier.isStatic(method.getModifiers()))
throw new IllegalArgumentException(clazz.getName() + "." + method.getName() + " cannot be static");
}
@Override
public void callback(Object instance)
{
try
{
super.callback(instance);
}
catch (Exception e)
{
LOG.warn("Ignoring exception thrown on preDestroy call to {}.{}", getTargetClass(), getTarget().getName(), e);
}
}
@Override
public boolean equals(Object o)
{
if (super.equals(o) && (o instanceof PreDestroyCallback))
return true;
return false;
}
}

View File

@ -1,61 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//
package org.eclipse.jetty.ee10.plus.annotation;
import java.util.Objects;
import org.eclipse.jetty.ee10.servlet.ServletHolder;
/**
* RunAs
* <p>
* Represents a <code>&lt;run-as&gt;</code> element in web.xml, or a <code>&#064;RunAs</code> annotation.
* @deprecated unused as of 9.4.28 due for removal in 10.0.0
*/
@Deprecated
public class RunAs
{
private String _className;
private String _roleName;
public RunAs(String className, String roleName)
{
_className = Objects.requireNonNull(className);
_roleName = Objects.requireNonNull(roleName);
}
public String getTargetClassName()
{
return _className;
}
public String getRoleName()
{
return _roleName;
}
public void setRunAs(ServletHolder holder)
{
if (holder == null)
return;
String className = holder.getClassName();
if (className.equals(_className))
{
//Only set the RunAs if it has not already been set, presumably by web/web-fragment.xml
if (holder.getRegistration().getRunAsRole() == null)
holder.getRegistration().setRunAsRole(_roleName);
}
}
}

View File

@ -1,69 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//
package org.eclipse.jetty.ee10.plus.annotation;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.eclipse.jetty.ee10.servlet.ServletHolder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* RunAsCollection
* @deprecated class unused as of 9.4.28 due for removal in 10.0.0
*/
@Deprecated
public class RunAsCollection
{
private static final Logger LOG = LoggerFactory.getLogger(RunAsCollection.class);
public static final String RUNAS_COLLECTION = "org.eclipse.jetty.runAsCollection";
private ConcurrentMap<String, RunAs> _runAsMap = new ConcurrentHashMap<String, RunAs>(); //map of classname to run-as
public void add(RunAs runAs)
{
if ((runAs == null) || (runAs.getTargetClassName() == null))
return;
if (LOG.isDebugEnabled())
LOG.debug("Adding run-as for class=" + runAs.getTargetClassName());
RunAs prev = _runAsMap.putIfAbsent(runAs.getTargetClassName(), runAs);
if (prev != null)
LOG.warn("Run-As {} on class {} ignored, already run-as {}", runAs.getRoleName(), runAs.getTargetClassName(), prev.getRoleName());
}
public RunAs getRunAs(Object o)
{
if (o == null)
return null;
return (RunAs)_runAsMap.get(o.getClass().getName());
}
public void setRunAs(Object o)
{
if (o == null)
return;
if (!ServletHolder.class.isAssignableFrom(o.getClass()))
return;
RunAs runAs = (RunAs)_runAsMap.get(o.getClass().getName());
if (runAs == null)
return;
runAs.setRunAs((ServletHolder)o);
}
}

View File

@ -1,17 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//
/**
* Jetty Plus : Limited JEE Annotation Support
*/
package org.eclipse.jetty.ee10.plus.annotation;

View File

@ -1,465 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//
package org.eclipse.jetty.ee10.plus.security;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;
import javax.naming.InitialContext;
import javax.naming.NameNotFoundException;
import javax.naming.NamingException;
import javax.sql.DataSource;
import org.eclipse.jetty.plus.jndi.NamingEntryUtil;
import org.eclipse.jetty.security.AbstractLoginService;
import org.eclipse.jetty.security.IdentityService;
import org.eclipse.jetty.security.RolePrincipal;
import org.eclipse.jetty.security.UserPrincipal;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.util.security.Credential;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* DataSourceLoginService
* <p>
* Obtain user/password/role information from a database via jndi DataSource.
*/
public class DataSourceLoginService extends AbstractLoginService
{
private static final Logger LOG = LoggerFactory.getLogger(DataSourceLoginService.class);
private String _jndiName = "javax.sql.DataSource/default";
private DataSource _datasource;
private Server _server;
private String _userTableName = "users";
private String _userTableKey = "id";
private String _userTableUserField = "username";
private String _userTablePasswordField = "pwd";
private String _roleTableName = "roles";
private String _roleTableKey = "id";
private String _roleTableRoleField = "role";
private String _userRoleTableName = "user_roles";
private String _userRoleTableUserKey = "user_id";
private String _userRoleTableRoleKey = "role_id";
private String _userSql;
private String _roleSql;
private boolean _createTables = false;
/**
* DBUser
*/
public class DBUserPrincipal extends UserPrincipal
{
private int _key;
public DBUserPrincipal(String name, Credential credential, int key)
{
super(name, credential);
_key = key;
}
public int getKey()
{
return _key;
}
}
public DataSourceLoginService()
{
}
public DataSourceLoginService(String name)
{
setName(name);
}
public DataSourceLoginService(String name, IdentityService identityService)
{
setName(name);
setIdentityService(identityService);
}
public void setJndiName(String jndi)
{
_jndiName = jndi;
}
public String getJndiName()
{
return _jndiName;
}
public void setServer(Server server)
{
_server = server;
}
public Server getServer()
{
return _server;
}
public void setCreateTables(boolean createTables)
{
_createTables = createTables;
}
public boolean getCreateTables()
{
return _createTables;
}
public void setUserTableName(String name)
{
_userTableName = name;
}
public String getUserTableName()
{
return _userTableName;
}
public String getUserTableKey()
{
return _userTableKey;
}
public void setUserTableKey(String tableKey)
{
_userTableKey = tableKey;
}
public String getUserTableUserField()
{
return _userTableUserField;
}
public void setUserTableUserField(String tableUserField)
{
_userTableUserField = tableUserField;
}
public String getUserTablePasswordField()
{
return _userTablePasswordField;
}
public void setUserTablePasswordField(String tablePasswordField)
{
_userTablePasswordField = tablePasswordField;
}
public String getRoleTableName()
{
return _roleTableName;
}
public void setRoleTableName(String tableName)
{
_roleTableName = tableName;
}
public String getRoleTableKey()
{
return _roleTableKey;
}
public void setRoleTableKey(String tableKey)
{
_roleTableKey = tableKey;
}
public String getRoleTableRoleField()
{
return _roleTableRoleField;
}
public void setRoleTableRoleField(String tableRoleField)
{
_roleTableRoleField = tableRoleField;
}
public String getUserRoleTableName()
{
return _userRoleTableName;
}
public void setUserRoleTableName(String roleTableName)
{
_userRoleTableName = roleTableName;
}
public String getUserRoleTableUserKey()
{
return _userRoleTableUserKey;
}
public void setUserRoleTableUserKey(String roleTableUserKey)
{
_userRoleTableUserKey = roleTableUserKey;
}
public String getUserRoleTableRoleKey()
{
return _userRoleTableRoleKey;
}
public void setUserRoleTableRoleKey(String roleTableRoleKey)
{
_userRoleTableRoleKey = roleTableRoleKey;
}
@Override
public UserPrincipal loadUserInfo(String username)
{
try
{
try (Connection connection = getConnection();
PreparedStatement statement1 = connection.prepareStatement(_userSql))
{
statement1.setObject(1, username);
try (ResultSet rs1 = statement1.executeQuery())
{
if (rs1.next())
{
int key = rs1.getInt(_userTableKey);
String credentials = rs1.getString(_userTablePasswordField);
return new DBUserPrincipal(username, Credential.getCredential(credentials), key);
}
}
}
}
catch (NamingException e)
{
LOG.warn("No datasource for {}", _jndiName, e);
}
catch (SQLException e)
{
LOG.warn("Problem loading user info for {}", username, e);
}
return null;
}
@Override
public List<RolePrincipal> loadRoleInfo(UserPrincipal user)
{
DBUserPrincipal dbuser = (DBUserPrincipal)user;
try
{
try (Connection connection = getConnection();
PreparedStatement statement2 = connection.prepareStatement(_roleSql))
{
List<String> roles = new ArrayList<String>();
statement2.setInt(1, dbuser.getKey());
try (ResultSet rs2 = statement2.executeQuery())
{
while (rs2.next())
roles.add(rs2.getString(_roleTableRoleField));
return roles.stream().map(RolePrincipal::new).collect(Collectors.toList());
}
}
}
catch (NamingException e)
{
LOG.warn("No datasource for {}", _jndiName, e);
}
catch (SQLException e)
{
LOG.warn("Problem loading user info for {}", user.getName(), e);
}
return null;
}
/**
* Lookup the datasource for the jndiName and formulate the
* necessary sql query strings based on the configured table
* and column names.
*
* @throws NamingException if unable to init jndi
* @throws SQLException if unable to init database
*/
public void initDb() throws NamingException, SQLException
{
if (_datasource != null)
return;
@SuppressWarnings("unused")
InitialContext ic = new InitialContext();
assert ic != null;
// TODO Should we try webapp scope too?
// try finding the datasource in the Server scope
if (_server != null)
{
try
{
_datasource = (DataSource)NamingEntryUtil.lookup(_server, _jndiName);
}
catch (NameNotFoundException e)
{
//next try the jvm scope
}
}
//try finding the datasource in the jvm scope
if (_datasource == null)
{
_datasource = (DataSource)NamingEntryUtil.lookup(null, _jndiName);
}
// set up the select statements based on the table and column names configured
_userSql = "select " + _userTableKey + "," + _userTablePasswordField +
" from " + _userTableName +
" where " + _userTableUserField + " = ?";
_roleSql = "select r." + _roleTableRoleField +
" from " + _roleTableName + " r, " + _userRoleTableName +
" u where u." + _userRoleTableUserKey + " = ?" +
" and r." + _roleTableKey + " = u." + _userRoleTableRoleKey;
prepareTables();
}
/**
*
*/
private void prepareTables()
throws NamingException, SQLException
{
if (_createTables)
{
boolean autocommit = true;
Connection connection = getConnection();
try (Statement stmt = connection.createStatement())
{
autocommit = connection.getAutoCommit();
connection.setAutoCommit(false);
DatabaseMetaData metaData = connection.getMetaData();
//check if tables exist
String tableName = (metaData.storesLowerCaseIdentifiers() ? _userTableName.toLowerCase(Locale.ENGLISH) : (metaData.storesUpperCaseIdentifiers() ? _userTableName.toUpperCase(Locale.ENGLISH) : _userTableName));
try (ResultSet result = metaData.getTables(null, null, tableName, null))
{
if (!result.next())
{
//user table default
/*
* create table _userTableName (_userTableKey integer,
* _userTableUserField varchar(100) not null unique,
* _userTablePasswordField varchar(20) not null, primary key(_userTableKey));
*/
stmt.executeUpdate("create table " + _userTableName + "(" + _userTableKey + " integer," +
_userTableUserField + " varchar(100) not null unique," +
_userTablePasswordField + " varchar(20) not null, primary key(" + _userTableKey + "))");
if (LOG.isDebugEnabled())
LOG.debug("Created table {}", _userTableName);
}
}
tableName = (metaData.storesLowerCaseIdentifiers() ? _roleTableName.toLowerCase(Locale.ENGLISH) : (metaData.storesUpperCaseIdentifiers() ? _roleTableName.toUpperCase(Locale.ENGLISH) : _roleTableName));
try (ResultSet result = metaData.getTables(null, null, tableName, null))
{
if (!result.next())
{
//role table default
/*
* create table _roleTableName (_roleTableKey integer,
* _roleTableRoleField varchar(100) not null unique, primary key(_roleTableKey));
*/
String str = "create table " + _roleTableName + " (" + _roleTableKey + " integer, " +
_roleTableRoleField + " varchar(100) not null unique, primary key(" + _roleTableKey + "))";
stmt.executeUpdate(str);
if (LOG.isDebugEnabled())
LOG.debug("Created table {}", _roleTableName);
}
}
tableName = (metaData.storesLowerCaseIdentifiers() ? _userRoleTableName.toLowerCase(Locale.ENGLISH) : (metaData.storesUpperCaseIdentifiers() ? _userRoleTableName.toUpperCase(Locale.ENGLISH) : _userRoleTableName));
try (ResultSet result = metaData.getTables(null, null, tableName, null))
{
if (!result.next())
{
//user-role table
/*
* create table _userRoleTableName (_userRoleTableUserKey integer,
* _userRoleTableRoleKey integer,
* primary key (_userRoleTableUserKey, _userRoleTableRoleKey));
*
* create index idx_user_role on _userRoleTableName (_userRoleTableUserKey);
*/
stmt.executeUpdate("create table " + _userRoleTableName + " (" + _userRoleTableUserKey + " integer, " +
_userRoleTableRoleKey + " integer, " +
"primary key (" + _userRoleTableUserKey + ", " + _userRoleTableRoleKey + "))");
stmt.executeUpdate("create index indx_user_role on " + _userRoleTableName + "(" + _userRoleTableUserKey + ")");
if (LOG.isDebugEnabled())
LOG.debug("Created table {} and index", _userRoleTableName);
}
}
connection.commit();
}
finally
{
try
{
connection.setAutoCommit(autocommit);
}
catch (SQLException e)
{
if (LOG.isDebugEnabled())
LOG.debug("Prepare tables", e);
}
finally
{
try
{
connection.close();
}
catch (SQLException e)
{
if (LOG.isDebugEnabled())
LOG.debug("Prepare tables", e);
}
}
}
}
else if (LOG.isDebugEnabled())
{
LOG.debug("createTables false");
}
}
/**
*
*/
private Connection getConnection()
throws NamingException, SQLException
{
initDb();
return _datasource.getConnection();
}
}

View File

@ -1,17 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//
/**
* Jetty Plus : Limited JEE Security Support
*/
package org.eclipse.jetty.ee10.plus.security;

View File

@ -17,8 +17,6 @@ import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NameNotFoundException;
import org.eclipse.jetty.ee10.plus.annotation.InjectionCollection;
import org.eclipse.jetty.ee10.plus.annotation.LifeCycleCallbackCollection;
import org.eclipse.jetty.ee10.plus.jndi.Transaction;
import org.eclipse.jetty.ee10.servlet.ServletContextHandler;
import org.eclipse.jetty.ee10.webapp.AbstractConfiguration;
@ -27,6 +25,8 @@ import org.eclipse.jetty.ee10.webapp.JettyWebXmlConfiguration;
import org.eclipse.jetty.ee10.webapp.MetaInfConfiguration;
import org.eclipse.jetty.ee10.webapp.WebAppContext;
import org.eclipse.jetty.ee10.webapp.WebXmlConfiguration;
import org.eclipse.jetty.plus.annotation.InjectionCollection;
import org.eclipse.jetty.plus.annotation.LifeCycleCallbackCollection;
import org.eclipse.jetty.util.NanoTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

View File

@ -13,9 +13,9 @@
package org.eclipse.jetty.ee10.plus.webapp;
import org.eclipse.jetty.ee10.plus.annotation.InjectionCollection;
import org.eclipse.jetty.ee10.plus.annotation.LifeCycleCallbackCollection;
import org.eclipse.jetty.ee10.webapp.WebAppContext;
import org.eclipse.jetty.plus.annotation.InjectionCollection;
import org.eclipse.jetty.plus.annotation.LifeCycleCallbackCollection;
import org.eclipse.jetty.util.Decorator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

View File

@ -19,17 +19,17 @@ import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NameNotFoundException;
import org.eclipse.jetty.ee10.plus.annotation.Injection;
import org.eclipse.jetty.ee10.plus.annotation.InjectionCollection;
import org.eclipse.jetty.ee10.plus.annotation.LifeCycleCallback;
import org.eclipse.jetty.ee10.plus.annotation.LifeCycleCallbackCollection;
import org.eclipse.jetty.ee10.plus.annotation.PostConstructCallback;
import org.eclipse.jetty.ee10.plus.annotation.PreDestroyCallback;
import org.eclipse.jetty.ee10.webapp.Descriptor;
import org.eclipse.jetty.ee10.webapp.FragmentDescriptor;
import org.eclipse.jetty.ee10.webapp.IterativeDescriptorProcessor;
import org.eclipse.jetty.ee10.webapp.Origin;
import org.eclipse.jetty.ee10.webapp.WebAppContext;
import org.eclipse.jetty.plus.annotation.Injection;
import org.eclipse.jetty.plus.annotation.InjectionCollection;
import org.eclipse.jetty.plus.annotation.LifeCycleCallback;
import org.eclipse.jetty.plus.annotation.LifeCycleCallbackCollection;
import org.eclipse.jetty.plus.annotation.PostConstructCallback;
import org.eclipse.jetty.plus.annotation.PreDestroyCallback;
import org.eclipse.jetty.plus.jndi.EnvEntry;
import org.eclipse.jetty.plus.jndi.Link;
import org.eclipse.jetty.plus.jndi.NamingEntry;

View File

@ -19,6 +19,10 @@ import java.nio.file.Path;
import jakarta.servlet.http.HttpServlet;
import org.eclipse.jetty.ee10.servlet.ServletHolder;
import org.eclipse.jetty.ee10.webapp.WebAppContext;
import org.eclipse.jetty.plus.annotation.LifeCycleCallback;
import org.eclipse.jetty.plus.annotation.LifeCycleCallbackCollection;
import org.eclipse.jetty.plus.annotation.PostConstructCallback;
import org.eclipse.jetty.plus.annotation.PreDestroyCallback;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.toolchain.test.FS;
import org.eclipse.jetty.toolchain.test.jupiter.WorkDir;

View File

@ -19,8 +19,6 @@ import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.Name;
import org.eclipse.jetty.ee10.plus.annotation.Injection;
import org.eclipse.jetty.ee10.plus.annotation.InjectionCollection;
import org.eclipse.jetty.ee10.webapp.Configuration;
import org.eclipse.jetty.ee10.webapp.Descriptor;
import org.eclipse.jetty.ee10.webapp.FragmentDescriptor;
@ -28,6 +26,8 @@ import org.eclipse.jetty.ee10.webapp.Origin;
import org.eclipse.jetty.ee10.webapp.WebAppClassLoader;
import org.eclipse.jetty.ee10.webapp.WebAppContext;
import org.eclipse.jetty.ee10.webapp.WebDescriptor;
import org.eclipse.jetty.plus.annotation.Injection;
import org.eclipse.jetty.plus.annotation.InjectionCollection;
import org.eclipse.jetty.plus.jndi.EnvEntry;
import org.eclipse.jetty.plus.jndi.NamingEntryUtil;
import org.eclipse.jetty.plus.jndi.Resource;

View File

@ -31,8 +31,6 @@ import jakarta.servlet.SessionTrackingMode;
import jakarta.servlet.descriptor.JspPropertyGroupDescriptor;
import jakarta.servlet.descriptor.TaglibDescriptor;
import org.eclipse.jetty.ee10.annotations.AnnotationConfiguration;
import org.eclipse.jetty.ee10.plus.annotation.LifeCycleCallback;
import org.eclipse.jetty.ee10.plus.annotation.LifeCycleCallbackCollection;
import org.eclipse.jetty.ee10.servlet.ErrorPageErrorHandler;
import org.eclipse.jetty.ee10.servlet.FilterHolder;
import org.eclipse.jetty.ee10.servlet.FilterMapping;
@ -52,6 +50,8 @@ import org.eclipse.jetty.ee10.webapp.MetaInfConfiguration;
import org.eclipse.jetty.ee10.webapp.WebAppContext;
import org.eclipse.jetty.ee10.webapp.WebInfConfiguration;
import org.eclipse.jetty.http.MimeTypes;
import org.eclipse.jetty.plus.annotation.LifeCycleCallback;
import org.eclipse.jetty.plus.annotation.LifeCycleCallbackCollection;
import org.eclipse.jetty.security.Authenticator;
import org.eclipse.jetty.security.Constraint;
import org.eclipse.jetty.security.Constraint.Transport;

View File

@ -26,7 +26,7 @@ import org.eclipse.jetty.client.AuthenticationStore;
import org.eclipse.jetty.client.BasicAuthentication;
import org.eclipse.jetty.client.ContentResponse;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.ee10.plus.security.DataSourceLoginService;
import org.eclipse.jetty.plus.security.DataSourceLoginService;
import org.eclipse.jetty.toolchain.test.FS;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.eclipse.jetty.util.Loader;

View File

@ -111,7 +111,7 @@
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>@{argLine} ${jetty.surefire.argLine} --add-reads org.eclipse.jetty.ee8.annotations=org.eclipse.jetty.logging --add-opens org.eclipse.jetty.ee8.annotations/org.eclipse.jetty.ee8.annotations.resources=org.eclipse.jetty.ee8.plus</argLine>
<argLine>@{argLine} ${jetty.surefire.argLine} --add-reads org.eclipse.jetty.ee8.annotations=org.eclipse.jetty.logging --add-opens org.eclipse.jetty.ee8.annotations/org.eclipse.jetty.ee8.annotations.resources=org.eclipse.jetty.plus</argLine>
</configuration>
</plugin>
</plugins>

View File

@ -64,6 +64,13 @@
</instructions>
</configuration>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>@{argLine} ${jetty.surefire.argLine} --add-exports=org.eclipse.jetty.ee8.plus/org.eclipse.jetty.ee8.plus.annotation=org.eclipse.jetty.ee8.nested --add-opens org.eclipse.jetty.ee8.plus/org.eclipse.jetty.ee8.plus.annotation=org.eclipse.jetty.plus</argLine>
</configuration>
</plugin>
</plugins>
</build>

View File

@ -91,7 +91,7 @@
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>@{argLine} ${jetty.surefire.argLine} --add-reads org.eclipse.jetty.ee9.annotations=org.eclipse.jetty.logging --add-opens org.eclipse.jetty.ee9.annotations/org.eclipse.jetty.ee9.annotations.resources=org.eclipse.jetty.ee9.plus</argLine>
<argLine>@{argLine} ${jetty.surefire.argLine} --add-reads org.eclipse.jetty.ee9.annotations=org.eclipse.jetty.logging --add-opens org.eclipse.jetty.ee9.annotations/org.eclipse.jetty.ee9.annotations.resources=org.eclipse.jetty.plus</argLine>
</configuration>
</plugin>
</plugins>

View File

@ -18,11 +18,11 @@ import java.lang.reflect.Modifier;
import jakarta.annotation.PostConstruct;
import org.eclipse.jetty.ee9.annotations.AnnotationIntrospector.AbstractIntrospectableAnnotationHandler;
import org.eclipse.jetty.ee9.plus.annotation.LifeCycleCallbackCollection;
import org.eclipse.jetty.ee9.plus.annotation.PostConstructCallback;
import org.eclipse.jetty.ee9.webapp.MetaData;
import org.eclipse.jetty.ee9.webapp.Origin;
import org.eclipse.jetty.ee9.webapp.WebAppContext;
import org.eclipse.jetty.plus.annotation.LifeCycleCallbackCollection;
import org.eclipse.jetty.plus.annotation.PostConstructCallback;
public class PostConstructAnnotationHandler extends AbstractIntrospectableAnnotationHandler
{

View File

@ -18,11 +18,11 @@ import java.lang.reflect.Modifier;
import jakarta.annotation.PreDestroy;
import org.eclipse.jetty.ee9.annotations.AnnotationIntrospector.AbstractIntrospectableAnnotationHandler;
import org.eclipse.jetty.ee9.plus.annotation.LifeCycleCallbackCollection;
import org.eclipse.jetty.ee9.plus.annotation.PreDestroyCallback;
import org.eclipse.jetty.ee9.webapp.MetaData;
import org.eclipse.jetty.ee9.webapp.Origin;
import org.eclipse.jetty.ee9.webapp.WebAppContext;
import org.eclipse.jetty.plus.annotation.LifeCycleCallbackCollection;
import org.eclipse.jetty.plus.annotation.PreDestroyCallback;
public class PreDestroyAnnotationHandler extends AbstractIntrospectableAnnotationHandler
{

View File

@ -26,10 +26,10 @@ import javax.naming.NamingException;
import jakarta.annotation.Resource;
import org.eclipse.jetty.ee9.annotations.AnnotationIntrospector.AbstractIntrospectableAnnotationHandler;
import org.eclipse.jetty.ee9.nested.ContextHandler;
import org.eclipse.jetty.ee9.plus.annotation.Injection;
import org.eclipse.jetty.ee9.plus.annotation.InjectionCollection;
import org.eclipse.jetty.ee9.webapp.MetaData;
import org.eclipse.jetty.ee9.webapp.WebAppContext;
import org.eclipse.jetty.plus.annotation.Injection;
import org.eclipse.jetty.plus.annotation.InjectionCollection;
import org.eclipse.jetty.plus.jndi.NamingEntryUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

View File

@ -16,12 +16,12 @@ package org.eclipse.jetty.ee9.annotations;
import java.nio.file.Files;
import java.nio.file.Path;
import org.eclipse.jetty.ee9.plus.annotation.LifeCycleCallbackCollection;
import org.eclipse.jetty.ee9.servlet.ServletHolder;
import org.eclipse.jetty.ee9.servlet.Source;
import org.eclipse.jetty.ee9.webapp.MetaData;
import org.eclipse.jetty.ee9.webapp.WebAppContext;
import org.eclipse.jetty.ee9.webapp.WebDescriptor;
import org.eclipse.jetty.plus.annotation.LifeCycleCallbackCollection;
import org.eclipse.jetty.toolchain.test.jupiter.WorkDir;
import org.eclipse.jetty.toolchain.test.jupiter.WorkDirExtension;
import org.eclipse.jetty.util.DecoratedObjectFactory;

View File

@ -21,9 +21,9 @@ import javax.naming.InitialContext;
import org.eclipse.jetty.ee9.annotations.AnnotationIntrospector;
import org.eclipse.jetty.ee9.annotations.ResourceAnnotationHandler;
import org.eclipse.jetty.ee9.annotations.ResourcesAnnotationHandler;
import org.eclipse.jetty.ee9.plus.annotation.Injection;
import org.eclipse.jetty.ee9.plus.annotation.InjectionCollection;
import org.eclipse.jetty.ee9.webapp.WebAppContext;
import org.eclipse.jetty.plus.annotation.Injection;
import org.eclipse.jetty.plus.annotation.InjectionCollection;
import org.eclipse.jetty.plus.jndi.EnvEntry;
import org.eclipse.jetty.server.Server;
import org.junit.jupiter.api.AfterEach;

View File

@ -67,6 +67,12 @@
</instructions>
</configuration>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>@{argLine} ${jetty.surefire.argLine} --add-exports=org.eclipse.jetty.ee9.plus/org.eclipse.jetty.ee9.plus.annotation=org.eclipse.jetty.ee9.nested --add-opens org.eclipse.jetty.ee9.plus/org.eclipse.jetty.ee9.plus.annotation=org.eclipse.jetty.plus</argLine>
</configuration>
</plugin>
</plugins>
</build>

View File

@ -22,16 +22,10 @@ module org.eclipse.jetty.ee9.plus
requires transitive org.eclipse.jetty.ee9.webapp;
requires transitive org.eclipse.jetty.plus;
// Only required if using DataSourceLoginService.
requires static java.sql;
// Only required if using Transaction.
requires static jakarta.transaction;
// Only required if using RunAs.
requires static org.eclipse.jetty.ee9.servlet;
exports org.eclipse.jetty.ee9.plus.annotation;
exports org.eclipse.jetty.ee9.plus.jndi;
exports org.eclipse.jetty.ee9.plus.security;
exports org.eclipse.jetty.ee9.plus.webapp;
provides org.eclipse.jetty.ee9.webapp.Configuration with

View File

@ -1,61 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//
package org.eclipse.jetty.ee9.plus.annotation;
import java.util.Objects;
import org.eclipse.jetty.ee9.servlet.ServletHolder;
/**
* RunAs
* <p>
* Represents a <code>&lt;run-as&gt;</code> element in web.xml, or a <code>&#064;RunAs</code> annotation.
* @deprecated unused as of 9.4.28 due for removal in 10.0.0
*/
@Deprecated
public class RunAs
{
private String _className;
private String _roleName;
public RunAs(String className, String roleName)
{
_className = Objects.requireNonNull(className);
_roleName = Objects.requireNonNull(roleName);
}
public String getTargetClassName()
{
return _className;
}
public String getRoleName()
{
return _roleName;
}
public void setRunAs(ServletHolder holder)
{
if (holder == null)
return;
String className = holder.getClassName();
if (className.equals(_className))
{
//Only set the RunAs if it has not already been set, presumably by web/web-fragment.xml
if (holder.getRegistration().getRunAsRole() == null)
holder.getRegistration().setRunAsRole(_roleName);
}
}
}

View File

@ -1,69 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//
package org.eclipse.jetty.ee9.plus.annotation;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.eclipse.jetty.ee9.servlet.ServletHolder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* RunAsCollection
* @deprecated class unused as of 9.4.28 due for removal in 10.0.0
*/
@Deprecated
public class RunAsCollection
{
private static final Logger LOG = LoggerFactory.getLogger(RunAsCollection.class);
public static final String RUNAS_COLLECTION = "org.eclipse.jetty.runAsCollection";
private ConcurrentMap<String, RunAs> _runAsMap = new ConcurrentHashMap<String, RunAs>(); //map of classname to run-as
public void add(RunAs runAs)
{
if ((runAs == null) || (runAs.getTargetClassName() == null))
return;
if (LOG.isDebugEnabled())
LOG.debug("Adding run-as for class=" + runAs.getTargetClassName());
RunAs prev = _runAsMap.putIfAbsent(runAs.getTargetClassName(), runAs);
if (prev != null)
LOG.warn("Run-As {} on class {} ignored, already run-as {}", runAs.getRoleName(), runAs.getTargetClassName(), prev.getRoleName());
}
public RunAs getRunAs(Object o)
{
if (o == null)
return null;
return (RunAs)_runAsMap.get(o.getClass().getName());
}
public void setRunAs(Object o)
{
if (o == null)
return;
if (!ServletHolder.class.isAssignableFrom(o.getClass()))
return;
RunAs runAs = (RunAs)_runAsMap.get(o.getClass().getName());
if (runAs == null)
return;
runAs.setRunAs((ServletHolder)o);
}
}

View File

@ -18,8 +18,6 @@ import javax.naming.InitialContext;
import javax.naming.NameNotFoundException;
import org.eclipse.jetty.ee9.nested.ContextHandler;
import org.eclipse.jetty.ee9.plus.annotation.InjectionCollection;
import org.eclipse.jetty.ee9.plus.annotation.LifeCycleCallbackCollection;
import org.eclipse.jetty.ee9.plus.jndi.Transaction;
import org.eclipse.jetty.ee9.webapp.AbstractConfiguration;
import org.eclipse.jetty.ee9.webapp.FragmentConfiguration;
@ -27,6 +25,8 @@ import org.eclipse.jetty.ee9.webapp.JettyWebXmlConfiguration;
import org.eclipse.jetty.ee9.webapp.MetaInfConfiguration;
import org.eclipse.jetty.ee9.webapp.WebAppContext;
import org.eclipse.jetty.ee9.webapp.WebXmlConfiguration;
import org.eclipse.jetty.plus.annotation.InjectionCollection;
import org.eclipse.jetty.plus.annotation.LifeCycleCallbackCollection;
import org.eclipse.jetty.util.NanoTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

View File

@ -13,9 +13,9 @@
package org.eclipse.jetty.ee9.plus.webapp;
import org.eclipse.jetty.ee9.plus.annotation.InjectionCollection;
import org.eclipse.jetty.ee9.plus.annotation.LifeCycleCallbackCollection;
import org.eclipse.jetty.ee9.webapp.WebAppContext;
import org.eclipse.jetty.plus.annotation.InjectionCollection;
import org.eclipse.jetty.plus.annotation.LifeCycleCallbackCollection;
import org.eclipse.jetty.util.Decorator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

View File

@ -19,17 +19,17 @@ import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NameNotFoundException;
import org.eclipse.jetty.ee9.plus.annotation.Injection;
import org.eclipse.jetty.ee9.plus.annotation.InjectionCollection;
import org.eclipse.jetty.ee9.plus.annotation.LifeCycleCallback;
import org.eclipse.jetty.ee9.plus.annotation.LifeCycleCallbackCollection;
import org.eclipse.jetty.ee9.plus.annotation.PostConstructCallback;
import org.eclipse.jetty.ee9.plus.annotation.PreDestroyCallback;
import org.eclipse.jetty.ee9.webapp.Descriptor;
import org.eclipse.jetty.ee9.webapp.FragmentDescriptor;
import org.eclipse.jetty.ee9.webapp.IterativeDescriptorProcessor;
import org.eclipse.jetty.ee9.webapp.Origin;
import org.eclipse.jetty.ee9.webapp.WebAppContext;
import org.eclipse.jetty.plus.annotation.Injection;
import org.eclipse.jetty.plus.annotation.InjectionCollection;
import org.eclipse.jetty.plus.annotation.LifeCycleCallback;
import org.eclipse.jetty.plus.annotation.LifeCycleCallbackCollection;
import org.eclipse.jetty.plus.annotation.PostConstructCallback;
import org.eclipse.jetty.plus.annotation.PreDestroyCallback;
import org.eclipse.jetty.plus.jndi.EnvEntry;
import org.eclipse.jetty.plus.jndi.Link;
import org.eclipse.jetty.plus.jndi.NamingEntry;

View File

@ -19,6 +19,10 @@ import java.nio.file.Path;
import jakarta.servlet.http.HttpServlet;
import org.eclipse.jetty.ee9.servlet.ServletHolder;
import org.eclipse.jetty.ee9.webapp.WebAppContext;
import org.eclipse.jetty.plus.annotation.LifeCycleCallback;
import org.eclipse.jetty.plus.annotation.LifeCycleCallbackCollection;
import org.eclipse.jetty.plus.annotation.PostConstructCallback;
import org.eclipse.jetty.plus.annotation.PreDestroyCallback;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.toolchain.test.FS;
import org.eclipse.jetty.toolchain.test.jupiter.WorkDir;

View File

@ -19,8 +19,6 @@ import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.Name;
import org.eclipse.jetty.ee9.plus.annotation.Injection;
import org.eclipse.jetty.ee9.plus.annotation.InjectionCollection;
import org.eclipse.jetty.ee9.webapp.Configuration;
import org.eclipse.jetty.ee9.webapp.Descriptor;
import org.eclipse.jetty.ee9.webapp.FragmentDescriptor;
@ -28,6 +26,8 @@ import org.eclipse.jetty.ee9.webapp.Origin;
import org.eclipse.jetty.ee9.webapp.WebAppClassLoader;
import org.eclipse.jetty.ee9.webapp.WebAppContext;
import org.eclipse.jetty.ee9.webapp.WebDescriptor;
import org.eclipse.jetty.plus.annotation.Injection;
import org.eclipse.jetty.plus.annotation.InjectionCollection;
import org.eclipse.jetty.plus.jndi.EnvEntry;
import org.eclipse.jetty.plus.jndi.NamingEntryUtil;
import org.eclipse.jetty.plus.jndi.Resource;

View File

@ -33,8 +33,6 @@ import jakarta.servlet.descriptor.JspPropertyGroupDescriptor;
import jakarta.servlet.descriptor.TaglibDescriptor;
import org.eclipse.jetty.ee9.annotations.AnnotationConfiguration;
import org.eclipse.jetty.ee9.nested.ServletConstraint;
import org.eclipse.jetty.ee9.plus.annotation.LifeCycleCallback;
import org.eclipse.jetty.ee9.plus.annotation.LifeCycleCallbackCollection;
import org.eclipse.jetty.ee9.security.Authenticator;
import org.eclipse.jetty.ee9.security.ConstraintAware;
import org.eclipse.jetty.ee9.security.ConstraintMapping;
@ -57,6 +55,8 @@ import org.eclipse.jetty.ee9.webapp.MetaInfConfiguration;
import org.eclipse.jetty.ee9.webapp.WebAppContext;
import org.eclipse.jetty.ee9.webapp.WebInfConfiguration;
import org.eclipse.jetty.http.MimeTypes;
import org.eclipse.jetty.plus.annotation.LifeCycleCallback;
import org.eclipse.jetty.plus.annotation.LifeCycleCallbackCollection;
import org.eclipse.jetty.util.QuotedStringTokenizer;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.resource.AttributeNormalizer;

View File

@ -26,7 +26,7 @@ import org.eclipse.jetty.client.AuthenticationStore;
import org.eclipse.jetty.client.BasicAuthentication;
import org.eclipse.jetty.client.ContentResponse;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.ee9.plus.security.DataSourceLoginService;
import org.eclipse.jetty.plus.security.DataSourceLoginService;
import org.eclipse.jetty.toolchain.test.FS;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.eclipse.jetty.util.Loader;