This is an automated email from the ASF dual-hosted git repository.
rgoers pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
The following commit(s) were added to refs/heads/master by this push:
new 5370298 LOG4J2-3307 - Move scripting to its own module
5370298 is described below
commit 5370298f3a549a3502a585e2de997a97101e651a
Author: Ralph Goers <[email protected]>
AuthorDate: Sat Jan 1 21:03:42 2022 -0700
LOG4J2-3307 - Move scripting to its own module
---
log4j-api/src/main/java/module-info.java | 2 +-
.../apache/logging/log4j/util/ProviderUtil.java | 23 +-
.../logging/log4j/util/ServiceLoaderUtil.java | 69 ++++++
log4j-core-test/pom.xml | 26 --
.../rolling/action/DummyFileAttributes.java | 2 +-
log4j-core-test/src/main/java9/module-info.java | 1 +
.../rolling/action/IfAccumulatedFileSizeTest.java | 1 +
.../rolling/action/IfLastModifiedTest.java | 1 +
.../action/PathSortByModificationTimeTest.java | 1 +
.../log4j/core/config/TestConfigurator.java | 39 +--
log4j-core-test/src/test/java9/module-info.java | 1 -
log4j-core/src/main/java/module-info.java | 35 +--
.../core/appender/rolling/action/DeleteAction.java | 7 +-
.../log4j/core/appender/routing/Routes.java | 18 +-
.../core/appender/routing/RoutingAppender.java | 18 +-
.../log4j/core/config/AbstractConfiguration.java | 20 +-
.../core/config/plugins/util/PluginBuilder.java | 9 +-
.../apache/logging/log4j/core/script/Script.java | 43 +---
.../{package-info.java => ScriptBindings.java} | 11 +-
.../{package-info.java => ScriptConditional.java} | 13 +-
.../logging/log4j/core/script/ScriptManager.java | 270 +--------------------
...package-info.java => ScriptManagerFactory.java} | 12 +-
log4j-jpl/pom.xml | 7 +-
log4j-jpl/src/main/java/module-info.java | 1 +
log4j-plugins/src/main/java/module-info.java | 3 +-
.../logging/log4j/plugins/util/PluginRegistry.java | 12 +-
.../logging/log4j/plugins/util/PluginType.java | 4 +
.../log4j/plugins/validation/PluginValidator.java | 21 +-
.../validation/constraints/RequiredClass.java | 49 ++++
.../validation/constraints/RequiredProperty.java | 51 ++++
.../validators/RequiredClassValidator.java | 61 +++++
.../validators/RequiredPropertyValidator.java | 65 +++++
log4j-script/pom.xml | 27 +++
log4j-script/src/main/java/module-info.java | 36 +++
.../logging/log4j}/script/AbstractScript.java | 4 +-
.../apache/logging/log4j}/script/ScriptFile.java | 2 +-
.../logging/log4j/script/ScriptManagerImpl.java | 70 ++++--
.../apache/logging/log4j/script/ScriptPlugin.java | 12 +-
.../apache/logging/log4j}/script/ScriptRef.java | 8 +-
.../logging/log4j/script}/ScriptsPlugin.java | 3 +-
.../script}/appender/ScriptAppenderSelector.java | 26 +-
.../appender/rolling/action/ScriptCondition.java | 21 +-
.../script/config/arbiter}/ScriptArbiter.java | 23 +-
.../script/factory/ScriptManagerFactoryImpl.java | 19 +-
.../logging/log4j/script}/filter/ScriptFilter.java | 28 ++-
.../script}/layout/ScriptPatternSelector.java | 13 +-
.../apache/logging/log4j}/script/package-info.java | 2 +-
....logging.log4j.core.script.ScriptManagerFactory | 1 +
.../appender/ScriptAppenderSelectorTest.java | 2 +-
.../RollingAppenderDeleteScriptFri13thTest.java | 2 +-
.../rolling/RollingAppenderDeleteScriptTest.java | 2 +-
.../rolling/action/ScriptConditionTest.java | 16 +-
.../routing/DefaultRouteScriptAppenderTest.java | 3 +-
.../appender/routing/RoutesScriptAppenderTest.java | 12 +-
.../log4j/script/config/TestConfigurator.java | 79 ++++++
.../script/config/arbiter}/ScriptArbiterTest.java | 2 +-
.../script}/filter/AbstractScriptFilterTest.java | 2 +-
.../filter/ScriptFileFilterPropertiesTest.java | 2 +-
.../log4j/script}/filter/ScriptFileFilterTest.java | 2 +-
.../log4j/script}/filter/ScriptFilterTest.java | 2 +-
.../log4j/script}/filter/ScriptRefFilterTest.java | 2 +-
.../log4j/script/layout}/PatternSelectorTest.java | 12 +-
.../resources/log4j-appender-selector-groovy.xml | 0
.../log4j-appender-selector-javascript.xml | 0
.../src/test/resources/log4j-patternSelector.xml | 0
...j-rolling-with-custom-delete-script-fri13th.xml | 0
.../log4j-rolling-with-custom-delete-script.xml | 0
.../log4j-routing-default-route-script-groovy.xml | 0
...g4j-routing-default-route-script-javascript.xml | 0
.../log4j-routing-routes-script-groovy.xml | 0
.../log4j-routing-routes-script-javascript.xml | 0
.../log4j-routing-script-staticvars-groovy.xml | 0
.../log4j-routing-script-staticvars-javascript.xml | 0
.../src/test/resources/log4j-script-filters.xml | 0
.../resources/log4j-scriptFile-filters.properties | 0
.../test/resources/log4j-scriptFile-filters.xml | 0
.../src/test/resources/log4j-scriptRef-filters.xml | 0
.../src/test/resources/log4j2-scriptArbiters.xml | 0
.../src/test/resources/scripts/filter.groovy | 2 +
.../src/test/resources/scripts/filter.js | 0
pom.xml | 1 +
src/changes/changes.xml | 3 +
src/site/asciidoc/manual/appenders.adoc | 2 +-
src/site/asciidoc/manual/filters.adoc | 2 +-
84 files changed, 777 insertions(+), 564 deletions(-)
diff --git a/log4j-api/src/main/java/module-info.java
b/log4j-api/src/main/java/module-info.java
index b74edd7..d2c9490 100644
--- a/log4j-api/src/main/java/module-info.java
+++ b/log4j-api/src/main/java/module-info.java
@@ -22,7 +22,7 @@ module org.apache.logging.log4j {
exports org.apache.logging.log4j.status;
exports org.apache.logging.log4j.util;
- requires transitive org.osgi.framework;
+ requires static org.osgi.framework;
uses org.apache.logging.log4j.spi.Provider;
uses org.apache.logging.log4j.util.PropertySource;
uses org.apache.logging.log4j.message.ThreadDumpMessage.ThreadInfoFactory;
diff --git
a/log4j-api/src/main/java/org/apache/logging/log4j/util/ProviderUtil.java
b/log4j-api/src/main/java/org/apache/logging/log4j/util/ProviderUtil.java
index 0a01886..5651dcd 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/util/ProviderUtil.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/util/ProviderUtil.java
@@ -62,13 +62,9 @@ public final class ProviderUtil {
private static volatile ProviderUtil instance;
private ProviderUtil() {
- for (final ClassLoader classLoader : LoaderUtil.getClassLoaders()) {
- try {
- loadProviders(classLoader);
- } catch (final Throwable ex) {
- LOGGER.debug("Unable to retrieve provider from ClassLoader
{}", classLoader, ex);
- }
- }
+ PROVIDERS.addAll(ServiceLoaderUtil.loadServices(Provider.class,
+ (layer) -> ServiceLoader.load(layer, Provider.class),
+ (provider) -> validVersion(provider.getVersions())));
for (final LoaderUtil.UrlResource resource :
LoaderUtil.findUrlResources(PROVIDER_RESOURCE)) {
loadProvider(resource.getUrl(), resource.getClassLoader());
}
@@ -99,19 +95,6 @@ public final class ProviderUtil {
}
}
- /**
- *
- * @param classLoader null can be used to mark the bootstrap class loader.
- */
- protected static void loadProviders(final ClassLoader classLoader) {
- final ServiceLoader<Provider> serviceLoader =
ServiceLoader.load(Provider.class, classLoader);
- for (final Provider provider : serviceLoader) {
- if (validVersion(provider.getVersions()) &&
!PROVIDERS.contains(provider)) {
- PROVIDERS.add(provider);
- }
- }
- }
-
public static Iterable<Provider> getProviders() {
lazyInit();
return PROVIDERS;
diff --git
a/log4j-api/src/main/java/org/apache/logging/log4j/util/ServiceLoaderUtil.java
b/log4j-api/src/main/java/org/apache/logging/log4j/util/ServiceLoaderUtil.java
new file mode 100644
index 0000000..785291b
--- /dev/null
+++
b/log4j-api/src/main/java/org/apache/logging/log4j/util/ServiceLoaderUtil.java
@@ -0,0 +1,69 @@
+/*
+ * 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.logging.log4j.util;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.ServiceLoader;
+import java.util.function.Function;
+
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.status.StatusLogger;
+
+/**
+ * Loads all valid instances of a service.
+ */
+public class ServiceLoaderUtil {
+ private static final Logger LOGGER = StatusLogger.getLogger();
+
+ public static <S> List<S> loadServices(final Class<S> clazz,
Function<ModuleLayer, ServiceLoader<S>> loader,
+ Function<S, Boolean> validator) {
+ final List<S> services = new ArrayList<>();
+ final ModuleLayer moduleLayer =
ServiceLoaderUtil.class.getModule().getLayer();
+ if (moduleLayer == null) {
+ final ClassLoader[] classLoaders = LoaderUtil.getClassLoaders();
+ Throwable throwable = null;
+ ClassLoader errorClassLoader = null;
+ for (ClassLoader classLoader : classLoaders) {
+ try {
+ final ServiceLoader<S> serviceLoader =
ServiceLoader.load(clazz, classLoader);
+ for (final S service : serviceLoader) {
+ if (!services.contains(service) && (validator == null
|| validator.apply(service))) {
+ services.add(service);
+ }
+ }
+ } catch (final Throwable ex) {
+ if (throwable == null) {
+ throwable = ex;
+ errorClassLoader = classLoader;
+ }
+ }
+ }
+ if (services.size() == 0 && throwable != null) {
+ LOGGER.debug("Unable to retrieve provider from ClassLoader
{}", errorClassLoader, throwable);
+ }
+ } else {
+ final ServiceLoader<S> serviceLoader = loader.apply(moduleLayer);
+ for (final S service : serviceLoader) {
+ if (!services.contains(service) && (validator == null ||
validator.apply(service))) {
+ services.add(service);
+ }
+ }
+ }
+ return services;
+ }
+}
diff --git a/log4j-core-test/pom.xml b/log4j-core-test/pom.xml
index a580e32..1b28951 100644
--- a/log4j-core-test/pom.xml
+++ b/log4j-core-test/pom.xml
@@ -262,38 +262,12 @@
<scope>test</scope>
</dependency>
<dependency>
- <groupId>org.apache-extras.beanshell</groupId>
- <artifactId>bsh</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
<groupId>org.graalvm.truffle</groupId>
<artifactId>truffle-api</artifactId>
<version>21.3.0</version>
<scope>test</scope>
</dependency>
<dependency>
- <groupId>org.openjdk.nashorn</groupId>
- <artifactId>nashorn-core</artifactId>
- <version>15.3</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.codehaus.groovy</groupId>
- <artifactId>groovy</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.codehaus.groovy</groupId>
- <artifactId>groovy-jsr223</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.codehaus.groovy</groupId>
- <artifactId>groovy-dateutil</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
<groupId>org.hdrhistogram</groupId>
<artifactId>HdrHistogram</artifactId>
<scope>test</scope>
diff --git
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/DummyFileAttributes.java
b/log4j-core-test/src/main/java/org/apache/logging/log4j/core/test/appender/rolling/action/DummyFileAttributes.java
similarity index 96%
rename from
log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/DummyFileAttributes.java
rename to
log4j-core-test/src/main/java/org/apache/logging/log4j/core/test/appender/rolling/action/DummyFileAttributes.java
index c2bbb1b..9c14230 100644
---
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/DummyFileAttributes.java
+++
b/log4j-core-test/src/main/java/org/apache/logging/log4j/core/test/appender/rolling/action/DummyFileAttributes.java
@@ -15,7 +15,7 @@
* limitations under the license.
*/
-package org.apache.logging.log4j.core.appender.rolling.action;
+package org.apache.logging.log4j.core.test.appender.rolling.action;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileTime;
diff --git a/log4j-core-test/src/main/java9/module-info.java
b/log4j-core-test/src/main/java9/module-info.java
index 1479ae2..f84c4ac 100644
--- a/log4j-core-test/src/main/java9/module-info.java
+++ b/log4j-core-test/src/main/java9/module-info.java
@@ -17,6 +17,7 @@
module org.apache.logging.log4j.core.test {
exports org.apache.logging.log4j.core.test;
exports org.apache.logging.log4j.core.test.appender;
+ exports org.apache.logging.log4j.core.test.appender.rolling.action;
exports org.apache.logging.log4j.core.test.categories;
exports org.apache.logging.log4j.core.test.hamcrest;
exports org.apache.logging.log4j.core.test.junit;
diff --git
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/IfAccumulatedFileSizeTest.java
b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/IfAccumulatedFileSizeTest.java
index 76bb0fc..70ff7ba 100644
---
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/IfAccumulatedFileSizeTest.java
+++
b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/IfAccumulatedFileSizeTest.java
@@ -17,6 +17,7 @@
package org.apache.logging.log4j.core.appender.rolling.action;
+import
org.apache.logging.log4j.core.test.appender.rolling.action.DummyFileAttributes;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
diff --git
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/IfLastModifiedTest.java
b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/IfLastModifiedTest.java
index b6f177c..21a29a7 100644
---
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/IfLastModifiedTest.java
+++
b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/IfLastModifiedTest.java
@@ -19,6 +19,7 @@ package org.apache.logging.log4j.core.appender.rolling.action;
import java.nio.file.attribute.FileTime;
+import
org.apache.logging.log4j.core.test.appender.rolling.action.DummyFileAttributes;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
diff --git
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/PathSortByModificationTimeTest.java
b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/PathSortByModificationTimeTest.java
index 3893378..84afb62 100644
---
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/PathSortByModificationTimeTest.java
+++
b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/PathSortByModificationTimeTest.java
@@ -21,6 +21,7 @@ import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.FileTime;
+import
org.apache.logging.log4j.core.test.appender.rolling.action.DummyFileAttributes;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
diff --git
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/config/TestConfigurator.java
b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/config/TestConfigurator.java
index c592236..7b16ff6 100644
---
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/config/TestConfigurator.java
+++
b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/config/TestConfigurator.java
@@ -443,43 +443,6 @@ public class TestConfigurator {
}
- @Test
- public void testBuilderWithScripts() throws Exception {
- final String script = "if
(logEvent.getLoggerName().equals(\"NoLocation\")) {\n" +
- " return \"NoLocation\";\n" +
- " } else if (logEvent.getMarker() != null &&
logEvent.getMarker().isInstanceOf(\"FLOW\")) {\n" +
- " return \"Flow\";\n" +
- " } else {\n" +
- " return null;\n" +
- " }";
- final ConfigurationBuilder<BuiltConfiguration> builder =
ConfigurationBuilderFactory.newConfigurationBuilder();
- builder.setStatusLevel(Level.ERROR);
- builder.setConfigurationName("BuilderTest");
- builder.add(builder.newScriptFile("filter.groovy",
"target/test-classes/scripts/filter.groovy").addIsWatched(true));
- final AppenderComponentBuilder appenderBuilder =
builder.newAppender("Stdout", "CONSOLE").addAttribute("target",
- ConsoleAppender.Target.SYSTEM_OUT);
- appenderBuilder.add(builder.newLayout("PatternLayout").
- addComponent(builder.newComponent("ScriptPatternSelector")
- .addAttribute("defaultPattern", "[%-5level] %c{1.}
%C{1.}.%M.%L %msg%n")
-
.addComponent(builder.newComponent("PatternMatch").addAttribute("key",
"NoLocation")
- .addAttribute("pattern", "[%-5level] %c{1.}
%msg%n"))
-
.addComponent(builder.newComponent("PatternMatch").addAttribute("key", "FLOW")
- .addAttribute("pattern", "[%-5level] %c{1.}
====== %C{1.}.%M:%L %msg ======%n"))
- .addComponent(builder.newComponent("selectorScript",
"Script", script).addAttribute("language", "beanshell"))));
- appenderBuilder.add(builder.newFilter("ScriptFilter",
Filter.Result.DENY,
-
Filter.Result.NEUTRAL).addComponent(builder.newComponent("ScriptRef").addAttribute("ref",
"filter.groovy")));
- builder.add(appenderBuilder);
- builder.add(builder.newLogger("org.apache.logging.log4j", Level.DEBUG).
- add(builder.newAppenderRef("Stdout")).
- addAttribute("additivity", false));
-
builder.add(builder.newRootLogger(Level.ERROR).add(builder.newAppenderRef("Stdout")));
- ctx = Configurator.initialize(builder.build());
- final Configuration config = ctx.getConfiguration();
- assertNotNull(config, "No configuration");
- assertEquals("BuilderTest", config.getName(), "Unexpected
Configuration");
- assertThat(config.getAppenders(), hasSize(equalTo(1)));
- assertNotNull(config.getScriptManager().getScript("filter.groovy"),
"Filter script not found");
- assertNotNull(config.getScriptManager().getScript("selectorScript"),
"pattern selector script not found");
- }
+
}
diff --git a/log4j-core-test/src/test/java9/module-info.java
b/log4j-core-test/src/test/java9/module-info.java
index d02fec4..03a6eac 100644
--- a/log4j-core-test/src/test/java9/module-info.java
+++ b/log4j-core-test/src/test/java9/module-info.java
@@ -60,7 +60,6 @@ open module org.apache.logging.log4j.core {
requires transitive java.management;
requires transitive java.sql;
requires transitive java.rmi;
- requires transitive java.scripting;
requires transitive java.xml;
requires transitive org.apache.logging.log4j;
requires transitive org.apache.logging.log4j.test;
diff --git a/log4j-core/src/main/java/module-info.java
b/log4j-core/src/main/java/module-info.java
index d4b3d93..cb34b89 100644
--- a/log4j-core/src/main/java/module-info.java
+++ b/log4j-core/src/main/java/module-info.java
@@ -60,27 +60,28 @@ module org.apache.logging.log4j.core {
exports org.apache.logging.log4j.core.util;
exports org.apache.logging.log4j.core.util.datetime;
- requires transitive java.desktop;
- requires transitive java.management;
- requires transitive java.naming;
- requires transitive java.sql;
- requires transitive java.rmi;
- requires transitive java.scripting;
- requires transitive java.xml;
+ // Required Dependenceis
requires transitive org.apache.logging.log4j;
requires transitive org.apache.logging.log4j.plugins;
- requires transitive com.lmax.disruptor;
- requires transitive org.jctools.core;
- requires transitive org.osgi.framework;
- requires transitive com.conversantmedia.disruptor;
- requires transitive com.fasterxml.jackson.core;
- requires transitive com.fasterxml.jackson.databind;
- requires transitive com.fasterxml.jackson.dataformat.xml;
- requires transitive com.fasterxml.jackson.dataformat.yaml;
- requires transitive org.apache.commons.compress;
- requires transitive org.fusesource.jansi;
+ // Optional Despendencies
+ requires static java.desktop;
+ requires static java.management;
+ requires static java.sql;
+ requires static java.rmi;
+ requires static java.xml;
+ requires static com.lmax.disruptor;
+ requires static org.jctools.core;
+ requires static org.osgi.framework;
+ requires static com.conversantmedia.disruptor;
+ requires static com.fasterxml.jackson.core;
+ requires static com.fasterxml.jackson.databind;
+ requires static com.fasterxml.jackson.dataformat.xml;
+ requires static com.fasterxml.jackson.dataformat.yaml;
+ requires static org.apache.commons.compress;
+ requires static org.fusesource.jansi;
uses org.apache.logging.log4j.core.util.ContextDataProvider;
uses org.apache.logging.log4j.core.util.WatchEventService;
+ uses org.apache.logging.log4j.core.script.ScriptManagerFactory;
provides
org.apache.logging.log4j.message.ThreadDumpMessage.ThreadInfoFactory with
org.apache.logging.log4j.core.message.ExtendedThreadInfoFactory;
provides org.apache.logging.log4j.core.util.ContextDataProvider with
org.apache.logging.log4j.core.impl.ThreadContextDataProvider;
provides org.apache.logging.log4j.spi.Provider with
org.apache.logging.log4j.core.impl.Log4jProvider;
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/DeleteAction.java
b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/DeleteAction.java
index c51c715..11ba5fb 100644
---
a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/DeleteAction.java
+++
b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/DeleteAction.java
@@ -26,6 +26,7 @@ import java.util.Objects;
import org.apache.logging.log4j.core.Core;
import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.core.script.ScriptConditional;
import org.apache.logging.log4j.plugins.Plugin;
import org.apache.logging.log4j.plugins.PluginAttribute;
import org.apache.logging.log4j.core.config.plugins.PluginConfiguration;
@@ -41,7 +42,7 @@ public class DeleteAction extends AbstractPathAction {
private final PathSorter pathSorter;
private final boolean testMode;
- private final ScriptCondition scriptCondition;
+ private final ScriptConditional scriptCondition;
/**
* Creates a new DeleteAction that starts scanning for files to delete
from the specified base path.
@@ -60,7 +61,7 @@ public class DeleteAction extends AbstractPathAction {
* @param scriptCondition
*/
DeleteAction(final String basePath, final boolean followSymbolicLinks,
final int maxDepth, final boolean testMode,
- final PathSorter sorter, final PathCondition[] pathConditions,
final ScriptCondition scriptCondition,
+ final PathSorter sorter, final PathCondition[] pathConditions,
final ScriptConditional scriptCondition,
final StrSubstitutor subst) {
super(basePath, followSymbolicLinks, maxDepth, pathConditions, subst);
this.testMode = testMode;
@@ -203,7 +204,7 @@ public class DeleteAction extends AbstractPathAction {
@PluginAttribute final boolean testMode,
@PluginElement final PathSorter sorterParameter,
@PluginElement final PathCondition[] pathConditions,
- @PluginElement final ScriptCondition scriptCondition,
+ @PluginElement final ScriptConditional scriptCondition,
@PluginConfiguration final Configuration config) {
// @formatter:on
final PathSorter sorter = sorterParameter == null ? new
PathSortByModificationTime(true) : sorterParameter;
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/routing/Routes.java
b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/routing/Routes.java
index a7e0813..7355e2a 100644
---
a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/routing/Routes.java
+++
b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/routing/Routes.java
@@ -21,7 +21,8 @@ import org.apache.logging.log4j.core.Core;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.plugins.PluginConfiguration;
-import org.apache.logging.log4j.core.script.AbstractScript;
+import org.apache.logging.log4j.core.script.Script;
+import org.apache.logging.log4j.core.script.ScriptBindings;
import org.apache.logging.log4j.core.script.ScriptManager;
import org.apache.logging.log4j.plugins.Plugin;
import org.apache.logging.log4j.plugins.PluginAttribute;
@@ -30,7 +31,6 @@ import org.apache.logging.log4j.plugins.PluginFactory;
import org.apache.logging.log4j.plugins.validation.constraints.Required;
import org.apache.logging.log4j.status.StatusLogger;
-import javax.script.Bindings;
import java.util.Objects;
import java.util.concurrent.ConcurrentMap;
@@ -53,7 +53,7 @@ public final class Routes {
private String pattern;
@PluginElement("Script")
- private AbstractScript patternScript;
+ private Script patternScript;
@PluginElement
@Required
@@ -86,7 +86,7 @@ public final class Routes {
return pattern;
}
- public AbstractScript getPatternScript() {
+ public Script getPatternScript() {
return patternScript;
}
@@ -104,7 +104,7 @@ public final class Routes {
return this;
}
- public Builder setPatternScript(@SuppressWarnings("hiding") final
AbstractScript patternScript) {
+ public Builder setPatternScript(@SuppressWarnings("hiding") final
Script patternScript) {
this.patternScript = patternScript;
return this;
}
@@ -127,12 +127,12 @@ public final class Routes {
private final String pattern;
- private final AbstractScript patternScript;
+ private final Script patternScript;
// TODO Why not make this a Map or add a Map.
private final Route[] routes;
- private Routes(final Configuration configuration, final AbstractScript
patternScript, final String pattern, final Route... routes) {
+ private Routes(final Configuration configuration, final Script
patternScript, final String pattern, final Route... routes) {
this.configuration = configuration;
this.patternScript = patternScript;
this.pattern = pattern;
@@ -148,7 +148,7 @@ public final class Routes {
public String getPattern(final LogEvent event, final ConcurrentMap<Object,
Object> scriptStaticVariables) {
if (patternScript != null) {
final ScriptManager scriptManager =
configuration.getScriptManager();
- final Bindings bindings =
scriptManager.createBindings(patternScript);
+ final ScriptBindings bindings =
scriptManager.createBindings(patternScript);
bindings.put(STATIC_VARIABLES_KEY, scriptStaticVariables);
bindings.put(LOG_EVENT_KEY, event);
final Object object =
scriptManager.execute(patternScript.getName(), bindings);
@@ -162,7 +162,7 @@ public final class Routes {
* Gets the optional script that decides which route to pick.
* @return the optional script that decides which route to pick. May be
null.
*/
- public AbstractScript getPatternScript() {
+ public Script getPatternScript() {
return patternScript;
}
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/routing/RoutingAppender.java
b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/routing/RoutingAppender.java
index a1e9051..584eadd 100644
---
a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/routing/RoutingAppender.java
+++
b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/routing/RoutingAppender.java
@@ -25,14 +25,14 @@ import
org.apache.logging.log4j.core.appender.rewrite.RewritePolicy;
import org.apache.logging.log4j.core.config.AppenderControl;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.Property;
-import org.apache.logging.log4j.core.script.AbstractScript;
+import org.apache.logging.log4j.core.script.Script;
+import org.apache.logging.log4j.core.script.ScriptBindings;
import org.apache.logging.log4j.core.script.ScriptManager;
import org.apache.logging.log4j.plugins.Node;
import org.apache.logging.log4j.plugins.Plugin;
import org.apache.logging.log4j.plugins.PluginElement;
import org.apache.logging.log4j.plugins.PluginFactory;
-import javax.script.Bindings;
import java.util.Collections;
import java.util.Map;
import java.util.Objects;
@@ -59,7 +59,7 @@ public final class RoutingAppender extends AbstractAppender {
// Does not work unless the element is called "Script", I wanted
"DefaultRounteScript"...
@PluginElement("Script")
- private AbstractScript defaultRouteScript;
+ private Script defaultRouteScript;
@PluginElement("Routes")
private Routes routes;
@@ -92,7 +92,7 @@ public final class RoutingAppender extends AbstractAppender {
return routes;
}
- public AbstractScript getDefaultRouteScript() {
+ public Script getDefaultRouteScript() {
return defaultRouteScript;
}
@@ -113,7 +113,7 @@ public final class RoutingAppender extends AbstractAppender
{
return asBuilder();
}
- public B setDefaultRouteScript(@SuppressWarnings("hiding") final
AbstractScript defaultRouteScript) {
+ public B setDefaultRouteScript(@SuppressWarnings("hiding") final
Script defaultRouteScript) {
this.defaultRouteScript = defaultRouteScript;
return asBuilder();
}
@@ -151,13 +151,13 @@ public final class RoutingAppender extends
AbstractAppender {
private final ConcurrentMap<String, RouteAppenderControl>
referencedAppenders = new ConcurrentHashMap<>();
private final RewritePolicy rewritePolicy;
private final PurgePolicy purgePolicy;
- private final AbstractScript defaultRouteScript;
+ private final Script defaultRouteScript;
private final ConcurrentMap<Object, Object> scriptStaticVariables = new
ConcurrentHashMap<>();
private final Boolean requiresLocation;
private RoutingAppender(final String name, final Filter filter, final
boolean ignoreExceptions, final Routes routes,
final RewritePolicy rewritePolicy, final Configuration
configuration, final PurgePolicy purgePolicy,
- final AbstractScript defaultRouteScript, final Property[]
properties, final Boolean requiresLocation) {
+ final Script defaultRouteScript, final Property[] properties,
final Boolean requiresLocation) {
super(name, filter, null, ignoreExceptions, properties);
this.routes = routes;
this.configuration = configuration;
@@ -189,7 +189,7 @@ public final class RoutingAppender extends AbstractAppender
{
} else {
final ScriptManager scriptManager =
configuration.getScriptManager();
scriptManager.addScript(defaultRouteScript);
- final Bindings bindings =
scriptManager.createBindings(defaultRouteScript);
+ final ScriptBindings bindings =
scriptManager.createBindings(defaultRouteScript);
bindings.put(STATIC_VARIABLES_KEY, scriptStaticVariables);
final Object object =
scriptManager.execute(defaultRouteScript.getName(), bindings);
final Route route = routes.getRoute(Objects.toString(object,
null));
@@ -365,7 +365,7 @@ public final class RoutingAppender extends AbstractAppender
{
return defaultRoute;
}
- public AbstractScript getDefaultRouteScript() {
+ public Script getDefaultRouteScript() {
return defaultRouteScript;
}
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/AbstractConfiguration.java
b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/AbstractConfiguration.java
index 8c1217a..1f00a2c 100644
---
a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/AbstractConfiguration.java
+++
b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/AbstractConfiguration.java
@@ -30,6 +30,7 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
+import java.util.ServiceLoader;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
@@ -59,9 +60,8 @@ import org.apache.logging.log4j.core.lookup.MapLookup;
import org.apache.logging.log4j.core.lookup.StrLookup;
import org.apache.logging.log4j.core.lookup.StrSubstitutor;
import org.apache.logging.log4j.core.net.Advertiser;
-import org.apache.logging.log4j.core.script.AbstractScript;
import org.apache.logging.log4j.core.script.ScriptManager;
-import org.apache.logging.log4j.core.script.ScriptRef;
+import org.apache.logging.log4j.core.script.ScriptManagerFactory;
import org.apache.logging.log4j.core.util.Constants;
import org.apache.logging.log4j.core.time.internal.DummyNanoClock;
import org.apache.logging.log4j.core.util.Loader;
@@ -75,6 +75,7 @@ import org.apache.logging.log4j.plugins.Node;
import org.apache.logging.log4j.plugins.util.PluginManager;
import org.apache.logging.log4j.plugins.util.PluginType;
import org.apache.logging.log4j.util.PropertiesUtil;
+import org.apache.logging.log4j.util.ServiceLoaderUtil;
/**
* The base Configuration. Many configuration implementations will extend this
class.
@@ -219,7 +220,10 @@ public abstract class AbstractConfiguration extends
AbstractFilterable implement
LOGGER.debug(Version.getProductString() + " initializing configuration
{}", this);
subst.setConfiguration(this);
try {
- scriptManager = new ScriptManager(this, watchManager);
+ ServiceLoaderUtil.loadServices(ScriptManagerFactory.class,
+ (layer) -> ServiceLoader.load(layer,
ScriptManagerFactory.class),
+
null).stream().findFirst().ifPresent(scriptManagerFactory ->
+ scriptManager =
scriptManagerFactory.createScriptManager(this, watchManager));
} catch (final LinkageError | Exception e) {
// LOG4J2-1920 ScriptEngineManager is not available in Android
LOGGER.info("Cannot initialize scripting support because this JRE
does not support it.", e);
@@ -641,14 +645,8 @@ public abstract class AbstractConfiguration extends
AbstractFilterable implement
continue;
}
if (child.getName().equalsIgnoreCase("Scripts")) {
- for (final AbstractScript script :
child.getObject(AbstractScript[].class)) {
- if (script instanceof ScriptRef) {
- LOGGER.error("Script reference to {} not added.
Scripts definition cannot contain script references",
- script.getName());
- } else {
- if (scriptManager != null) {
- scriptManager.addScript(script);
- }}
+ if (scriptManager != null) {
+ scriptManager.addScripts(child);
}
} else if (child.getName().equalsIgnoreCase("Appenders")) {
appenders = child.getObject();
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/util/PluginBuilder.java
b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/util/PluginBuilder.java
index dd98827..a59bb5f 100644
---
a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/util/PluginBuilder.java
+++
b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/util/PluginBuilder.java
@@ -31,6 +31,7 @@ import
org.apache.logging.log4j.plugins.inject.ConfigurationInjector;
import org.apache.logging.log4j.plugins.util.Builder;
import org.apache.logging.log4j.plugins.util.PluginType;
import org.apache.logging.log4j.plugins.util.TypeUtil;
+import org.apache.logging.log4j.plugins.validation.PluginValidator;
import org.apache.logging.log4j.status.StatusLogger;
import org.apache.logging.log4j.util.ReflectionUtil;
import org.apache.logging.log4j.util.StringBuilders;
@@ -116,8 +117,14 @@ public class PluginBuilder implements Builder<Object> {
@Override
public Object build() {
verify();
+ Class<?> pluginClass = pluginType.getPluginClass();
+ if (!PluginValidator.validatePlugin(pluginClass,
pluginType.getElementName())) {
+ LOGGER.error("Could not create plugin builder for plugin {} due to
constraint violations",
+ pluginType.getElementName());
+ return null;
+ }
LOGGER.debug("Building Plugin[name={}, class={}].",
pluginType.getElementName(),
- pluginType.getPluginClass().getName());
+ pluginClass.getName());
substitutor = new Substitutor(event);
// first try to use a builder class if one is available
try {
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/script/Script.java
b/log4j-core/src/main/java/org/apache/logging/log4j/core/script/Script.java
index b51eb37..2e4fa13 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/script/Script.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/script/Script.java
@@ -16,47 +16,14 @@
*/
package org.apache.logging.log4j.core.script;
-import org.apache.logging.log4j.plugins.Node;
-import org.apache.logging.log4j.plugins.Plugin;
-import org.apache.logging.log4j.plugins.PluginAttribute;
-import org.apache.logging.log4j.plugins.PluginFactory;
-import org.apache.logging.log4j.plugins.PluginValue;
-
/**
- * Container for the language and body of a script.
+ * Represents int
*/
-@Plugin(name = Script.PLUGIN_NAME, category = Node.CATEGORY, printObject =
true)
-public class Script extends AbstractScript {
-
- private static final String ATTR_LANGUAGE = "language";
- private static final String ATTR_SCRIPT_TEXT = "scriptText";
- static final String PLUGIN_NAME = "Script";
-
- public Script(final String name, final String language, final String
scriptText) {
- super(name, language, scriptText);
- }
+public interface Script {
- @PluginFactory
- public static Script createScript(
- // @formatter:off
- @PluginAttribute final String name,
- @PluginAttribute String language,
- @PluginValue final String scriptText) {
- // @formatter:on
- if (language == null) {
- LOGGER.error("No '{}' attribute provided for {} plugin '{}'",
ATTR_LANGUAGE, PLUGIN_NAME, name);
- language = DEFAULT_LANGUAGE;
- }
- if (scriptText == null) {
- LOGGER.error("No '{}' attribute provided for {} plugin '{}'",
ATTR_SCRIPT_TEXT, PLUGIN_NAME, name);
- return null;
- }
- return new Script(name, language, scriptText);
+ String getLanguage();
- }
+ String getScriptText();
- @Override
- public String toString() {
- return getName() != null ? getName() : super.toString();
- }
+ String getName();
}
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/script/package-info.java
b/log4j-core/src/main/java/org/apache/logging/log4j/core/script/ScriptBindings.java
similarity index 86%
copy from
log4j-core/src/main/java/org/apache/logging/log4j/core/script/package-info.java
copy to
log4j-core/src/main/java/org/apache/logging/log4j/core/script/ScriptBindings.java
index 4964b30..181b03d 100644
---
a/log4j-core/src/main/java/org/apache/logging/log4j/core/script/package-info.java
+++
b/log4j-core/src/main/java/org/apache/logging/log4j/core/script/ScriptBindings.java
@@ -14,7 +14,14 @@
* See the license for the specific language governing permissions and
* limitations under the license.
*/
+package org.apache.logging.log4j.core.script;
+
+import java.util.Map;
+
/**
- * Log4j 2 Script support.
+ * Container for javax.script.Bindings.
*/
-package org.apache.logging.log4j.core.script;
+public interface ScriptBindings extends Map<String, Object> {
+
+
+}
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/script/package-info.java
b/log4j-core/src/main/java/org/apache/logging/log4j/core/script/ScriptConditional.java
similarity index 72%
copy from
log4j-core/src/main/java/org/apache/logging/log4j/core/script/package-info.java
copy to
log4j-core/src/main/java/org/apache/logging/log4j/core/script/ScriptConditional.java
index 4964b30..d00cddd 100644
---
a/log4j-core/src/main/java/org/apache/logging/log4j/core/script/package-info.java
+++
b/log4j-core/src/main/java/org/apache/logging/log4j/core/script/ScriptConditional.java
@@ -14,7 +14,16 @@
* See the license for the specific language governing permissions and
* limitations under the license.
*/
+package org.apache.logging.log4j.core.script;
+
+import java.nio.file.Path;
+import java.util.List;
+
+import
org.apache.logging.log4j.core.appender.rolling.action.PathWithAttributes;
+
/**
- * Log4j 2 Script support.
+ * Interface for the ScriptCondition plugin.
*/
-package org.apache.logging.log4j.core.script;
+public interface ScriptConditional {
+ List<PathWithAttributes> selectFilesToDelete(final Path basePath, final
List<PathWithAttributes> candidates);
+}
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/script/ScriptManager.java
b/log4j-core/src/main/java/org/apache/logging/log4j/core/script/ScriptManager.java
index 43c4f85..297426a 100644
---
a/log4j-core/src/main/java/org/apache/logging/log4j/core/script/ScriptManager.java
+++
b/log4j-core/src/main/java/org/apache/logging/log4j/core/script/ScriptManager.java
@@ -16,269 +16,23 @@
*/
package org.apache.logging.log4j.core.script;
-import java.io.File;
-import java.io.Serializable;
-import java.nio.file.Path;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.List;
-import java.util.Objects;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
-import javax.script.Bindings;
-import javax.script.Compilable;
-import javax.script.CompiledScript;
-import javax.script.ScriptEngine;
-import javax.script.ScriptEngineFactory;
-import javax.script.ScriptEngineManager;
-import javax.script.ScriptException;
-import javax.script.SimpleBindings;
-
-import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.core.config.Configuration;
-import org.apache.logging.log4j.core.util.FileWatcher;
-import org.apache.logging.log4j.core.util.WatchManager;
-import org.apache.logging.log4j.status.StatusLogger;
-import org.apache.logging.log4j.util.Strings;
+import org.apache.logging.log4j.plugins.Node;
/**
- * Manages the scripts use by the Configuration.
+ * Class Description goes here.
*/
-public class ScriptManager implements FileWatcher, Serializable {
-
- private abstract class AbstractScriptRunner implements ScriptRunner {
-
- private static final String KEY_STATUS_LOGGER = "statusLogger";
- private static final String KEY_CONFIGURATION = "configuration";
-
- @Override
- public Bindings createBindings() {
- final SimpleBindings bindings = new SimpleBindings();
- bindings.put(KEY_CONFIGURATION, configuration);
- bindings.put(KEY_STATUS_LOGGER, logger);
- return bindings;
- }
-
- }
-
- private static final long serialVersionUID = -2534169384971965196L;
- private static final String KEY_THREADING = "THREADING";
- private static final Logger logger = StatusLogger.getLogger();
-
- private final Configuration configuration;
- private final ScriptEngineManager manager = new ScriptEngineManager();
- private final ConcurrentMap<String, ScriptRunner> scriptRunners = new
ConcurrentHashMap<>();
- private final String languages;
- private final WatchManager watchManager;
-
- public ScriptManager(final Configuration configuration, final WatchManager
watchManager) {
- this.configuration = configuration;
- this.watchManager = watchManager;
- final List<ScriptEngineFactory> factories =
manager.getEngineFactories();
- if (logger.isDebugEnabled()) {
- final StringBuilder sb = new StringBuilder();
- final int factorySize = factories.size();
- logger.debug("Installed {} script engine{}", factorySize,
factorySize != 1 ? "s" : Strings.EMPTY);
- for (final ScriptEngineFactory factory : factories) {
- String threading =
Objects.toString(factory.getParameter(KEY_THREADING), null);
- if (threading == null) {
- threading = "Not Thread Safe";
- }
- final StringBuilder names = new StringBuilder();
- final List<String> languageNames = factory.getNames();
- for (final String name : languageNames) {
- if (names.length() > 0) {
- names.append(", ");
- }
- names.append(name);
- }
- boolean compiled = false;
- try {
- compiled = factory.getScriptEngine() instanceof Compilable;
- logger.debug("{} version: {}, language: {}, threading: {},
compile: {}, names: {}, factory class: {}",
- factory.getEngineName(),
factory.getEngineVersion(), factory.getLanguageName(), threading,
- compiled, languageNames,
factory.getClass().getName());
- if (sb.length() > 0) {
- sb.append(", ");
- }
- sb.append(names);
- } catch (RuntimeException ex) {
- logger.warn("Error accessing scriptEngine for {}: {}",
factory.getEngineName(), ex.getMessage());
- }
-
- }
- languages = sb.toString();
- } else {
- final StringBuilder names = new StringBuilder();
- for (final ScriptEngineFactory factory : factories) {
- for (final String name : factory.getNames()) {
- if (names.length() > 0) {
- names.append(", ");
- }
- names.append(name);
- }
- }
- languages = names.toString();
- }
- }
-
- public void addScript(final AbstractScript script) {
- final ScriptEngine engine =
manager.getEngineByName(script.getLanguage());
- if (engine == null) {
- logger.error("No ScriptEngine found for language " +
script.getLanguage() + ". Available languages are: "
- + languages);
- return;
- }
- if (engine.getFactory().getParameter(KEY_THREADING) == null) {
- scriptRunners.put(script.getName(), new
ThreadLocalScriptRunner(script));
- } else {
- scriptRunners.put(script.getName(), new MainScriptRunner(engine,
script));
- }
-
- if (script instanceof ScriptFile) {
- final ScriptFile scriptFile = (ScriptFile) script;
- final Path path = scriptFile.getPath();
- if (scriptFile.isWatched() && path != null) {
- watchManager.watchFile(path.toFile(), this);
- }
- }
- }
-
- public Bindings createBindings(final AbstractScript script) {
- return getScriptRunner(script).createBindings();
- }
-
- public AbstractScript getScript(final String name) {
- final ScriptRunner runner = scriptRunners.get(name);
- return runner != null ? runner.getScript() : null;
- }
-
- @Override
- public void fileModified(final File file) {
- final ScriptRunner runner = scriptRunners.get(file.toString());
- if (runner == null) {
- logger.info("{} is not a running script", file.getName());
- return;
- }
- final ScriptEngine engine = runner.getScriptEngine();
- final AbstractScript script = runner.getScript();
- if (engine.getFactory().getParameter(KEY_THREADING) == null) {
- scriptRunners.put(script.getName(), new
ThreadLocalScriptRunner(script));
- } else {
- scriptRunners.put(script.getName(), new MainScriptRunner(engine,
script));
- }
-
- }
-
- public Object execute(final String name, final Bindings bindings) {
- final ScriptRunner scriptRunner = scriptRunners.get(name);
- if (scriptRunner == null) {
- logger.warn("No script named {} could be found", name);
- return null;
- }
- return AccessController.doPrivileged((PrivilegedAction<Object>) () ->
scriptRunner.execute(bindings));
- }
-
- private interface ScriptRunner {
-
- Bindings createBindings();
-
- Object execute(Bindings bindings);
-
- AbstractScript getScript();
-
- ScriptEngine getScriptEngine();
- }
-
- private class MainScriptRunner extends AbstractScriptRunner {
- private final AbstractScript script;
- private final CompiledScript compiledScript;
- private final ScriptEngine scriptEngine;
-
- public MainScriptRunner(final ScriptEngine scriptEngine, final
AbstractScript script) {
- this.script = script;
- this.scriptEngine = scriptEngine;
- CompiledScript compiled = null;
- if (scriptEngine instanceof Compilable) {
- logger.debug("Script {} is compilable", script.getName());
- compiled =
AccessController.doPrivileged((PrivilegedAction<CompiledScript>) () -> {
- try {
- return ((Compilable)
scriptEngine).compile(script.getScriptText());
- } catch (final Throwable ex) {
- /*
- * ScriptException is what really should be caught
here. However, beanshell's ScriptEngine
- * implements Compilable but then throws Error when
the compile method is called!
- */
- logger.warn("Error compiling script", ex);
- return null;
- }
- });
- }
- compiledScript = compiled;
- }
-
- @Override
- public ScriptEngine getScriptEngine() {
- return this.scriptEngine;
- }
-
- @Override
- public Object execute(final Bindings bindings) {
- if (compiledScript != null) {
- try {
- return compiledScript.eval(bindings);
- } catch (final ScriptException ex) {
- logger.error("Error running script " + script.getName(),
ex);
- return null;
- }
- }
- try {
- return scriptEngine.eval(script.getScriptText(), bindings);
- } catch (final ScriptException ex) {
- logger.error("Error running script " + script.getName(), ex);
- return null;
- }
- }
-
- @Override
- public AbstractScript getScript() {
- return script;
- }
- }
-
- private class ThreadLocalScriptRunner extends AbstractScriptRunner {
- private final AbstractScript script;
-
- private final ThreadLocal<MainScriptRunner> runners = new
ThreadLocal<MainScriptRunner>() {
- @Override
- protected MainScriptRunner initialValue() {
- final ScriptEngine engine =
manager.getEngineByName(script.getLanguage());
- return new MainScriptRunner(engine, script);
- }
- };
-
- public ThreadLocalScriptRunner(final AbstractScript script) {
- this.script = script;
- }
+public interface ScriptManager {
- @Override
- public Object execute(final Bindings bindings) {
- return runners.get().execute(bindings);
- }
+ /**
+ * Add scripts defined in the configuration.
+ * @param child The Scripts node.
+ */
+ void addScripts(Node child);
+ void addScript(final Script script);
- @Override
- public AbstractScript getScript() {
- return script;
- }
+ ScriptBindings createBindings(final Script script);
- @Override
- public ScriptEngine getScriptEngine() {
- return runners.get().getScriptEngine();
- }
- }
+ Script getScript(final String name);
- private ScriptRunner getScriptRunner(final AbstractScript script) {
- return scriptRunners.get(script.getName());
- }
+ Object execute(final String name, final ScriptBindings bindings);
}
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/script/package-info.java
b/log4j-core/src/main/java/org/apache/logging/log4j/core/script/ScriptManagerFactory.java
similarity index 74%
copy from
log4j-core/src/main/java/org/apache/logging/log4j/core/script/package-info.java
copy to
log4j-core/src/main/java/org/apache/logging/log4j/core/script/ScriptManagerFactory.java
index 4964b30..d4711d3 100644
---
a/log4j-core/src/main/java/org/apache/logging/log4j/core/script/package-info.java
+++
b/log4j-core/src/main/java/org/apache/logging/log4j/core/script/ScriptManagerFactory.java
@@ -14,7 +14,15 @@
* See the license for the specific language governing permissions and
* limitations under the license.
*/
+package org.apache.logging.log4j.core.script;
+
+import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.core.util.WatchManager;
+
/**
- * Log4j 2 Script support.
+ * Interface to create a ScriptManager.
*/
-package org.apache.logging.log4j.core.script;
+public interface ScriptManagerFactory {
+
+ ScriptManager createScriptManager(Configuration configuration,
WatchManager watchManager);
+}
diff --git a/log4j-jpl/pom.xml b/log4j-jpl/pom.xml
index 7c0cd91..b940b7d 100644
--- a/log4j-jpl/pom.xml
+++ b/log4j-jpl/pom.xml
@@ -43,7 +43,12 @@
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
- <scope>test</scope>
+ <optional>true</optional>
+ </dependency>
+ <dependency>
+ <groupId>com.lmax</groupId>
+ <artifactId>disruptor</artifactId>
+ <optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
diff --git a/log4j-jpl/src/main/java/module-info.java
b/log4j-jpl/src/main/java/module-info.java
index 2788318..0b5affa 100644
--- a/log4j-jpl/src/main/java/module-info.java
+++ b/log4j-jpl/src/main/java/module-info.java
@@ -16,6 +16,7 @@
*/
module org.apache.logging.log4j.jpl {
requires org.apache.logging.log4j;
+ requires transitive org.apache.logging.log4j.core;
provides java.lang.System.LoggerFinder with
org.apache.logging.log4j.jpl.Log4jSystemLoggerFinder;
}
diff --git a/log4j-plugins/src/main/java/module-info.java
b/log4j-plugins/src/main/java/module-info.java
index 20f1f17..d6150e1 100644
--- a/log4j-plugins/src/main/java/module-info.java
+++ b/log4j-plugins/src/main/java/module-info.java
@@ -29,8 +29,9 @@ module org.apache.logging.log4j.plugins {
exports org.apache.logging.log4j.plugins.name;
requires org.apache.logging.log4j;
- requires transitive org.osgi.framework;
+ requires static org.osgi.framework;
uses org.apache.logging.log4j.plugins.processor.PluginService;
provides org.apache.logging.log4j.plugins.processor.PluginService with
org.apache.logging.log4j.plugins.convert.plugins.Log4jPlugins;
+
}
diff --git
a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/util/PluginRegistry.java
b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/util/PluginRegistry.java
index f0fef7c..7019d54 100644
---
a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/util/PluginRegistry.java
+++
b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/util/PluginRegistry.java
@@ -195,13 +195,23 @@ public class PluginRegistry {
* @since 3.0
*/
public void loadPlugins(Map<String, List<PluginType<?>>> map) {
+ Throwable throwable = null;
+ ClassLoader errorClassLoader = null;
+ boolean allFail = true;
for (ClassLoader classLoader : LoaderUtil.getClassLoaders()) {
try {
loadPlugins(classLoader, map);
+ allFail = false;
} catch (Throwable ex) {
- LOGGER.debug("Unable to retrieve provider from ClassLoader
{}", classLoader, ex);
+ if (throwable == null) {
+ throwable = ex;
+ errorClassLoader = classLoader;
+ }
}
}
+ if (allFail && throwable != null) {
+ LOGGER.debug("Unable to retrieve provider from ClassLoader {}",
errorClassLoader, throwable);
+ }
}
/**
diff --git
a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/util/PluginType.java
b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/util/PluginType.java
index 3e1a4b1..b379506 100644
---
a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/util/PluginType.java
+++
b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/util/PluginType.java
@@ -17,7 +17,11 @@
package org.apache.logging.log4j.plugins.util;
+import java.util.Collection;
+
import org.apache.logging.log4j.plugins.processor.PluginEntry;
+import org.apache.logging.log4j.plugins.validation.ConstraintValidator;
+import org.apache.logging.log4j.plugins.validation.ConstraintValidators;
/**
* Plugin Descriptor. This is a memento object for Plugin annotations paired
to their annotated classes.
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/script/package-info.java
b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/validation/PluginValidator.java
similarity index 56%
copy from
log4j-core/src/main/java/org/apache/logging/log4j/core/script/package-info.java
copy to
log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/validation/PluginValidator.java
index 4964b30..3727c0e 100644
---
a/log4j-core/src/main/java/org/apache/logging/log4j/core/script/package-info.java
+++
b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/validation/PluginValidator.java
@@ -14,7 +14,24 @@
* See the license for the specific language governing permissions and
* limitations under the license.
*/
+package org.apache.logging.log4j.plugins.validation;
+
+import java.util.Collection;
+
/**
- * Log4j 2 Script support.
+ * Performs validation on the Plugin to determine if it can be used.
*/
-package org.apache.logging.log4j.core.script;
+public class PluginValidator {
+
+
+ public static boolean validatePlugin(Class<?> pluginClass, String
elementName) {
+ Collection<ConstraintValidator<?>> validators =
+
ConstraintValidators.findValidators(pluginClass.getAnnotations());
+ for (ConstraintValidator<?> validator : validators) {
+ if (!validator.isValid(elementName, pluginClass)) {
+ return false;
+ }
+ }
+ return true;
+ }
+}
diff --git
a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/validation/constraints/RequiredClass.java
b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/validation/constraints/RequiredClass.java
new file mode 100644
index 0000000..d640e39
--- /dev/null
+++
b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/validation/constraints/RequiredClass.java
@@ -0,0 +1,49 @@
+/*
+ * 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.logging.log4j.plugins.validation.constraints;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.apache.logging.log4j.plugins.validation.Constraint;
+import
org.apache.logging.log4j.plugins.validation.validators.RequiredClassValidator;
+
+/**
+ * Marks a plugin builder field or plugin factory parameter as required.
+ *
+ * @since 3.0.0
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.TYPE})
+@Constraint(RequiredClassValidator.class)
+public @interface RequiredClass {
+
+ /** The fully qualified name of the Class that is required */
+ String value();
+
+ /**
+ * The message to be logged if this constraint is violated. This should
normally be overridden.
+ * @return the message to be logged if the constraint is violated.
+ */
+ String message() default "The required class is not present";
+}
+
diff --git
a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/validation/constraints/RequiredProperty.java
b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/validation/constraints/RequiredProperty.java
new file mode 100644
index 0000000..9c5d884
--- /dev/null
+++
b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/validation/constraints/RequiredProperty.java
@@ -0,0 +1,51 @@
+/*
+ * 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.logging.log4j.plugins.validation.constraints;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.apache.logging.log4j.plugins.validation.Constraint;
+import
org.apache.logging.log4j.plugins.validation.validators.RequiredPropertyValidator;
+
+/**
+ * Marks a plugin as requiring a property to be set, possibly to a specific
value.
+ *
+ * @since 3.0.0
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.TYPE})
+@Constraint(RequiredPropertyValidator.class)
+public @interface RequiredProperty {
+
+ /** The name of the property that is required */
+ String name();
+ /** The value that the property is required to be set to. */
+ String value() default "";
+
+ /**
+ * The message to be logged if this constraint is violated. This should
normally be overridden.
+ * @return the message to be logged if the constraint is violated.
+ */
+ String message() default "The required property is not present or has an
incorrect value";
+}
+
diff --git
a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/validation/validators/RequiredClassValidator.java
b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/validation/validators/RequiredClassValidator.java
new file mode 100644
index 0000000..05622f6
--- /dev/null
+++
b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/validation/validators/RequiredClassValidator.java
@@ -0,0 +1,61 @@
+/*
+ * 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.logging.log4j.plugins.validation.validators;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.plugins.validation.ConstraintValidator;
+import org.apache.logging.log4j.plugins.validation.constraints.Required;
+import org.apache.logging.log4j.plugins.validation.constraints.RequiredClass;
+import org.apache.logging.log4j.status.StatusLogger;
+import org.apache.logging.log4j.util.Assert;
+import org.apache.logging.log4j.util.LoaderUtil;
+
+/**
+ * Validator that checks for the existence of a class that is required.
+ * <ul>
+ * <li>The value {@code null}</li>
+ * <li>An object of type {@link CharSequence} with length 0</li>
+ * <li>An empty array</li>
+ * <li>An empty {@link Collection}</li>
+ * <li>An empty {@link Map}</li>
+ * </ul>
+ *
+ * @since 2.1
+ */
+public class RequiredClassValidator implements
ConstraintValidator<RequiredClass> {
+
+ private static final Logger LOGGER = StatusLogger.getLogger();
+
+ private RequiredClass annotation;
+
+ @Override
+ public void initialize(final RequiredClass anAnnotation) {
+ this.annotation = anAnnotation;
+ }
+
+ @Override
+ public boolean isValid(final String name, final Object value) {
+ boolean isValid = LoaderUtil.isClassAvailable(annotation.value());
+ if (!isValid) {
+ LOGGER.error("{} cannot be used. {} is unavailable.", name,
annotation.value());
+ }
+ return isValid;
+ }
+}
diff --git
a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/validation/validators/RequiredPropertyValidator.java
b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/validation/validators/RequiredPropertyValidator.java
new file mode 100644
index 0000000..f17bd0e
--- /dev/null
+++
b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/validation/validators/RequiredPropertyValidator.java
@@ -0,0 +1,65 @@
+/*
+ * 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.logging.log4j.plugins.validation.validators;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.plugins.validation.ConstraintValidator;
+import
org.apache.logging.log4j.plugins.validation.constraints.RequiredProperty;
+import org.apache.logging.log4j.status.StatusLogger;
+import org.apache.logging.log4j.util.PropertiesUtil;
+
+/**
+ * Validator that checks that a property exists and has the correct value if a
value is required.
+ * <ul>
+ * <li>The value {@code null}</li>
+ * <li>An object of type {@link CharSequence} with length 0</li>
+ * <li>An empty array</li>
+ * <li>An empty {@link Collection}</li>
+ * <li>An empty {@link Map}</li>
+ * </ul>
+ *
+ * @since 3.0.0
+ */
+public class RequiredPropertyValidator implements
ConstraintValidator<RequiredProperty> {
+
+ private static final Logger LOGGER = StatusLogger.getLogger();
+
+ private RequiredProperty annotation;
+
+ @Override
+ public void initialize(final RequiredProperty anAnnotation) {
+ this.annotation = anAnnotation;
+ }
+
+ @Override
+ public boolean isValid(final String name, final Object value) {
+ String property =
PropertiesUtil.getProperties().getStringProperty(annotation.name());
+ if (property == null) {
+ LOGGER.error("{} cannot be used. Required property {} is not
defined", name, annotation.name());
+ return false;
+ }
+ if (annotation.value().length() > 0 &&
!annotation.value().equalsIgnoreCase(property)) {
+ LOGGER.error("{} cannot be used. Required property {} is not set
to {}", name, annotation.name(),
+ annotation.value());
+ return false;
+ }
+ return true;
+ }
+}
diff --git a/log4j-script/pom.xml b/log4j-script/pom.xml
index 816b0e4..de51e43 100644
--- a/log4j-script/pom.xml
+++ b/log4j-script/pom.xml
@@ -62,6 +62,33 @@
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.openjdk.nashorn</groupId>
+ <artifactId>nashorn-core</artifactId>
+ <version>15.3</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.groovy</groupId>
+ <artifactId>groovy</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.groovy</groupId>
+ <artifactId>groovy-jsr223</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.groovy</groupId>
+ <artifactId>groovy-dateutil</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache-extras.beanshell</groupId>
+ <artifactId>bsh</artifactId>
+ <scope>test</scope>
</dependency>
</dependencies>
diff --git a/log4j-script/src/main/java/module-info.java
b/log4j-script/src/main/java/module-info.java
new file mode 100644
index 0000000..7f4d466
--- /dev/null
+++ b/log4j-script/src/main/java/module-info.java
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+module org.apache.logging.log4j.script {
+
+ exports org.apache.logging.log4j.script;
+ exports org.apache.logging.log4j.script.appender;
+ exports org.apache.logging.log4j.script.appender.rolling.action;
+ exports org.apache.logging.log4j.script.config.arbiter;
+ exports org.apache.logging.log4j.script.filter;
+ exports org.apache.logging.log4j.script.layout;
+
+ opens org.apache.logging.log4j.script.appender;
+ opens org.apache.logging.log4j.script.config.arbiter to
org.apache.logging.log4j.core;
+ opens org.apache.logging.log4j.script.layout to
org.apache.logging.log4j.core;
+
+ requires java.scripting;
+ requires org.apache.logging.log4j;
+ requires org.apache.logging.log4j.plugins;
+ requires org.apache.logging.log4j.core;
+ provides org.apache.logging.log4j.plugins.processor.PluginService with
org.apache.logging.log4j.script.plugins.Log4jPlugins;
+ provides org.apache.logging.log4j.core.script.ScriptManagerFactory with
org.apache.logging.log4j.script.factory.ScriptManagerFactoryImpl;
+}
\ No newline at end of file
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/script/AbstractScript.java
b/log4j-script/src/main/java/org/apache/logging/log4j/script/AbstractScript.java
similarity index 92%
rename from
log4j-core/src/main/java/org/apache/logging/log4j/core/script/AbstractScript.java
rename to
log4j-script/src/main/java/org/apache/logging/log4j/script/AbstractScript.java
index b78bff2..ff645cd 100644
---
a/log4j-core/src/main/java/org/apache/logging/log4j/core/script/AbstractScript.java
+++
b/log4j-script/src/main/java/org/apache/logging/log4j/script/AbstractScript.java
@@ -14,7 +14,7 @@
* See the license for the specific language governing permissions and
* limitations under the license.
*/
-package org.apache.logging.log4j.core.script;
+package org.apache.logging.log4j.script;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.status.StatusLogger;
@@ -22,7 +22,7 @@ import org.apache.logging.log4j.status.StatusLogger;
/**
* Container for the language and body of a script.
*/
-public abstract class AbstractScript {
+public abstract class AbstractScript implements
org.apache.logging.log4j.core.script.Script {
protected static final Logger LOGGER = StatusLogger.getLogger();
protected static final String DEFAULT_LANGUAGE = "JavaScript";
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/script/ScriptFile.java
b/log4j-script/src/main/java/org/apache/logging/log4j/script/ScriptFile.java
similarity index 99%
rename from
log4j-core/src/main/java/org/apache/logging/log4j/core/script/ScriptFile.java
rename to
log4j-script/src/main/java/org/apache/logging/log4j/script/ScriptFile.java
index 6d52051..adc701e 100644
---
a/log4j-core/src/main/java/org/apache/logging/log4j/core/script/ScriptFile.java
+++ b/log4j-script/src/main/java/org/apache/logging/log4j/script/ScriptFile.java
@@ -14,7 +14,7 @@
* See the license for the specific language governing permissions and
* limitations under the license.
*/
-package org.apache.logging.log4j.core.script;
+package org.apache.logging.log4j.script;
import java.io.File;
import java.io.FileInputStream;
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/script/ScriptManager.java
b/log4j-script/src/main/java/org/apache/logging/log4j/script/ScriptManagerImpl.java
similarity index 82%
copy from
log4j-core/src/main/java/org/apache/logging/log4j/core/script/ScriptManager.java
copy to
log4j-script/src/main/java/org/apache/logging/log4j/script/ScriptManagerImpl.java
index 43c4f85..46a7b2d 100644
---
a/log4j-core/src/main/java/org/apache/logging/log4j/core/script/ScriptManager.java
+++
b/log4j-script/src/main/java/org/apache/logging/log4j/script/ScriptManagerImpl.java
@@ -14,7 +14,7 @@
* See the license for the specific language governing permissions and
* limitations under the license.
*/
-package org.apache.logging.log4j.core.script;
+package org.apache.logging.log4j.script;
import java.io.File;
import java.io.Serializable;
@@ -37,15 +37,19 @@ import javax.script.SimpleBindings;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.core.script.Script;
+import org.apache.logging.log4j.core.script.ScriptBindings;
+import org.apache.logging.log4j.core.script.ScriptManager;
import org.apache.logging.log4j.core.util.FileWatcher;
import org.apache.logging.log4j.core.util.WatchManager;
+import org.apache.logging.log4j.plugins.Node;
import org.apache.logging.log4j.status.StatusLogger;
import org.apache.logging.log4j.util.Strings;
/**
* Manages the scripts use by the Configuration.
*/
-public class ScriptManager implements FileWatcher, Serializable {
+public class ScriptManagerImpl implements ScriptManager, FileWatcher,
Serializable {
private abstract class AbstractScriptRunner implements ScriptRunner {
@@ -53,8 +57,8 @@ public class ScriptManager implements FileWatcher,
Serializable {
private static final String KEY_CONFIGURATION = "configuration";
@Override
- public Bindings createBindings() {
- final SimpleBindings bindings = new SimpleBindings();
+ public ScriptBindings createBindings() {
+ final ScriptBindings bindings = new ScriptBindingsImpl();
bindings.put(KEY_CONFIGURATION, configuration);
bindings.put(KEY_STATUS_LOGGER, logger);
return bindings;
@@ -62,6 +66,9 @@ public class ScriptManager implements FileWatcher,
Serializable {
}
+ private static class ScriptBindingsImpl extends SimpleBindings implements
ScriptBindings {
+ }
+
private static final long serialVersionUID = -2534169384971965196L;
private static final String KEY_THREADING = "THREADING";
private static final Logger logger = StatusLogger.getLogger();
@@ -72,7 +79,7 @@ public class ScriptManager implements FileWatcher,
Serializable {
private final String languages;
private final WatchManager watchManager;
- public ScriptManager(final Configuration configuration, final WatchManager
watchManager) {
+ public ScriptManagerImpl(final Configuration configuration, final
WatchManager watchManager) {
this.configuration = configuration;
this.watchManager = watchManager;
final List<ScriptEngineFactory> factories =
manager.getEngineFactories();
@@ -123,7 +130,18 @@ public class ScriptManager implements FileWatcher,
Serializable {
}
}
- public void addScript(final AbstractScript script) {
+ public void addScripts(Node child) {
+ for (final AbstractScript script :
child.getObject(AbstractScript[].class)) {
+ if (script instanceof ScriptRef) {
+ logger.error("Script reference to {} not added. Scripts
definition cannot contain script references",
+ script.getName());
+ } else {
+ addScript(script);
+ }
+ }
+ }
+
+ public void addScript(final Script script) {
final ScriptEngine engine =
manager.getEngineByName(script.getLanguage());
if (engine == null) {
logger.error("No ScriptEngine found for language " +
script.getLanguage() + ". Available languages are: "
@@ -145,11 +163,15 @@ public class ScriptManager implements FileWatcher,
Serializable {
}
}
- public Bindings createBindings(final AbstractScript script) {
+ public static ScriptBindings createBindings() {
+ return new ScriptBindingsImpl();
+ }
+
+ public ScriptBindings createBindings(final Script script) {
return getScriptRunner(script).createBindings();
}
- public AbstractScript getScript(final String name) {
+ public Script getScript(final String name) {
final ScriptRunner runner = scriptRunners.get(name);
return runner != null ? runner.getScript() : null;
}
@@ -162,7 +184,7 @@ public class ScriptManager implements FileWatcher,
Serializable {
return;
}
final ScriptEngine engine = runner.getScriptEngine();
- final AbstractScript script = runner.getScript();
+ final Script script = runner.getScript();
if (engine.getFactory().getParameter(KEY_THREADING) == null) {
scriptRunners.put(script.getName(), new
ThreadLocalScriptRunner(script));
} else {
@@ -171,7 +193,7 @@ public class ScriptManager implements FileWatcher,
Serializable {
}
- public Object execute(final String name, final Bindings bindings) {
+ public Object execute(final String name, final ScriptBindings bindings) {
final ScriptRunner scriptRunner = scriptRunners.get(name);
if (scriptRunner == null) {
logger.warn("No script named {} could be found", name);
@@ -182,21 +204,21 @@ public class ScriptManager implements FileWatcher,
Serializable {
private interface ScriptRunner {
- Bindings createBindings();
+ ScriptBindings createBindings();
- Object execute(Bindings bindings);
+ Object execute(ScriptBindings bindings);
- AbstractScript getScript();
+ Script getScript();
ScriptEngine getScriptEngine();
}
private class MainScriptRunner extends AbstractScriptRunner {
- private final AbstractScript script;
+ private final Script script;
private final CompiledScript compiledScript;
private final ScriptEngine scriptEngine;
- public MainScriptRunner(final ScriptEngine scriptEngine, final
AbstractScript script) {
+ public MainScriptRunner(final ScriptEngine scriptEngine, final Script
script) {
this.script = script;
this.scriptEngine = scriptEngine;
CompiledScript compiled = null;
@@ -224,17 +246,17 @@ public class ScriptManager implements FileWatcher,
Serializable {
}
@Override
- public Object execute(final Bindings bindings) {
+ public Object execute(final ScriptBindings bindings) {
if (compiledScript != null) {
try {
- return compiledScript.eval(bindings);
+ return compiledScript.eval((Bindings) bindings);
} catch (final ScriptException ex) {
logger.error("Error running script " + script.getName(),
ex);
return null;
}
}
try {
- return scriptEngine.eval(script.getScriptText(), bindings);
+ return scriptEngine.eval(script.getScriptText(), (Bindings)
bindings);
} catch (final ScriptException ex) {
logger.error("Error running script " + script.getName(), ex);
return null;
@@ -242,13 +264,13 @@ public class ScriptManager implements FileWatcher,
Serializable {
}
@Override
- public AbstractScript getScript() {
+ public Script getScript() {
return script;
}
}
private class ThreadLocalScriptRunner extends AbstractScriptRunner {
- private final AbstractScript script;
+ private final Script script;
private final ThreadLocal<MainScriptRunner> runners = new
ThreadLocal<MainScriptRunner>() {
@Override
@@ -258,17 +280,17 @@ public class ScriptManager implements FileWatcher,
Serializable {
}
};
- public ThreadLocalScriptRunner(final AbstractScript script) {
+ public ThreadLocalScriptRunner(final Script script) {
this.script = script;
}
@Override
- public Object execute(final Bindings bindings) {
+ public Object execute(final ScriptBindings bindings) {
return runners.get().execute(bindings);
}
@Override
- public AbstractScript getScript() {
+ public Script getScript() {
return script;
}
@@ -278,7 +300,7 @@ public class ScriptManager implements FileWatcher,
Serializable {
}
}
- private ScriptRunner getScriptRunner(final AbstractScript script) {
+ private ScriptRunner getScriptRunner(final Script script) {
return scriptRunners.get(script.getName());
}
}
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/script/Script.java
b/log4j-script/src/main/java/org/apache/logging/log4j/script/ScriptPlugin.java
similarity index 84%
copy from
log4j-core/src/main/java/org/apache/logging/log4j/core/script/Script.java
copy to
log4j-script/src/main/java/org/apache/logging/log4j/script/ScriptPlugin.java
index b51eb37..1e1c3c8 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/script/Script.java
+++
b/log4j-script/src/main/java/org/apache/logging/log4j/script/ScriptPlugin.java
@@ -14,7 +14,7 @@
* See the license for the specific language governing permissions and
* limitations under the license.
*/
-package org.apache.logging.log4j.core.script;
+package org.apache.logging.log4j.script;
import org.apache.logging.log4j.plugins.Node;
import org.apache.logging.log4j.plugins.Plugin;
@@ -25,19 +25,19 @@ import org.apache.logging.log4j.plugins.PluginValue;
/**
* Container for the language and body of a script.
*/
-@Plugin(name = Script.PLUGIN_NAME, category = Node.CATEGORY, printObject =
true)
-public class Script extends AbstractScript {
+@Plugin(name = ScriptPlugin.PLUGIN_NAME, category = Node.CATEGORY, printObject
= true)
+public class ScriptPlugin extends AbstractScript {
private static final String ATTR_LANGUAGE = "language";
private static final String ATTR_SCRIPT_TEXT = "scriptText";
static final String PLUGIN_NAME = "Script";
- public Script(final String name, final String language, final String
scriptText) {
+ public ScriptPlugin(final String name, final String language, final String
scriptText) {
super(name, language, scriptText);
}
@PluginFactory
- public static Script createScript(
+ public static ScriptPlugin createScript(
// @formatter:off
@PluginAttribute final String name,
@PluginAttribute String language,
@@ -51,7 +51,7 @@ public class Script extends AbstractScript {
LOGGER.error("No '{}' attribute provided for {} plugin '{}'",
ATTR_SCRIPT_TEXT, PLUGIN_NAME, name);
return null;
}
- return new Script(name, language, scriptText);
+ return new ScriptPlugin(name, language, scriptText);
}
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/script/ScriptRef.java
b/log4j-script/src/main/java/org/apache/logging/log4j/script/ScriptRef.java
similarity index 88%
rename from
log4j-core/src/main/java/org/apache/logging/log4j/core/script/ScriptRef.java
rename to
log4j-script/src/main/java/org/apache/logging/log4j/script/ScriptRef.java
index abec150..d165ff4 100644
---
a/log4j-core/src/main/java/org/apache/logging/log4j/core/script/ScriptRef.java
+++ b/log4j-script/src/main/java/org/apache/logging/log4j/script/ScriptRef.java
@@ -14,9 +14,11 @@
* See the license for the specific language governing permissions and
* limitations under the license.
*/
-package org.apache.logging.log4j.core.script;
+package org.apache.logging.log4j.script;
import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.core.script.Script;
+import org.apache.logging.log4j.core.script.ScriptManager;
import org.apache.logging.log4j.plugins.Node;
import org.apache.logging.log4j.plugins.Plugin;
import org.apache.logging.log4j.plugins.PluginAttribute;
@@ -38,14 +40,14 @@ public class ScriptRef extends AbstractScript {
@Override
public String getLanguage() {
- final AbstractScript script = this.scriptManager.getScript(getName());
+ final Script script = this.scriptManager.getScript(getName());
return script != null ? script.getLanguage() : null;
}
@Override
public String getScriptText() {
- final AbstractScript script = this.scriptManager.getScript(getName());
+ final Script script = this.scriptManager.getScript(getName());
return script != null ? script.getScriptText() : null;
}
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ScriptsPlugin.java
b/log4j-script/src/main/java/org/apache/logging/log4j/script/ScriptsPlugin.java
similarity index 93%
rename from
log4j-core/src/main/java/org/apache/logging/log4j/core/config/ScriptsPlugin.java
rename to
log4j-script/src/main/java/org/apache/logging/log4j/script/ScriptsPlugin.java
index 6329f89..d4e2f92 100644
---
a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ScriptsPlugin.java
+++
b/log4j-script/src/main/java/org/apache/logging/log4j/script/ScriptsPlugin.java
@@ -14,13 +14,12 @@
* See the license for the specific language governing permissions and
* limitations under the license.
*/
-package org.apache.logging.log4j.core.config;
+package org.apache.logging.log4j.script;
import org.apache.logging.log4j.core.Core;
import org.apache.logging.log4j.plugins.Plugin;
import org.apache.logging.log4j.plugins.PluginElement;
import org.apache.logging.log4j.plugins.PluginFactory;
-import org.apache.logging.log4j.core.script.AbstractScript;
/**
* A container of Scripts.
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/ScriptAppenderSelector.java
b/log4j-script/src/main/java/org/apache/logging/log4j/script/appender/ScriptAppenderSelector.java
similarity index 79%
rename from
log4j-core/src/main/java/org/apache/logging/log4j/core/appender/ScriptAppenderSelector.java
rename to
log4j-script/src/main/java/org/apache/logging/log4j/script/appender/ScriptAppenderSelector.java
index cfcf580..0ea9fb2 100644
---
a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/ScriptAppenderSelector.java
+++
b/log4j-script/src/main/java/org/apache/logging/log4j/script/appender/ScriptAppenderSelector.java
@@ -14,25 +14,28 @@
* See the license for the specific language governing permissions and
* limitations under the license.
*/
-package org.apache.logging.log4j.core.appender;
+package org.apache.logging.log4j.script.appender;
+import org.apache.logging.log4j.core.AbstractLifeCycle;
import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.Core;
import org.apache.logging.log4j.core.Filter;
import org.apache.logging.log4j.core.Layout;
import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.appender.AbstractAppender;
+import org.apache.logging.log4j.core.appender.AppenderSet;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.Property;
import org.apache.logging.log4j.core.config.plugins.PluginConfiguration;
-import org.apache.logging.log4j.core.script.AbstractScript;
+import org.apache.logging.log4j.core.script.ScriptBindings;
import org.apache.logging.log4j.core.script.ScriptManager;
import org.apache.logging.log4j.plugins.Plugin;
import org.apache.logging.log4j.plugins.PluginBuilderAttribute;
import org.apache.logging.log4j.plugins.PluginElement;
import org.apache.logging.log4j.plugins.PluginFactory;
import org.apache.logging.log4j.plugins.validation.constraints.Required;
+import org.apache.logging.log4j.script.AbstractScript;
-import javax.script.Bindings;
import java.io.Serializable;
import java.util.Objects;
@@ -63,29 +66,32 @@ public class ScriptAppenderSelector extends
AbstractAppender {
@Override
public Appender build() {
if (name == null) {
- LOGGER.error("Name missing.");
+ AbstractLifeCycle.LOGGER.error("Name missing.");
return null;
}
if (script == null) {
- LOGGER.error("Script missing for ScriptAppenderSelector
appender {}", name);
+ AbstractLifeCycle.LOGGER.error("Script missing for
ScriptAppenderSelector appender {}", name);
return null;
}
if (appenderSet == null) {
- LOGGER.error("AppenderSet missing for ScriptAppenderSelector
appender {}", name);
+ AbstractLifeCycle.LOGGER.error("AppenderSet missing for
ScriptAppenderSelector appender {}", name);
return null;
}
if (configuration == null) {
- LOGGER.error("Configuration missing for ScriptAppenderSelector
appender {}", name);
+ AbstractLifeCycle.LOGGER.error("Configuration missing for
ScriptAppenderSelector appender {}", name);
return null;
}
final ScriptManager scriptManager =
configuration.getScriptManager();
+ if (scriptManager == null) {
+ return null;
+ }
scriptManager.addScript(script);
- final Bindings bindings = scriptManager.createBindings(script);
- LOGGER.debug("ScriptAppenderSelector '{}' executing {} '{}': {}",
name, script.getLanguage(),
+ final ScriptBindings bindings =
scriptManager.createBindings(script);
+ AbstractLifeCycle.LOGGER.debug("ScriptAppenderSelector '{}'
executing {} '{}': {}", name, script.getLanguage(),
script.getName(), script.getScriptText());
final Object object = scriptManager.execute(script.getName(),
bindings);
final String actualAppenderName = Objects.toString(object, null);
- LOGGER.debug("ScriptAppenderSelector '{}' selected '{}'", name,
actualAppenderName);
+ AbstractLifeCycle.LOGGER.debug("ScriptAppenderSelector '{}'
selected '{}'", name, actualAppenderName);
return appenderSet.createAppender(actualAppenderName, name);
}
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/ScriptCondition.java
b/log4j-script/src/main/java/org/apache/logging/log4j/script/appender/rolling/action/ScriptCondition.java
similarity index 87%
rename from
log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/ScriptCondition.java
rename to
log4j-script/src/main/java/org/apache/logging/log4j/script/appender/rolling/action/ScriptCondition.java
index 2f6a0f6..744d5bb 100644
---
a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/ScriptCondition.java
+++
b/log4j-script/src/main/java/org/apache/logging/log4j/script/appender/rolling/action/ScriptCondition.java
@@ -15,7 +15,7 @@
* limitations under the license.
*/
-package org.apache.logging.log4j.core.appender.rolling.action;
+package org.apache.logging.log4j.script.appender.rolling.action;
import java.nio.file.Path;
import java.util.List;
@@ -25,14 +25,17 @@ import javax.script.SimpleBindings;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.Core;
+import
org.apache.logging.log4j.core.appender.rolling.action.PathWithAttributes;
import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.core.script.Script;
+import org.apache.logging.log4j.core.script.ScriptBindings;
+import org.apache.logging.log4j.core.script.ScriptConditional;
import org.apache.logging.log4j.plugins.Plugin;
import org.apache.logging.log4j.core.config.plugins.PluginConfiguration;
import org.apache.logging.log4j.plugins.PluginElement;
import org.apache.logging.log4j.plugins.PluginFactory;
-import org.apache.logging.log4j.core.script.AbstractScript;
-import org.apache.logging.log4j.core.script.ScriptFile;
-import org.apache.logging.log4j.core.script.ScriptRef;
+import org.apache.logging.log4j.script.ScriptManagerImpl;
+import org.apache.logging.log4j.script.ScriptRef;
import org.apache.logging.log4j.status.StatusLogger;
/**
@@ -42,10 +45,10 @@ import org.apache.logging.log4j.status.StatusLogger;
* @see #createCondition(AbstractScript, Configuration)
*/
@Plugin(name = "ScriptCondition", category = Core.CATEGORY_NAME, printObject =
true)
-public class ScriptCondition {
+public class ScriptCondition implements ScriptConditional {
private static final Logger LOGGER = StatusLogger.getLogger();
- private final AbstractScript script;
+ private final Script script;
private final Configuration configuration;
/**
@@ -54,7 +57,7 @@ public class ScriptCondition {
* @param script the script that can select files to delete
* @param configuration configuration containing the StrSubstitutor passed
to the script
*/
- public ScriptCondition(final AbstractScript script, final Configuration
configuration) {
+ public ScriptCondition(final Script script, final Configuration
configuration) {
this.script = Objects.requireNonNull(script, "script");
this.configuration = Objects.requireNonNull(configuration,
"configuration");
if (!(script instanceof ScriptRef)) {
@@ -71,7 +74,7 @@ public class ScriptCondition {
*/
@SuppressWarnings("unchecked")
public List<PathWithAttributes> selectFilesToDelete(final Path basePath,
final List<PathWithAttributes> candidates) {
- final SimpleBindings bindings = new SimpleBindings();
+ final ScriptBindings bindings = ScriptManagerImpl.createBindings();
bindings.put("basePath", basePath);
bindings.put("pathList", candidates);
bindings.putAll(configuration.getProperties());
@@ -102,7 +105,7 @@ public class ScriptCondition {
* @return A ScriptCondition.
*/
@PluginFactory
- public static ScriptCondition createCondition(@PluginElement("Script")
final AbstractScript script,
+ public static ScriptCondition createCondition(@PluginElement("Script")
final Script script,
@PluginConfiguration final Configuration configuration) {
if (script == null) {
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/arbiters/ScriptArbiter.java
b/log4j-script/src/main/java/org/apache/logging/log4j/script/config/arbiter/ScriptArbiter.java
similarity index 86%
rename from
log4j-core/src/main/java/org/apache/logging/log4j/core/config/arbiters/ScriptArbiter.java
rename to
log4j-script/src/main/java/org/apache/logging/log4j/script/config/arbiter/ScriptArbiter.java
index c968a32..35d06ec 100644
---
a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/arbiters/ScriptArbiter.java
+++
b/log4j-script/src/main/java/org/apache/logging/log4j/script/config/arbiter/ScriptArbiter.java
@@ -14,21 +14,22 @@
* See the license for the specific language governing permissions and
* limitations under the license.
*/
-package org.apache.logging.log4j.core.config.arbiters;
-
-import javax.script.SimpleBindings;
+package org.apache.logging.log4j.script.config.arbiter;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.config.AbstractConfiguration;
import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.core.config.arbiters.Arbiter;
import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory;
import org.apache.logging.log4j.core.config.plugins.PluginConfiguration;
import org.apache.logging.log4j.core.config.plugins.PluginNode;
-import org.apache.logging.log4j.core.script.AbstractScript;
-import org.apache.logging.log4j.core.script.ScriptRef;
+import org.apache.logging.log4j.core.script.Script;
+import org.apache.logging.log4j.core.script.ScriptBindings;
import org.apache.logging.log4j.plugins.Node;
import org.apache.logging.log4j.plugins.Plugin;
import org.apache.logging.log4j.plugins.util.PluginType;
+import org.apache.logging.log4j.script.ScriptManagerImpl;
+import org.apache.logging.log4j.script.ScriptRef;
import org.apache.logging.log4j.status.StatusLogger;
/**
@@ -38,10 +39,10 @@ import org.apache.logging.log4j.status.StatusLogger;
deferChildren = true, printObject = true)
public class ScriptArbiter implements Arbiter {
- private final AbstractScript script;
+ private final Script script;
private final Configuration configuration;
- private ScriptArbiter(final Configuration configuration, final
AbstractScript script) {
+ private ScriptArbiter(final Configuration configuration, final Script
script) {
this.configuration = configuration;
this.script = script;
if (!(script instanceof ScriptRef)) {
@@ -54,7 +55,7 @@ public class ScriptArbiter implements Arbiter {
*/
@Override
public boolean isCondition() {
- final SimpleBindings bindings = new SimpleBindings();
+ final ScriptBindings bindings = ScriptManagerImpl.createBindings();
bindings.putAll(configuration.getProperties());
bindings.put("substitutor", configuration.getStrSubstitutor());
final Object object =
configuration.getScriptManager().execute(script.getName(), bindings);
@@ -91,15 +92,15 @@ public class ScriptArbiter implements Arbiter {
}
public ScriptArbiter build() {
- AbstractScript script = null;
+ Script script = null;
for (final Node child : node.getChildren()) {
final PluginType<?> type = child.getType();
if (type == null) {
LOGGER.error("Node {} is missing a Plugintype",
child.getName());
continue;
}
- if
(AbstractScript.class.isAssignableFrom(type.getPluginClass())) {
- script = (AbstractScript)
configuration.createPluginObject(type, child);
+ if (Script.class.isAssignableFrom(type.getPluginClass())) {
+ script = (Script) configuration.createPluginObject(type,
child);
node.getChildren().remove(child);
break;
}
diff --git
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/filter/ScriptFileFilterTest.java
b/log4j-script/src/main/java/org/apache/logging/log4j/script/factory/ScriptManagerFactoryImpl.java
similarity index 58%
copy from
log4j-core-test/src/test/java/org/apache/logging/log4j/core/filter/ScriptFileFilterTest.java
copy to
log4j-script/src/main/java/org/apache/logging/log4j/script/factory/ScriptManagerFactoryImpl.java
index fca3e96..18887d5 100644
---
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/filter/ScriptFileFilterTest.java
+++
b/log4j-script/src/main/java/org/apache/logging/log4j/script/factory/ScriptManagerFactoryImpl.java
@@ -14,10 +14,21 @@
* See the license for the specific language governing permissions and
* limitations under the license.
*/
-package org.apache.logging.log4j.core.filter;
+package org.apache.logging.log4j.script.factory;
-import org.apache.logging.log4j.core.test.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.core.script.ScriptManager;
+import org.apache.logging.log4j.core.script.ScriptManagerFactory;
+import org.apache.logging.log4j.core.util.WatchManager;
+import org.apache.logging.log4j.script.ScriptManagerImpl;
-@LoggerContextSource("log4j-scriptFile-filters.xml")
-public class ScriptFileFilterTest extends AbstractScriptFilterTest {
+/**
+ * Creates a ScriptManager.
+ */
+public class ScriptManagerFactoryImpl implements ScriptManagerFactory {
+
+ @Override
+ public ScriptManager createScriptManager(Configuration configuration,
WatchManager watchManager) {
+ return new ScriptManagerImpl(configuration, watchManager);
+ }
}
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/filter/ScriptFilter.java
b/log4j-script/src/main/java/org/apache/logging/log4j/script/filter/ScriptFilter.java
similarity index 86%
rename from
log4j-core/src/main/java/org/apache/logging/log4j/core/filter/ScriptFilter.java
rename to
log4j-script/src/main/java/org/apache/logging/log4j/script/filter/ScriptFilter.java
index 14b7f84..8e793a6 100644
---
a/log4j-core/src/main/java/org/apache/logging/log4j/core/filter/ScriptFilter.java
+++
b/log4j-script/src/main/java/org/apache/logging/log4j/script/filter/ScriptFilter.java
@@ -14,27 +14,29 @@
* See the license for the specific language governing permissions and
* limitations under the license.
*/
-package org.apache.logging.log4j.core.filter;
-
-import javax.script.SimpleBindings;
+package org.apache.logging.log4j.script.filter;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.Marker;
+import org.apache.logging.log4j.core.AbstractLifeCycle;
import org.apache.logging.log4j.core.Filter;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.Logger;
import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.core.filter.AbstractFilter;
+import org.apache.logging.log4j.core.script.Script;
+import org.apache.logging.log4j.core.script.ScriptBindings;
import org.apache.logging.log4j.plugins.Node;
import org.apache.logging.log4j.plugins.Plugin;
import org.apache.logging.log4j.plugins.PluginAttribute;
import org.apache.logging.log4j.core.config.plugins.PluginConfiguration;
import org.apache.logging.log4j.plugins.PluginElement;
import org.apache.logging.log4j.plugins.PluginFactory;
-import org.apache.logging.log4j.core.script.AbstractScript;
-import org.apache.logging.log4j.core.script.ScriptRef;
import org.apache.logging.log4j.message.Message;
import org.apache.logging.log4j.message.ObjectMessage;
import org.apache.logging.log4j.message.SimpleMessage;
+import org.apache.logging.log4j.script.ScriptManagerImpl;
+import org.apache.logging.log4j.script.ScriptRef;
import org.apache.logging.log4j.status.StatusLogger;
/**
@@ -45,10 +47,10 @@ public final class ScriptFilter extends AbstractFilter {
private static final org.apache.logging.log4j.Logger logger =
StatusLogger.getLogger();
- private final AbstractScript script;
+ private final Script script;
private final Configuration configuration;
- private ScriptFilter(final AbstractScript script, final Configuration
configuration, final Result onMatch,
+ private ScriptFilter(final Script script, final Configuration
configuration, final Result onMatch,
final Result onMismatch) {
super(onMatch, onMismatch);
this.script = script;
@@ -61,7 +63,7 @@ public final class ScriptFilter extends AbstractFilter {
@Override
public Result filter(final Logger logger, final Level level, final Marker
marker, final String msg,
final Object... params) {
- final SimpleBindings bindings = new SimpleBindings();
+ final ScriptBindings bindings = ScriptManagerImpl.createBindings();
bindings.put("logger", logger);
bindings.put("level", level);
bindings.put("marker", marker);
@@ -77,7 +79,7 @@ public final class ScriptFilter extends AbstractFilter {
@Override
public Result filter(final Logger logger, final Level level, final Marker
marker, final Object msg,
final Throwable t) {
- final SimpleBindings bindings = new SimpleBindings();
+ final ScriptBindings bindings = ScriptManagerImpl.createBindings();
bindings.put("logger", logger);
bindings.put("level", level);
bindings.put("marker", marker);
@@ -93,7 +95,7 @@ public final class ScriptFilter extends AbstractFilter {
@Override
public Result filter(final Logger logger, final Level level, final Marker
marker, final Message msg,
final Throwable t) {
- final SimpleBindings bindings = new SimpleBindings();
+ final ScriptBindings bindings = ScriptManagerImpl.createBindings();
bindings.put("logger", logger);
bindings.put("level", level);
bindings.put("marker", marker);
@@ -108,7 +110,7 @@ public final class ScriptFilter extends AbstractFilter {
@Override
public Result filter(final LogEvent event) {
- final SimpleBindings bindings = new SimpleBindings();
+ final ScriptBindings bindings = ScriptManagerImpl.createBindings();
bindings.put("logEvent", event);
bindings.putAll(configuration.getProperties());
bindings.put("substitutor", configuration.getStrSubstitutor());
@@ -133,13 +135,13 @@ public final class ScriptFilter extends AbstractFilter {
// TODO Consider refactoring to use AbstractFilter.AbstractFilterBuilder
@PluginFactory
public static ScriptFilter createFilter(
- @PluginElement final AbstractScript script,
+ @PluginElement final Script script,
@PluginAttribute final Result onMatch,
@PluginAttribute final Result onMismatch,
@PluginConfiguration final Configuration configuration) {
if (script == null) {
- LOGGER.error("A Script, ScriptFile or ScriptRef element must be
provided for this ScriptFilter");
+ AbstractLifeCycle.LOGGER.error("A Script, ScriptFile or ScriptRef
element must be provided for this ScriptFilter");
return null;
}
if (script instanceof ScriptRef) {
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/ScriptPatternSelector.java
b/log4j-script/src/main/java/org/apache/logging/log4j/script/layout/ScriptPatternSelector.java
similarity index 94%
rename from
log4j-core/src/main/java/org/apache/logging/log4j/core/layout/ScriptPatternSelector.java
rename to
log4j-script/src/main/java/org/apache/logging/log4j/script/layout/ScriptPatternSelector.java
index b281377..0828756 100644
---
a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/ScriptPatternSelector.java
+++
b/log4j-script/src/main/java/org/apache/logging/log4j/script/layout/ScriptPatternSelector.java
@@ -14,21 +14,26 @@
* See the license for the specific language governing permissions and
* limitations under the license.
*/
-package org.apache.logging.log4j.core.layout;
+package org.apache.logging.log4j.script.layout;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.plugins.PluginConfiguration;
+import org.apache.logging.log4j.core.layout.PatternLayout;
+import org.apache.logging.log4j.core.layout.PatternMatch;
+import org.apache.logging.log4j.core.layout.PatternSelector;
import org.apache.logging.log4j.core.pattern.PatternFormatter;
import org.apache.logging.log4j.core.pattern.PatternParser;
-import org.apache.logging.log4j.core.script.AbstractScript;
-import org.apache.logging.log4j.core.script.ScriptRef;
+import org.apache.logging.log4j.core.script.ScriptBindings;
import org.apache.logging.log4j.plugins.Node;
import org.apache.logging.log4j.plugins.Plugin;
import org.apache.logging.log4j.plugins.PluginBuilderAttribute;
import org.apache.logging.log4j.plugins.PluginElement;
import org.apache.logging.log4j.plugins.PluginFactory;
+import org.apache.logging.log4j.script.AbstractScript;
+import org.apache.logging.log4j.script.ScriptManagerImpl;
+import org.apache.logging.log4j.script.ScriptRef;
import org.apache.logging.log4j.status.StatusLogger;
import javax.script.SimpleBindings;
@@ -189,7 +194,7 @@ public class ScriptPatternSelector implements
PatternSelector {
@Override
public PatternFormatter[] getFormatters(final LogEvent event) {
- final SimpleBindings bindings = new SimpleBindings();
+ final ScriptBindings bindings = ScriptManagerImpl.createBindings();
bindings.putAll(configuration.getProperties());
bindings.put("substitutor", configuration.getStrSubstitutor());
bindings.put("logEvent", event);
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/script/package-info.java
b/log4j-script/src/main/java/org/apache/logging/log4j/script/package-info.java
similarity index 94%
rename from
log4j-core/src/main/java/org/apache/logging/log4j/core/script/package-info.java
rename to
log4j-script/src/main/java/org/apache/logging/log4j/script/package-info.java
index 4964b30..46a4bba 100644
---
a/log4j-core/src/main/java/org/apache/logging/log4j/core/script/package-info.java
+++
b/log4j-script/src/main/java/org/apache/logging/log4j/script/package-info.java
@@ -17,4 +17,4 @@
/**
* Log4j 2 Script support.
*/
-package org.apache.logging.log4j.core.script;
+package org.apache.logging.log4j.script;
diff --git
a/log4j-script/src/main/resources/META-INF/services/org.apache.logging.log4j.core.script.ScriptManagerFactory
b/log4j-script/src/main/resources/META-INF/services/org.apache.logging.log4j.core.script.ScriptManagerFactory
new file mode 100644
index 0000000..01db40a
--- /dev/null
+++
b/log4j-script/src/main/resources/META-INF/services/org.apache.logging.log4j.core.script.ScriptManagerFactory
@@ -0,0 +1 @@
+org.apache.logging.log4j.script.factory.ScriptManagerFactoryImpl
\ No newline at end of file
diff --git
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ScriptAppenderSelectorTest.java
b/log4j-script/src/test/java/org/apache/logging/log4j/script/appender/ScriptAppenderSelectorTest.java
similarity index 98%
rename from
log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ScriptAppenderSelectorTest.java
rename to
log4j-script/src/test/java/org/apache/logging/log4j/script/appender/ScriptAppenderSelectorTest.java
index 0a175b2..4d70fc4 100644
---
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ScriptAppenderSelectorTest.java
+++
b/log4j-script/src/test/java/org/apache/logging/log4j/script/appender/ScriptAppenderSelectorTest.java
@@ -14,7 +14,7 @@
* See the license for the specific language governing permissions and
* limitations under the license.
*/
-package org.apache.logging.log4j.core.appender;
+package org.apache.logging.log4j.script.appender;
import org.apache.logging.log4j.MarkerManager;
import org.apache.logging.log4j.core.config.Configuration;
diff --git
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteScriptFri13thTest.java
b/log4j-script/src/test/java/org/apache/logging/log4j/script/appender/rolling/RollingAppenderDeleteScriptFri13thTest.java
similarity index 98%
rename from
log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteScriptFri13thTest.java
rename to
log4j-script/src/test/java/org/apache/logging/log4j/script/appender/rolling/RollingAppenderDeleteScriptFri13thTest.java
index f192b4d..156a8d3 100644
---
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteScriptFri13thTest.java
+++
b/log4j-script/src/test/java/org/apache/logging/log4j/script/appender/rolling/RollingAppenderDeleteScriptFri13thTest.java
@@ -14,7 +14,7 @@
* See the license for the specific language governing permissions and
* limitations under the license.
*/
-package org.apache.logging.log4j.core.appender.rolling;
+package org.apache.logging.log4j.script.appender.rolling;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
diff --git
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteScriptTest.java
b/log4j-script/src/test/java/org/apache/logging/log4j/script/appender/rolling/RollingAppenderDeleteScriptTest.java
similarity index 97%
rename from
log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteScriptTest.java
rename to
log4j-script/src/test/java/org/apache/logging/log4j/script/appender/rolling/RollingAppenderDeleteScriptTest.java
index e218f6b..3de0996 100644
---
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteScriptTest.java
+++
b/log4j-script/src/test/java/org/apache/logging/log4j/script/appender/rolling/RollingAppenderDeleteScriptTest.java
@@ -14,7 +14,7 @@
* See the license for the specific language governing permissions and
* limitations under the license.
*/
-package org.apache.logging.log4j.core.appender.rolling;
+package org.apache.logging.log4j.script.appender.rolling;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
diff --git
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/ScriptConditionTest.java
b/log4j-script/src/test/java/org/apache/logging/log4j/script/appender/rolling/action/ScriptConditionTest.java
similarity index 88%
rename from
log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/ScriptConditionTest.java
rename to
log4j-script/src/test/java/org/apache/logging/log4j/script/appender/rolling/action/ScriptConditionTest.java
index a2f14b9..5374db7 100644
---
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/ScriptConditionTest.java
+++
b/log4j-script/src/test/java/org/apache/logging/log4j/script/appender/rolling/action/ScriptConditionTest.java
@@ -15,11 +15,13 @@
* limitations under the license.
*/
-package org.apache.logging.log4j.core.appender.rolling.action;
+package org.apache.logging.log4j.script.appender.rolling.action;
+import
org.apache.logging.log4j.core.appender.rolling.action.PathWithAttributes;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.DefaultConfiguration;
-import org.apache.logging.log4j.core.script.Script;
+import
org.apache.logging.log4j.core.test.appender.rolling.action.DummyFileAttributes;
+import org.apache.logging.log4j.script.ScriptPlugin;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledForJreRange;
@@ -45,7 +47,7 @@ public class ScriptConditionTest {
@Test
public void testConstructorDisallowsNullConfig() {
assertThrows(NullPointerException.class,
- () -> new ScriptCondition(new Script("test", "js",
"print('hi')"), null));
+ () -> new ScriptCondition(new ScriptPlugin("test", "js",
"print('hi')"), null));
}
@Test
@@ -56,7 +58,7 @@ public class ScriptConditionTest {
@Test
public void testCreateConditionDisallowsNullConfig() {
assertThrows(NullPointerException.class, () ->
ScriptCondition.createCondition(
- new Script("test", "js", "print('hi')"), null));
+ new ScriptPlugin("test", "js", "print('hi')"), null));
}
@Test
@@ -65,7 +67,7 @@ public class ScriptConditionTest {
final Configuration config = new DefaultConfiguration();
config.initialize(); // creates the ScriptManager
- final Script script = new Script("test", "javascript", "pathList;");
// script that returns pathList
+ final ScriptPlugin script = new ScriptPlugin("test", "javascript",
"pathList;"); // script that returns pathList
final ScriptCondition condition = new ScriptCondition(script, config);
final List<PathWithAttributes> pathList = new ArrayList<>();
final Path base = Paths.get("baseDirectory");
@@ -86,7 +88,7 @@ public class ScriptConditionTest {
final String scriptText = "pathList.remove(1);" //
+ "pathList;";
- final Script script = new Script("test", "javascript", scriptText);
+ final ScriptPlugin script = new ScriptPlugin("test", "javascript",
scriptText);
final ScriptCondition condition = new ScriptCondition(script, config);
final Path base = Paths.get("baseDirectory");
final List<PathWithAttributes> result =
condition.selectFilesToDelete(base, pathList);
@@ -128,7 +130,7 @@ public class ScriptConditionTest {
+ "}" //
+ "println copy;"
+ "copy;";
- final Script script = new Script("test", "groovy", scriptText);
+ final ScriptPlugin script = new ScriptPlugin("test", "groovy",
scriptText);
final ScriptCondition condition = new ScriptCondition(script, config);
final Path base = Paths.get("/path");
final List<PathWithAttributes> result =
condition.selectFilesToDelete(base, pathList);
diff --git
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/routing/DefaultRouteScriptAppenderTest.java
b/log4j-script/src/test/java/org/apache/logging/log4j/script/appender/routing/DefaultRouteScriptAppenderTest.java
similarity index 97%
rename from
log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/routing/DefaultRouteScriptAppenderTest.java
rename to
log4j-script/src/test/java/org/apache/logging/log4j/script/appender/routing/DefaultRouteScriptAppenderTest.java
index 1500342..01cd51f 100644
---
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/routing/DefaultRouteScriptAppenderTest.java
+++
b/log4j-script/src/test/java/org/apache/logging/log4j/script/appender/routing/DefaultRouteScriptAppenderTest.java
@@ -14,7 +14,7 @@
* See the license for the specific language governing permissions and
* limitations under the license.
*/
-package org.apache.logging.log4j.core.appender.routing;
+package org.apache.logging.log4j.script.appender.routing;
import java.util.Map;
import java.util.concurrent.ConcurrentMap;
@@ -22,6 +22,7 @@ import java.util.concurrent.ConcurrentMap;
import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.MarkerManager;
import org.apache.logging.log4j.core.Logger;
+import org.apache.logging.log4j.core.appender.routing.RoutingAppender;
import org.apache.logging.log4j.core.config.AppenderControl;
import org.apache.logging.log4j.core.test.junit.LoggerContextRule;
import org.apache.logging.log4j.core.test.appender.ListAppender;
diff --git
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/routing/RoutesScriptAppenderTest.java
b/log4j-script/src/test/java/org/apache/logging/log4j/script/appender/routing/RoutesScriptAppenderTest.java
similarity index 92%
rename from
log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/routing/RoutesScriptAppenderTest.java
rename to
log4j-script/src/test/java/org/apache/logging/log4j/script/appender/routing/RoutesScriptAppenderTest.java
index f092692..e7dd240 100644
---
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/routing/RoutesScriptAppenderTest.java
+++
b/log4j-script/src/test/java/org/apache/logging/log4j/script/appender/routing/RoutesScriptAppenderTest.java
@@ -14,7 +14,7 @@
* See the license for the specific language governing permissions and
* limitations under the license.
*/
-package org.apache.logging.log4j.core.appender.routing;
+package org.apache.logging.log4j.script.appender.routing;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertEquals;
@@ -26,6 +26,8 @@ import java.util.concurrent.ConcurrentMap;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.MarkerManager;
+import org.apache.logging.log4j.core.appender.routing.Routes;
+import org.apache.logging.log4j.core.appender.routing.RoutingAppender;
import org.apache.logging.log4j.core.test.categories.Scripts;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.Logger;
@@ -48,10 +50,10 @@ public class RoutesScriptAppenderTest {
public static Object[][] getParameters() {
// @formatter:off
return new Object[][] {
- { "log4j-routing-routes-script-groovy.xml", false },
- { "log4j-routing-routes-script-javascript.xml", false },
- { "log4j-routing-script-staticvars-javascript.xml", true },
- { "log4j-routing-script-staticvars-groovy.xml", true },
+ {"log4j-routing-routes-script-groovy.xml", false },
+ {"log4j-routing-routes-script-javascript.xml", false },
+ {"log4j-routing-script-staticvars-javascript.xml", true },
+ {"log4j-routing-script-staticvars-groovy.xml", true },
};
// @formatter:on
}
diff --git
a/log4j-script/src/test/java/org/apache/logging/log4j/script/config/TestConfigurator.java
b/log4j-script/src/test/java/org/apache/logging/log4j/script/config/TestConfigurator.java
new file mode 100644
index 0000000..e0ed655
--- /dev/null
+++
b/log4j-script/src/test/java/org/apache/logging/log4j/script/config/TestConfigurator.java
@@ -0,0 +1,79 @@
+/*
+ * 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.logging.log4j.script.config;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.core.Filter;
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.appender.ConsoleAppender;
+import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.core.config.Configurator;
+import
org.apache.logging.log4j.core.config.builder.api.AppenderComponentBuilder;
+import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilder;
+import
org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilderFactory;
+import org.apache.logging.log4j.core.config.builder.impl.BuiltConfiguration;
+import org.junit.jupiter.api.Test;
+
+import static org.apache.logging.log4j.core.test.hamcrest.MapMatchers.hasSize;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.equalTo;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+/**
+ * Test Configuration
+ */
+public class TestConfigurator {
+ @Test
+ public void testBuilderWithScripts() throws Exception {
+ final String script = "if
(logEvent.getLoggerName().equals(\"NoLocation\")) {\n" +
+ " return \"NoLocation\";\n" +
+ " } else if (logEvent.getMarker() != null &&
logEvent.getMarker().isInstanceOf(\"FLOW\")) {\n" +
+ " return \"Flow\";\n" +
+ " } else {\n" +
+ " return null;\n" +
+ " }";
+ final ConfigurationBuilder<BuiltConfiguration> builder =
ConfigurationBuilderFactory.newConfigurationBuilder();
+ builder.setStatusLevel(Level.ERROR);
+ builder.setConfigurationName("BuilderTest");
+ builder.add(builder.newScriptFile("filter.groovy",
"target/test-classes/scripts/filter.groovy").addIsWatched(true));
+ final AppenderComponentBuilder appenderBuilder =
builder.newAppender("Stdout", "CONSOLE").addAttribute("target",
+ ConsoleAppender.Target.SYSTEM_OUT);
+ appenderBuilder.add(builder.newLayout("PatternLayout").
+ addComponent(builder.newComponent("ScriptPatternSelector")
+ .addAttribute("defaultPattern", "[%-5level] %c{1.}
%C{1.}.%M.%L %msg%n")
+
.addComponent(builder.newComponent("PatternMatch").addAttribute("key",
"NoLocation")
+ .addAttribute("pattern", "[%-5level] %c{1.}
%msg%n"))
+
.addComponent(builder.newComponent("PatternMatch").addAttribute("key", "FLOW")
+ .addAttribute("pattern", "[%-5level] %c{1.}
====== %C{1.}.%M:%L %msg ======%n"))
+ .addComponent(builder.newComponent("selectorScript",
"Script", script).addAttribute("language", "beanshell"))));
+ appenderBuilder.add(builder.newFilter("ScriptFilter",
Filter.Result.DENY,
+
Filter.Result.NEUTRAL).addComponent(builder.newComponent("ScriptRef").addAttribute("ref",
"filter.groovy")));
+ builder.add(appenderBuilder);
+ builder.add(builder.newLogger("org.apache.logging.log4j", Level.DEBUG).
+ add(builder.newAppenderRef("Stdout")).
+ addAttribute("additivity", false));
+
builder.add(builder.newRootLogger(Level.ERROR).add(builder.newAppenderRef("Stdout")));
+ LoggerContext ctx = Configurator.initialize(builder.build());
+ final Configuration config = ctx.getConfiguration();
+ assertNotNull(config, "No configuration");
+ assertEquals("BuilderTest", config.getName(), "Unexpected
Configuration");
+ assertThat(config.getAppenders(), hasSize(equalTo(1)));
+ assertNotNull(config.getScriptManager().getScript("filter.groovy"),
"Filter script not found");
+ assertNotNull(config.getScriptManager().getScript("selectorScript"),
"pattern selector script not found");
+ }
+}
diff --git
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/config/arbiters/ScriptArbiterTest.java
b/log4j-script/src/test/java/org/apache/logging/log4j/script/config/arbiter/ScriptArbiterTest.java
similarity index 97%
rename from
log4j-core-test/src/test/java/org/apache/logging/log4j/core/config/arbiters/ScriptArbiterTest.java
rename to
log4j-script/src/test/java/org/apache/logging/log4j/script/config/arbiter/ScriptArbiterTest.java
index c64cfe8..b293dfa 100644
---
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/config/arbiters/ScriptArbiterTest.java
+++
b/log4j-script/src/test/java/org/apache/logging/log4j/script/config/arbiter/ScriptArbiterTest.java
@@ -14,7 +14,7 @@
* See the license for the specific language governing permissions and
* limitations under the license.
*/
-package org.apache.logging.log4j.core.config.arbiters;
+package org.apache.logging.log4j.script.config.arbiter;
import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.LoggerContext;
diff --git
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/filter/AbstractScriptFilterTest.java
b/log4j-script/src/test/java/org/apache/logging/log4j/script/filter/AbstractScriptFilterTest.java
similarity index 98%
rename from
log4j-core-test/src/test/java/org/apache/logging/log4j/core/filter/AbstractScriptFilterTest.java
rename to
log4j-script/src/test/java/org/apache/logging/log4j/script/filter/AbstractScriptFilterTest.java
index 155a314..20a5e8b 100644
---
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/filter/AbstractScriptFilterTest.java
+++
b/log4j-script/src/test/java/org/apache/logging/log4j/script/filter/AbstractScriptFilterTest.java
@@ -14,7 +14,7 @@
* See the license for the specific language governing permissions and
* limitations under the license.
*/
-package org.apache.logging.log4j.core.filter;
+package org.apache.logging.log4j.script.filter;
import java.util.List;
diff --git
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/filter/ScriptFileFilterPropertiesTest.java
b/log4j-script/src/test/java/org/apache/logging/log4j/script/filter/ScriptFileFilterPropertiesTest.java
similarity index 95%
rename from
log4j-core-test/src/test/java/org/apache/logging/log4j/core/filter/ScriptFileFilterPropertiesTest.java
rename to
log4j-script/src/test/java/org/apache/logging/log4j/script/filter/ScriptFileFilterPropertiesTest.java
index 1afc3c0..6bee68c 100644
---
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/filter/ScriptFileFilterPropertiesTest.java
+++
b/log4j-script/src/test/java/org/apache/logging/log4j/script/filter/ScriptFileFilterPropertiesTest.java
@@ -14,7 +14,7 @@
* See the license for the specific language governing permissions and
* limitations under the license.
*/
-package org.apache.logging.log4j.core.filter;
+package org.apache.logging.log4j.script.filter;
import org.apache.logging.log4j.core.test.junit.LoggerContextSource;
diff --git
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/filter/ScriptFileFilterTest.java
b/log4j-script/src/test/java/org/apache/logging/log4j/script/filter/ScriptFileFilterTest.java
similarity index 95%
rename from
log4j-core-test/src/test/java/org/apache/logging/log4j/core/filter/ScriptFileFilterTest.java
rename to
log4j-script/src/test/java/org/apache/logging/log4j/script/filter/ScriptFileFilterTest.java
index fca3e96..0e79b70 100644
---
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/filter/ScriptFileFilterTest.java
+++
b/log4j-script/src/test/java/org/apache/logging/log4j/script/filter/ScriptFileFilterTest.java
@@ -14,7 +14,7 @@
* See the license for the specific language governing permissions and
* limitations under the license.
*/
-package org.apache.logging.log4j.core.filter;
+package org.apache.logging.log4j.script.filter;
import org.apache.logging.log4j.core.test.junit.LoggerContextSource;
diff --git
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/filter/ScriptFilterTest.java
b/log4j-script/src/test/java/org/apache/logging/log4j/script/filter/ScriptFilterTest.java
similarity index 95%
rename from
log4j-core-test/src/test/java/org/apache/logging/log4j/core/filter/ScriptFilterTest.java
rename to
log4j-script/src/test/java/org/apache/logging/log4j/script/filter/ScriptFilterTest.java
index 368d438..9beac81 100644
---
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/filter/ScriptFilterTest.java
+++
b/log4j-script/src/test/java/org/apache/logging/log4j/script/filter/ScriptFilterTest.java
@@ -14,7 +14,7 @@
* See the license for the specific language governing permissions and
* limitations under the license.
*/
-package org.apache.logging.log4j.core.filter;
+package org.apache.logging.log4j.script.filter;
import org.apache.logging.log4j.core.test.junit.LoggerContextSource;
diff --git
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/filter/ScriptRefFilterTest.java
b/log4j-script/src/test/java/org/apache/logging/log4j/script/filter/ScriptRefFilterTest.java
similarity index 95%
rename from
log4j-core-test/src/test/java/org/apache/logging/log4j/core/filter/ScriptRefFilterTest.java
rename to
log4j-script/src/test/java/org/apache/logging/log4j/script/filter/ScriptRefFilterTest.java
index 9a07f24..0397858 100644
---
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/filter/ScriptRefFilterTest.java
+++
b/log4j-script/src/test/java/org/apache/logging/log4j/script/filter/ScriptRefFilterTest.java
@@ -14,7 +14,7 @@
* See the license for the specific language governing permissions and
* limitations under the license.
*/
-package org.apache.logging.log4j.core.filter;
+package org.apache.logging.log4j.script.filter;
import org.apache.logging.log4j.core.test.junit.LoggerContextSource;
diff --git
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/PatternSelectorTest.java
b/log4j-script/src/test/java/org/apache/logging/log4j/script/layout/PatternSelectorTest.java
similarity index 87%
rename from
log4j-core-test/src/test/java/org/apache/logging/log4j/core/PatternSelectorTest.java
rename to
log4j-script/src/test/java/org/apache/logging/log4j/script/layout/PatternSelectorTest.java
index afc91aa..c29779b 100644
---
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/PatternSelectorTest.java
+++
b/log4j-script/src/test/java/org/apache/logging/log4j/script/layout/PatternSelectorTest.java
@@ -14,7 +14,7 @@
* See the license for the specific language governing permissions and
* limitations under the license.
*/
-package org.apache.logging.log4j.core;
+package org.apache.logging.log4j.script.layout;
import java.util.List;
@@ -43,7 +43,7 @@ public class PatternSelectorTest {
assertEquals(3, messages.size(),
"Incorrect number of messages. Expected 3, Actual " +
messages.size() + ": " + messages);
final String expect = String.format("[TRACE] TestMarkerPatternSelector
====== "
- + "o.a.l.l.c.PatternSelectorTest.testMarkerPatternSelector:38
Enter ======%n");
+ +
"o.a.l.l.s.l.PatternSelectorTest.testMarkerPatternSelector:38 Enter ======%n");
assertEquals(expect, messages.get(0));
assertEquals("[INFO ] TestMarkerPatternSelector Hello World" +
Strings.LINE_SEPARATOR, messages.get(1));
app.clear();
@@ -63,9 +63,9 @@ public class PatternSelectorTest {
assertEquals(4, messages.size(),
"Incorrect number of messages. Expected 4, Actual " +
messages.size() + ": " + messages);
String expect = "[TRACE] TestScriptPatternSelector ====== " +
- "o.a.l.l.c.PatternSelectorTest.testScriptPatternSelector:57
Enter ======" + Strings.LINE_SEPARATOR;
+ "o.a.l.l.s.l.PatternSelectorTest.testScriptPatternSelector:57
Enter ======" + Strings.LINE_SEPARATOR;
assertEquals(expect, messages.get(0));
- expect = "[INFO ] TestScriptPatternSelector
o.a.l.l.c.PatternSelectorTest.testScriptPatternSelector.58 " +
+ expect = "[INFO ] TestScriptPatternSelector
o.a.l.l.s.l.PatternSelectorTest.testScriptPatternSelector.58 " +
"Hello World" + Strings.LINE_SEPARATOR;
assertEquals(expect, messages.get(1));
assertEquals("[INFO ] NoLocation No location information" +
Strings.LINE_SEPARATOR, messages.get(2));
@@ -86,10 +86,10 @@ public class PatternSelectorTest {
assertEquals(4, messages.size(),
"Incorrect number of messages. Expected 4, Actual " +
messages.size() + ": " + messages);
String expect = "[TRACE] TestJavaScriptPatternSelector ====== " +
-
"o.a.l.l.c.PatternSelectorTest.testJavaScriptPatternSelector:80 Enter ======" +
Strings.LINE_SEPARATOR;
+
"o.a.l.l.s.l.PatternSelectorTest.testJavaScriptPatternSelector:80 Enter ======"
+ Strings.LINE_SEPARATOR;
assertEquals(expect, messages.get(0));
expect = "[INFO ] TestJavaScriptPatternSelector " +
-
"o.a.l.l.c.PatternSelectorTest.testJavaScriptPatternSelector.81 Hello World" +
Strings.LINE_SEPARATOR;
+
"o.a.l.l.s.l.PatternSelectorTest.testJavaScriptPatternSelector.81 Hello World"
+ Strings.LINE_SEPARATOR;
assertEquals(expect, messages.get(1));
assertEquals("[INFO ] JavascriptNoLocation No location information" +
Strings.LINE_SEPARATOR, messages.get(2));
app.clear();
diff --git
a/log4j-core-test/src/test/resources/log4j-appender-selector-groovy.xml
b/log4j-script/src/test/resources/log4j-appender-selector-groovy.xml
similarity index 100%
rename from
log4j-core-test/src/test/resources/log4j-appender-selector-groovy.xml
rename to log4j-script/src/test/resources/log4j-appender-selector-groovy.xml
diff --git
a/log4j-core-test/src/test/resources/log4j-appender-selector-javascript.xml
b/log4j-script/src/test/resources/log4j-appender-selector-javascript.xml
similarity index 100%
rename from
log4j-core-test/src/test/resources/log4j-appender-selector-javascript.xml
rename to log4j-script/src/test/resources/log4j-appender-selector-javascript.xml
diff --git a/log4j-core-test/src/test/resources/log4j-patternSelector.xml
b/log4j-script/src/test/resources/log4j-patternSelector.xml
similarity index 100%
rename from log4j-core-test/src/test/resources/log4j-patternSelector.xml
rename to log4j-script/src/test/resources/log4j-patternSelector.xml
diff --git
a/log4j-core-test/src/test/resources/log4j-rolling-with-custom-delete-script-fri13th.xml
b/log4j-script/src/test/resources/log4j-rolling-with-custom-delete-script-fri13th.xml
similarity index 100%
rename from
log4j-core-test/src/test/resources/log4j-rolling-with-custom-delete-script-fri13th.xml
rename to
log4j-script/src/test/resources/log4j-rolling-with-custom-delete-script-fri13th.xml
diff --git
a/log4j-core-test/src/test/resources/log4j-rolling-with-custom-delete-script.xml
b/log4j-script/src/test/resources/log4j-rolling-with-custom-delete-script.xml
similarity index 100%
rename from
log4j-core-test/src/test/resources/log4j-rolling-with-custom-delete-script.xml
rename to
log4j-script/src/test/resources/log4j-rolling-with-custom-delete-script.xml
diff --git
a/log4j-core-test/src/test/resources/log4j-routing-default-route-script-groovy.xml
b/log4j-script/src/test/resources/log4j-routing-default-route-script-groovy.xml
similarity index 100%
rename from
log4j-core-test/src/test/resources/log4j-routing-default-route-script-groovy.xml
rename to
log4j-script/src/test/resources/log4j-routing-default-route-script-groovy.xml
diff --git
a/log4j-core-test/src/test/resources/log4j-routing-default-route-script-javascript.xml
b/log4j-script/src/test/resources/log4j-routing-default-route-script-javascript.xml
similarity index 100%
rename from
log4j-core-test/src/test/resources/log4j-routing-default-route-script-javascript.xml
rename to
log4j-script/src/test/resources/log4j-routing-default-route-script-javascript.xml
diff --git
a/log4j-core-test/src/test/resources/log4j-routing-routes-script-groovy.xml
b/log4j-script/src/test/resources/log4j-routing-routes-script-groovy.xml
similarity index 100%
rename from
log4j-core-test/src/test/resources/log4j-routing-routes-script-groovy.xml
rename to log4j-script/src/test/resources/log4j-routing-routes-script-groovy.xml
diff --git
a/log4j-core-test/src/test/resources/log4j-routing-routes-script-javascript.xml
b/log4j-script/src/test/resources/log4j-routing-routes-script-javascript.xml
similarity index 100%
rename from
log4j-core-test/src/test/resources/log4j-routing-routes-script-javascript.xml
rename to
log4j-script/src/test/resources/log4j-routing-routes-script-javascript.xml
diff --git
a/log4j-core-test/src/test/resources/log4j-routing-script-staticvars-groovy.xml
b/log4j-script/src/test/resources/log4j-routing-script-staticvars-groovy.xml
similarity index 100%
rename from
log4j-core-test/src/test/resources/log4j-routing-script-staticvars-groovy.xml
rename to
log4j-script/src/test/resources/log4j-routing-script-staticvars-groovy.xml
diff --git
a/log4j-core-test/src/test/resources/log4j-routing-script-staticvars-javascript.xml
b/log4j-script/src/test/resources/log4j-routing-script-staticvars-javascript.xml
similarity index 100%
rename from
log4j-core-test/src/test/resources/log4j-routing-script-staticvars-javascript.xml
rename to
log4j-script/src/test/resources/log4j-routing-script-staticvars-javascript.xml
diff --git a/log4j-core-test/src/test/resources/log4j-script-filters.xml
b/log4j-script/src/test/resources/log4j-script-filters.xml
similarity index 100%
rename from log4j-core-test/src/test/resources/log4j-script-filters.xml
rename to log4j-script/src/test/resources/log4j-script-filters.xml
diff --git
a/log4j-core-test/src/test/resources/log4j-scriptFile-filters.properties
b/log4j-script/src/test/resources/log4j-scriptFile-filters.properties
similarity index 100%
rename from
log4j-core-test/src/test/resources/log4j-scriptFile-filters.properties
rename to log4j-script/src/test/resources/log4j-scriptFile-filters.properties
diff --git a/log4j-core-test/src/test/resources/log4j-scriptFile-filters.xml
b/log4j-script/src/test/resources/log4j-scriptFile-filters.xml
similarity index 100%
rename from log4j-core-test/src/test/resources/log4j-scriptFile-filters.xml
rename to log4j-script/src/test/resources/log4j-scriptFile-filters.xml
diff --git a/log4j-core-test/src/test/resources/log4j-scriptRef-filters.xml
b/log4j-script/src/test/resources/log4j-scriptRef-filters.xml
similarity index 100%
rename from log4j-core-test/src/test/resources/log4j-scriptRef-filters.xml
rename to log4j-script/src/test/resources/log4j-scriptRef-filters.xml
diff --git a/log4j-core-test/src/test/resources/log4j2-scriptArbiters.xml
b/log4j-script/src/test/resources/log4j2-scriptArbiters.xml
similarity index 100%
rename from log4j-core-test/src/test/resources/log4j2-scriptArbiters.xml
rename to log4j-script/src/test/resources/log4j2-scriptArbiters.xml
diff --git a/log4j-core-test/src/test/resources/scripts/filter.groovy
b/log4j-script/src/test/resources/scripts/filter.groovy
similarity index 84%
rename from log4j-core-test/src/test/resources/scripts/filter.groovy
rename to log4j-script/src/test/resources/scripts/filter.groovy
index ef6998b..72f98e7 100644
--- a/log4j-core-test/src/test/resources/scripts/filter.groovy
+++ b/log4j-script/src/test/resources/scripts/filter.groovy
@@ -1 +1,3 @@
+package scripts
+
return logEvent.marker?.isInstanceOf('FLOW') ||
logEvent.contextData.containsKey('UserId')
diff --git a/log4j-core-test/src/test/resources/scripts/filter.js
b/log4j-script/src/test/resources/scripts/filter.js
similarity index 100%
rename from log4j-core-test/src/test/resources/scripts/filter.js
rename to log4j-script/src/test/resources/scripts/filter.js
diff --git a/pom.xml b/pom.xml
index 2ae785f..6e9b535 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1740,6 +1740,7 @@
<module>log4j-jpl</module>
<module>log4j-liquibase</module>
<module>log4j-appserver</module>
+ <module>log4j-script</module>
<module>log4j-smtp</module>
<module>log4j-osgi</module>
<module>log4j-docker</module>
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 187d6bd..943fadc 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -31,6 +31,9 @@
- "remove" - Removed
-->
<release version="3.0.0" date="2021-MM-DD" description="GA Release 3.0.0">
+ <action issue="LOG4J2-3307" dev="rgoers" type="update">
+ Move Scripting to its own module.
+ </action>
<action issue="LOG4J2-3242" dev="rgoers" type="fix">
Move JNDI to its own module.
</action>
diff --git a/src/site/asciidoc/manual/appenders.adoc
b/src/site/asciidoc/manual/appenders.adoc
index f19195e..a246de6 100644
--- a/src/site/asciidoc/manual/appenders.adoc
+++ b/src/site/asciidoc/manual/appenders.adoc
@@ -4107,7 +4107,7 @@ Appender in a link:#FailoverAppender[FailoverAppender].
== ScriptAppenderSelector
When the configuration is built, the `ScriptAppenderSelector` appender
-calls a `Script` to compute an appender name. Log4j then creates one of
+calls a `ScriptPlugin` to compute an appender name. Log4j then creates one of
the appender named listed under `AppenderSet` using the name of the
`ScriptAppenderSelector`. After configuration, Log4j ignores the
`ScriptAppenderSelector`. Log4j only builds the one selected appender
diff --git a/src/site/asciidoc/manual/filters.adoc
b/src/site/asciidoc/manual/filters.adoc
index 5a61201..7a1ade7 100644
--- a/src/site/asciidoc/manual/filters.adoc
+++ b/src/site/asciidoc/manual/filters.adoc
@@ -580,7 +580,7 @@ Throwable as part of the Message.
The sample below shows how to declare script fields and then reference
them in specific components. See
link:appenders.html#ScriptCondition[ScriptCondition] for an example of
-how the `Script` element can be used to embed script code directly in
+how the `ScriptPlugin` element can be used to embed script code directly in
the configuration.
[source,xml]