You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by pk...@apache.org on 2024/12/27 17:14:19 UTC
(logging-admin) branch main created (now 363c0c4)
This is an automated email from the ASF dual-hosted git repository.
pkarwasz pushed a change to branch main
in repository https://gitbox.apache.org/repos/asf/logging-admin.git
at 363c0c4 Add unit tests
This branch includes the following new commits:
new 5a8053f Initial commit
new 8ef61ac Setup repository configuration
new 16e8404 Add Maven wrapper
new 3ed39b3 Initial implementation of the Apache Logging Admin API
new 0ad3df2 Add short README.adoc
new dceaeb4 Improve logger context detection in JUL
new 046c6b4 Merge into a single module.
new 363c0c4 Add unit tests
The 8 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
(logging-admin) 06/08: Improve logger context detection in JUL
Posted by pk...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
pkarwasz pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/logging-admin.git
commit dceaeb4447572cb6809c56c29fb2562537adec19
Author: Piotr P. Karwasz <pi...@karwasz.org>
AuthorDate: Sat Nov 2 19:52:51 2024 +0100
Improve logger context detection in JUL
---
.../java/org/apache/logging/admin/jul/internal/JulAdmin.java | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/jul/src/main/java/org/apache/logging/admin/jul/internal/JulAdmin.java b/jul/src/main/java/org/apache/logging/admin/jul/internal/JulAdmin.java
index 40a2314..ecb833e 100644
--- a/jul/src/main/java/org/apache/logging/admin/jul/internal/JulAdmin.java
+++ b/jul/src/main/java/org/apache/logging/admin/jul/internal/JulAdmin.java
@@ -31,7 +31,6 @@ import org.jspecify.annotations.Nullable;
class JulAdmin implements LoggingConfigurationAdmin {
- private static final Object GLOBAL_CONTEXT = new Object();
private static final Set<String> levels = Stream.of(
Level.ALL,
Level.FINEST,
@@ -54,7 +53,13 @@ class JulAdmin implements LoggingConfigurationAdmin {
@Override
public Object getLoggerContext() {
- return GLOBAL_CONTEXT;
+ // Implementations that support multiple logger contexts can be recognized by having multiple root loggers.
+ ClassLoader oldClassLoader = updateThreadContextClassLoader(classLoader);
+ try {
+ return Logger.getLogger("");
+ } finally {
+ updateThreadContextClassLoader(oldClassLoader);
+ }
}
@Override
(logging-admin) 01/08: Initial commit
Posted by pk...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
pkarwasz pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/logging-admin.git
commit 5a8053fd2a3819df518df181b1c50ab1feda0286
Author: Piotr P. Karwasz <pi...@github.copernik.eu>
AuthorDate: Sat Nov 2 09:22:37 2024 +0100
Initial commit
---
LICENSE | 201 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 201 insertions(+)
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..261eeb9
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed 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.
(logging-admin) 04/08: Initial implementation of the Apache Logging Admin API
Posted by pk...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
pkarwasz pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/logging-admin.git
commit 3ed39b389d367b76eed8de3f69f3a06847bc2cf4
Author: Piotr P. Karwasz <pi...@karwasz.org>
AuthorDate: Sat Nov 2 11:26:39 2024 +0100
Initial implementation of the Apache Logging Admin API
The API supports the following three backends:
- `java.util.logging`,
- Logback,
- Log4j Core.
---
.mvn/jvm.config | 11 ++
api/pom.xml | 33 ++++--
.../logging/admin/LoggingConfigurationAdmin.java | 129 +++++++++++++++++++++
.../logging/admin/internal/FactoryHolder.java | 79 +++++++++++++
.../logging/admin/internal/package-info.java | 20 ++++
.../org/apache/logging/admin/package-info.java | 20 ++++
.../spi/LoggingConfigurationAdminFactory.java | 43 +++++++
.../org/apache/logging/admin/spi/package-info.java | 20 ++++
jul/pom.xml | 42 +++++--
.../logging/admin/jul/internal/JulAdmin.java | 112 ++++++++++++++++++
.../logging/admin/jul/internal/JulFactory.java | 35 ++++++
.../logging/admin/jul/internal/package-info.java | 20 ++++
log4j-core/pom.xml | 49 ++++++--
.../logging/admin/log4j/internal/CoreAdmin.java | 100 ++++++++++++++++
.../logging/admin/log4j/internal/CoreFactory.java | 39 +++++++
.../logging/admin/log4j/internal/package-info.java | 20 ++++
logback/pom.xml | 48 ++++++--
.../admin/logback/internal/LogbackAdmin.java | 72 ++++++++++++
.../admin/logback/internal/LogbackFactory.java | 34 ++++++
.../admin/logback/internal/package-info.java | 20 ++++
parent/pom.xml | 71 ++++++++++--
pom.xml | 63 +++++-----
22 files changed, 1019 insertions(+), 61 deletions(-)
diff --git a/.mvn/jvm.config b/.mvn/jvm.config
new file mode 100644
index 0000000..f3b9f7d
--- /dev/null
+++ b/.mvn/jvm.config
@@ -0,0 +1,11 @@
+--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED
+--add-opens jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED
+--add-opens jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED
+-Dfile.encoding=UTF-8
diff --git a/api/pom.xml b/api/pom.xml
index f84b48f..ae5bc61 100644
--- a/api/pom.xml
+++ b/api/pom.xml
@@ -1,15 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to you under the Apache License, Version 2.0
+ ~ (the "License"); you may not use this file except in compliance with
+ ~ the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
- <groupId>org.apache.logging.log4j</groupId>
- <artifactId>log4j-config-admin-parent</artifactId>
+ <groupId>org.apache.logging.admin</groupId>
+ <artifactId>logging-admin-parent</artifactId>
<version>${revision}</version>
<relativePath>../parent</relativePath>
</parent>
- <artifactId>log4j-config-admin-api</artifactId>
+ <artifactId>logging-admin-api</artifactId>
+ <name>Apache Logging Admin: API</name>
+ <description>Implementation independent API to modify logging implementation</description>
-</project>
\ No newline at end of file
+ <properties>
+ <bnd-module-name>org.apache.logging.admin.api</bnd-module-name>
+ </properties>
+</project>
diff --git a/api/src/main/java/org/apache/logging/admin/LoggingConfigurationAdmin.java b/api/src/main/java/org/apache/logging/admin/LoggingConfigurationAdmin.java
new file mode 100644
index 0000000..0e366f1
--- /dev/null
+++ b/api/src/main/java/org/apache/logging/admin/LoggingConfigurationAdmin.java
@@ -0,0 +1,129 @@
+/*
+ * 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.admin;
+
+import static java.util.Objects.requireNonNull;
+
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import org.apache.logging.admin.internal.FactoryHolder;
+import org.jspecify.annotations.Nullable;
+
+/**
+ * The {@code LoggingConfigurationAdmin} interface provides a logging implementation independent support to:
+ * <ul>
+ * <li>Query the logging implementation for the configured level of each logger.</li>
+ * <li>Change the configured level of a logger.</li>
+ * </ul>
+ *
+ * <h2>Usage</h2>
+ *
+ * <p>
+ * This API should only be used by Java applications or libraries dedicated to the modification of logging configuration.
+ * For this purpose, the API features security tokens that prevent other libraries from accessing it.
+ * </p>
+ * <p>
+ * An example application of this API is to modify the level of the root logger, based on CLI parameters:
+ * </p>
+ * <pre>
+ * public final class Main {
+ * private static final Object TOKEN = new Object();
+ *
+ * public static void main(String[] args) {
+ * if (args.length == 2 && "--logLevel".equals(args[0])) {
+ * LoggingConfigurationAdmin admin = LoggingConfigurationAdmin.getInstance(TOKEN);
+ * admin.setLoggerLevel("", args[1]);
+ * }
+ * }
+ * }
+ * </pre>
+ */
+public interface LoggingConfigurationAdmin {
+
+ /**
+ * The logger context that this interface will be configuring.
+ *
+ * @return A logger context.
+ */
+ Object getLoggerContext();
+
+ /**
+ * The names of the available log levels.
+ */
+ Set<String> getSupportedLevels();
+
+ /**
+ * A map associating logger names with the configured log levels.
+ * <p>
+ * Loggers that inherit their configuration from the parent logger will be associated with {@link Optional#empty()}.
+ * </p>
+ */
+ Map<String, Optional<String>> getLoggerLevels();
+
+ /**
+ * The configured log level for the given logger.
+ * <p>
+ * If a logger inherits its configuration from its parent, {@link Optional#empty()} will be returned.
+ * </p>
+ * @param loggerName The name of the logger.
+ */
+ Optional<String> getLoggerLevel(String loggerName);
+
+ /**
+ * Sets the level for a logger.
+ *
+ * @param loggerName The name of the logger.
+ * @param level The level to use or {@code null} to inherit the level of the parent logger.
+ */
+ void setLoggerLevel(String loggerName, @Nullable String level);
+
+ /**
+ * Retrieves the logging configuration admin for the given classloader.
+ * <p>
+ * If {@code token} is not null, it also sets a security token for the appropriate logger context.
+ * All future invocations of this method will need to use the same token.
+ * Tokens are compared using object equality.
+ * </p>
+ * @param token The security token.
+ * @param classLoader A class loader.
+ * @return A logging configuration admin.
+ * @throws IllegalStateException If no implementation of the Apache Logging Admin API is present on the classpath.
+ * @throws SecurityException If a security token is set for the associated logger context and the provided token
+ * does not match.
+ */
+ static LoggingConfigurationAdmin getInstance(Object token, ClassLoader classLoader) {
+ return FactoryHolder.getLoggingConfigurationAdmin(requireNonNull(token), requireNonNull(classLoader));
+ }
+
+ /**
+ * Retrieves the logging configuration admin for the classloader that loaded this class.
+ * <p>
+ * If {@code token} is not null, it also sets a security token for the appropriate logger context.
+ * All future invocations of this method will need to use the same token.
+ * Tokens are compared using object equality.
+ * </p>
+ * @return A logging configuration admin.
+ * @throws IllegalStateException If no implementation of the Apache Logging Admin API is present on the classpath.
+ * @throws SecurityException If a security token is set for the associated logger context and the provided token
+ * does not match.
+ */
+ static LoggingConfigurationAdmin getInstance(Object token) {
+ return FactoryHolder.getLoggingConfigurationAdmin(
+ requireNonNull(token), LoggingConfigurationAdmin.class.getClassLoader());
+ }
+}
diff --git a/api/src/main/java/org/apache/logging/admin/internal/FactoryHolder.java b/api/src/main/java/org/apache/logging/admin/internal/FactoryHolder.java
new file mode 100644
index 0000000..e42b784
--- /dev/null
+++ b/api/src/main/java/org/apache/logging/admin/internal/FactoryHolder.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.admin.internal;
+
+import aQute.bnd.annotation.Cardinality;
+import aQute.bnd.annotation.Resolution;
+import aQute.bnd.annotation.spi.ServiceConsumer;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Map;
+import java.util.ServiceLoader;
+import java.util.WeakHashMap;
+import java.util.concurrent.locks.ReentrantLock;
+import org.apache.logging.admin.LoggingConfigurationAdmin;
+import org.apache.logging.admin.spi.LoggingConfigurationAdminFactory;
+
+@ServiceConsumer(
+ value = LoggingConfigurationAdminFactory.class,
+ cardinality = Cardinality.MULTIPLE,
+ resolution = Resolution.MANDATORY)
+public final class FactoryHolder {
+
+ private static final Collection<LoggingConfigurationAdminFactory> factories = new ArrayList<>();
+ private static final ReentrantLock lock = new ReentrantLock();
+ private static final Map<ClassLoader, LoggingConfigurationAdmin> instances = new WeakHashMap<>();
+ private static final Map<Object, Object> tokensByLoggerContext = new WeakHashMap<>();
+
+ static {
+ ServiceLoader.load(LoggingConfigurationAdminFactory.class, FactoryHolder.class.getClassLoader())
+ .forEach(factories::add);
+ }
+
+ private static void checkSecurityToken(Object token, Object loggerContext) {
+ Object oldToken = tokensByLoggerContext.get(loggerContext);
+ if (oldToken == null) {
+ tokensByLoggerContext.put(loggerContext, token);
+ return;
+ }
+ if (token != oldToken) {
+ throw new SecurityException("Security token changed from " + oldToken + " to " + token);
+ }
+ }
+
+ public static LoggingConfigurationAdmin getLoggingConfigurationAdmin(Object token, ClassLoader classLoader) {
+ lock.lock();
+ try {
+ LoggingConfigurationAdmin instance = instances.get(classLoader);
+ if (instance == null) {
+ instance = factories.stream()
+ .filter(f -> f.isActive(classLoader))
+ .findAny()
+ .map(f -> f.createLoggingConfigurationAdmin(classLoader))
+ .orElseThrow(() -> new IllegalStateException(
+ "No " + LoggingConfigurationAdminFactory.class.getName() + " found."));
+ instances.put(classLoader, instance);
+ }
+ checkSecurityToken(token, instance.getLoggerContext());
+ return instance;
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ private FactoryHolder() {}
+}
diff --git a/api/src/main/java/org/apache/logging/admin/internal/package-info.java b/api/src/main/java/org/apache/logging/admin/internal/package-info.java
new file mode 100644
index 0000000..6d73df2
--- /dev/null
+++ b/api/src/main/java/org/apache/logging/admin/internal/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+@NullMarked
+package org.apache.logging.admin.internal;
+
+import org.jspecify.annotations.NullMarked;
diff --git a/api/src/main/java/org/apache/logging/admin/package-info.java b/api/src/main/java/org/apache/logging/admin/package-info.java
new file mode 100644
index 0000000..be36b44
--- /dev/null
+++ b/api/src/main/java/org/apache/logging/admin/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+@NullMarked
+package org.apache.logging.admin;
+
+import org.jspecify.annotations.NullMarked;
diff --git a/api/src/main/java/org/apache/logging/admin/spi/LoggingConfigurationAdminFactory.java b/api/src/main/java/org/apache/logging/admin/spi/LoggingConfigurationAdminFactory.java
new file mode 100644
index 0000000..e10fd90
--- /dev/null
+++ b/api/src/main/java/org/apache/logging/admin/spi/LoggingConfigurationAdminFactory.java
@@ -0,0 +1,43 @@
+/*
+ * 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.admin.spi;
+
+import org.apache.logging.admin.LoggingConfigurationAdmin;
+
+/**
+ * Factory class for {@link LoggingConfigurationAdmin} instances.
+ * <p>
+ * Implementations of this class should be registered using {@link java.util.ServiceLoader}.
+ * </p>
+ */
+public interface LoggingConfigurationAdminFactory {
+
+ /**
+ * Determines whether the logging system handled by this factory is used.
+ *
+ * @param classLoader The class loader associated with the logger context.
+ */
+ boolean isActive(ClassLoader classLoader);
+
+ /**
+ * Creates a new {@link LoggingConfigurationAdmin} instance associated with the given classloader.
+ *
+ * @param classLoader The class loader associated with the logger context.
+ * @return A new instance of {@link LoggingConfigurationAdmin}.
+ */
+ LoggingConfigurationAdmin createLoggingConfigurationAdmin(ClassLoader classLoader);
+}
diff --git a/api/src/main/java/org/apache/logging/admin/spi/package-info.java b/api/src/main/java/org/apache/logging/admin/spi/package-info.java
new file mode 100644
index 0000000..ab19b30
--- /dev/null
+++ b/api/src/main/java/org/apache/logging/admin/spi/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+@NullMarked
+package org.apache.logging.admin.spi;
+
+import org.jspecify.annotations.NullMarked;
diff --git a/jul/pom.xml b/jul/pom.xml
index 44d4c9e..c9545e2 100644
--- a/jul/pom.xml
+++ b/jul/pom.xml
@@ -1,15 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to you under the Apache License, Version 2.0
+ ~ (the "License"); you may not use this file except in compliance with
+ ~ the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
- <groupId>org.apache.logging.log4j</groupId>
- <artifactId>log4j-config-admin-parent</artifactId>
+ <groupId>org.apache.logging.admin</groupId>
+ <artifactId>logging-admin-parent</artifactId>
<version>${revision}</version>
<relativePath>../parent</relativePath>
</parent>
- <artifactId>log4j-config-admin-jul</artifactId>
+ <artifactId>logging-admin-jul</artifactId>
+ <name>Apache Logging Admin: JUL implementation</name>
+ <description>Implementation of the Apache Logging Admin API for `java.util.logging`.</description>
-</project>
\ No newline at end of file
+ <properties>
+ <bnd-module-name>org.apache.logging.admin.jul</bnd-module-name>
+ </properties>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.apache.logging.admin</groupId>
+ <artifactId>logging-admin-api</artifactId>
+ </dependency>
+
+ </dependencies>
+</project>
diff --git a/jul/src/main/java/org/apache/logging/admin/jul/internal/JulAdmin.java b/jul/src/main/java/org/apache/logging/admin/jul/internal/JulAdmin.java
new file mode 100644
index 0000000..40a2314
--- /dev/null
+++ b/jul/src/main/java/org/apache/logging/admin/jul/internal/JulAdmin.java
@@ -0,0 +1,112 @@
+/*
+ * 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.admin.jul.internal;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.LogManager;
+import java.util.logging.Logger;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import org.apache.logging.admin.LoggingConfigurationAdmin;
+import org.jspecify.annotations.Nullable;
+
+class JulAdmin implements LoggingConfigurationAdmin {
+
+ private static final Object GLOBAL_CONTEXT = new Object();
+ private static final Set<String> levels = Stream.of(
+ Level.ALL,
+ Level.FINEST,
+ Level.FINER,
+ Level.FINE,
+ Level.CONFIG,
+ Level.INFO,
+ Level.WARNING,
+ Level.SEVERE,
+ Level.OFF)
+ .map(Level::toString)
+ .collect(Collectors.toSet());
+
+ private final LogManager logManager = LogManager.getLogManager();
+ private final ClassLoader classLoader;
+
+ JulAdmin(final ClassLoader classLoader) {
+ this.classLoader = classLoader;
+ }
+
+ @Override
+ public Object getLoggerContext() {
+ return GLOBAL_CONTEXT;
+ }
+
+ @Override
+ public Set<String> getSupportedLevels() {
+ return levels;
+ }
+
+ @Override
+ public Map<String, Optional<String>> getLoggerLevels() {
+ ClassLoader oldClassLoader = updateThreadContextClassLoader(classLoader);
+ try {
+ final Map<String, Optional<String>> loggerLevels = new HashMap<>();
+ for (final String loggerName : Collections.list(logManager.getLoggerNames())) {
+ loggerLevels.computeIfAbsent(loggerName, this::getLoggerLevel);
+ }
+ return loggerLevels;
+ } finally {
+ updateThreadContextClassLoader(oldClassLoader);
+ }
+ }
+
+ @Override
+ public Optional<String> getLoggerLevel(String loggerName) {
+ ClassLoader oldClassLoader = updateThreadContextClassLoader(classLoader);
+ try {
+ return Optional.ofNullable(logManager.getLogger(loggerName))
+ .map(Logger::getLevel)
+ .map(Level::getName);
+ } finally {
+ updateThreadContextClassLoader(oldClassLoader);
+ }
+ }
+
+ private Optional<String> doGetLoggerLevel(String loggerName) {
+ return Optional.ofNullable(logManager.getLogger(loggerName))
+ .map(Logger::getLevel)
+ .map(Level::getName);
+ }
+
+ @Override
+ public void setLoggerLevel(String loggerName, @Nullable String level) {
+ ClassLoader oldClassLoader = updateThreadContextClassLoader(classLoader);
+ try {
+ logManager.getLogger(loggerName).setLevel(level != null ? Level.parse(level) : null);
+ } finally {
+ updateThreadContextClassLoader(oldClassLoader);
+ }
+ }
+
+ private static ClassLoader updateThreadContextClassLoader(final ClassLoader classLoader) {
+ ClassLoader old = Thread.currentThread().getContextClassLoader();
+ Thread.currentThread().setContextClassLoader(classLoader);
+ return old;
+ }
+}
diff --git a/jul/src/main/java/org/apache/logging/admin/jul/internal/JulFactory.java b/jul/src/main/java/org/apache/logging/admin/jul/internal/JulFactory.java
new file mode 100644
index 0000000..baff61b
--- /dev/null
+++ b/jul/src/main/java/org/apache/logging/admin/jul/internal/JulFactory.java
@@ -0,0 +1,35 @@
+/*
+ * 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.admin.jul.internal;
+
+import aQute.bnd.annotation.spi.ServiceProvider;
+import org.apache.logging.admin.LoggingConfigurationAdmin;
+import org.apache.logging.admin.spi.LoggingConfigurationAdminFactory;
+
+@ServiceProvider(LoggingConfigurationAdminFactory.class)
+public class JulFactory implements LoggingConfigurationAdminFactory {
+
+ @Override
+ public boolean isActive(ClassLoader classLoader) {
+ return true;
+ }
+
+ @Override
+ public LoggingConfigurationAdmin createLoggingConfigurationAdmin(ClassLoader classLoader) {
+ return new JulAdmin(classLoader);
+ }
+}
diff --git a/jul/src/main/java/org/apache/logging/admin/jul/internal/package-info.java b/jul/src/main/java/org/apache/logging/admin/jul/internal/package-info.java
new file mode 100644
index 0000000..cbca3c2
--- /dev/null
+++ b/jul/src/main/java/org/apache/logging/admin/jul/internal/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+@NullMarked
+package org.apache.logging.admin.jul.internal;
+
+import org.jspecify.annotations.NullMarked;
diff --git a/log4j-core/pom.xml b/log4j-core/pom.xml
index ef27846..4953404 100644
--- a/log4j-core/pom.xml
+++ b/log4j-core/pom.xml
@@ -1,15 +1,50 @@
<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to you under the Apache License, Version 2.0
+ ~ (the "License"); you may not use this file except in compliance with
+ ~ the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
- <groupId>org.apache.logging.log4j</groupId>
- <artifactId>log4j-config-admin-parent</artifactId>
+ <groupId>org.apache.logging.admin</groupId>
+ <artifactId>logging-admin-parent</artifactId>
<version>${revision}</version>
<relativePath>../parent</relativePath>
</parent>
- <artifactId>log4j-config-admin-log4j-core</artifactId>
+ <artifactId>logging-admin-log4j-core</artifactId>
+ <name>Apache Logging Admin: Log4j Core implementation</name>
+ <description>Implementation of the Apache Logging Admin API for Log4j Core.</description>
-</project>
\ No newline at end of file
+ <properties>
+ <bnd-module-name>org.apache.logging.admin.log4j</bnd-module-name>
+ </properties>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.apache.logging.admin</groupId>
+ <artifactId>logging-admin-api</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-core</artifactId>
+ <version>2.24.1</version>
+ </dependency>
+
+ </dependencies>
+
+</project>
diff --git a/log4j-core/src/main/java/org/apache/logging/admin/log4j/internal/CoreAdmin.java b/log4j-core/src/main/java/org/apache/logging/admin/log4j/internal/CoreAdmin.java
new file mode 100644
index 0000000..43393d2
--- /dev/null
+++ b/log4j-core/src/main/java/org/apache/logging/admin/log4j/internal/CoreAdmin.java
@@ -0,0 +1,100 @@
+/*
+ * 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.admin.log4j.internal;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import org.apache.logging.admin.LoggingConfigurationAdmin;
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.core.config.LoggerConfig;
+import org.apache.logging.log4j.core.util.NameUtil;
+import org.jspecify.annotations.Nullable;
+
+class CoreAdmin implements LoggingConfigurationAdmin {
+
+ private final LoggerContext loggerContext;
+
+ CoreAdmin(LoggerContext loggerContext) {
+ this.loggerContext = loggerContext;
+ }
+
+ @Override
+ public Object getLoggerContext() {
+ return loggerContext;
+ }
+
+ @Override
+ public Set<String> getSupportedLevels() {
+ return Stream.of(Level.values()).map(Level::name).collect(Collectors.toSet());
+ }
+
+ @Override
+ public Map<String, Optional<String>> getLoggerLevels() {
+ Map<String, Optional<String>> loggerLevels = new HashMap<>();
+ // Insert the ancestors of all existing loggers
+ loggerContext.getLoggers().forEach(logger -> fillLoggerLevels(logger.getName(), loggerLevels));
+ // Insert the ancestors of all existing logger configurations
+ loggerContext
+ .getConfiguration()
+ .getLoggers()
+ .keySet()
+ .forEach(loggerName -> fillLoggerLevels(loggerName, loggerLevels));
+ return loggerLevels;
+ }
+
+ @Override
+ public Optional<String> getLoggerLevel(String loggerName) {
+ Configuration config = loggerContext.getConfiguration();
+ return Optional.of(config.getLoggerConfig(loggerName))
+ .filter(lc -> loggerName.equals(lc.getName()))
+ .map(LoggerConfig::getLevel)
+ .map(Level::name);
+ }
+
+ @Override
+ public void setLoggerLevel(String loggerName, @Nullable String level) {
+ boolean changed;
+ Configuration config = loggerContext.getConfiguration();
+ Level levelObj = level != null ? Level.valueOf(level) : null;
+ LoggerConfig loggerConfig = config.getLoggerConfig(loggerName);
+ if (!loggerName.equals(loggerConfig.getName())) {
+ loggerConfig = new LoggerConfig(loggerName, levelObj, true);
+ config.addLogger(loggerName, loggerConfig);
+ changed = true;
+ } else {
+ changed = Objects.equals(levelObj, loggerConfig.getLevel());
+ loggerConfig.setLevel(levelObj);
+ }
+ if (changed) {
+ loggerContext.updateLoggers();
+ }
+ }
+
+ private void fillLoggerLevels(String loggerName, Map<String, Optional<String>> loggerLevels) {
+ String currentName = loggerName;
+ while (currentName != null && loggerLevels.computeIfAbsent(currentName, this::getLoggerLevel) == null) {
+ currentName = NameUtil.getSubName(currentName);
+ }
+ }
+}
diff --git a/log4j-core/src/main/java/org/apache/logging/admin/log4j/internal/CoreFactory.java b/log4j-core/src/main/java/org/apache/logging/admin/log4j/internal/CoreFactory.java
new file mode 100644
index 0000000..a1c8db5
--- /dev/null
+++ b/log4j-core/src/main/java/org/apache/logging/admin/log4j/internal/CoreFactory.java
@@ -0,0 +1,39 @@
+/*
+ * 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.admin.log4j.internal;
+
+import aQute.bnd.annotation.spi.ServiceProvider;
+import org.apache.logging.admin.LoggingConfigurationAdmin;
+import org.apache.logging.admin.spi.LoggingConfigurationAdminFactory;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.spi.LoggerContext;
+
+@ServiceProvider(value = LoggingConfigurationAdminFactory.class)
+public class CoreFactory implements LoggingConfigurationAdminFactory {
+
+ @Override
+ public boolean isActive(ClassLoader classLoader) {
+ LoggerContext loggerContext = LogManager.getContext(classLoader, false);
+ return loggerContext instanceof org.apache.logging.log4j.core.LoggerContext;
+ }
+
+ @Override
+ public LoggingConfigurationAdmin createLoggingConfigurationAdmin(ClassLoader classLoader) {
+ LoggerContext loggerContext = LogManager.getContext(classLoader, false);
+ return new CoreAdmin((org.apache.logging.log4j.core.LoggerContext) loggerContext);
+ }
+}
diff --git a/log4j-core/src/main/java/org/apache/logging/admin/log4j/internal/package-info.java b/log4j-core/src/main/java/org/apache/logging/admin/log4j/internal/package-info.java
new file mode 100644
index 0000000..9cd5c0c
--- /dev/null
+++ b/log4j-core/src/main/java/org/apache/logging/admin/log4j/internal/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+@NullMarked
+package org.apache.logging.admin.log4j.internal;
+
+import org.jspecify.annotations.NullMarked;
diff --git a/logback/pom.xml b/logback/pom.xml
index c1862e5..313fa04 100644
--- a/logback/pom.xml
+++ b/logback/pom.xml
@@ -1,15 +1,49 @@
<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to you under the Apache License, Version 2.0
+ ~ (the "License"); you may not use this file except in compliance with
+ ~ the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
- <groupId>org.apache.logging.log4j</groupId>
- <artifactId>log4j-config-admin-parent</artifactId>
+ <groupId>org.apache.logging.admin</groupId>
+ <artifactId>logging-admin-parent</artifactId>
<version>${revision}</version>
<relativePath>../parent</relativePath>
</parent>
- <artifactId>log4j-config-admin-logback</artifactId>
+ <artifactId>logging-admin-logback</artifactId>
+ <name>Apache Logging Admin: Logback</name>
+ <description>Implementation of the Apache Logging Admin API for Logback.</description>
-</project>
\ No newline at end of file
+ <properties>
+ <bnd-module-name>org.apache.logging.admin.logback</bnd-module-name>
+ </properties>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.apache.logging.admin</groupId>
+ <artifactId>logging-admin-api</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-classic</artifactId>
+ <version>1.5.11</version>
+ </dependency>
+
+ </dependencies>
+</project>
diff --git a/logback/src/main/java/org/apache/logging/admin/logback/internal/LogbackAdmin.java b/logback/src/main/java/org/apache/logging/admin/logback/internal/LogbackAdmin.java
new file mode 100644
index 0000000..477cca2
--- /dev/null
+++ b/logback/src/main/java/org/apache/logging/admin/logback/internal/LogbackAdmin.java
@@ -0,0 +1,72 @@
+/*
+ * 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.admin.logback.internal;
+
+import ch.qos.logback.classic.Level;
+import ch.qos.logback.classic.Logger;
+import ch.qos.logback.classic.LoggerContext;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import org.apache.logging.admin.LoggingConfigurationAdmin;
+import org.jspecify.annotations.Nullable;
+
+class LogbackAdmin implements LoggingConfigurationAdmin {
+
+ private static final Set<String> levels = Stream.of(
+ Level.TRACE, Level.DEBUG, Level.INFO, Level.WARN, Level.ERROR, Level.OFF)
+ .map(Level::toString)
+ .collect(Collectors.toSet());
+
+ private final LoggerContext loggerContext;
+
+ @Override
+ public Object getLoggerContext() {
+ return loggerContext;
+ }
+
+ LogbackAdmin(final LoggerContext loggerContext) {
+ this.loggerContext = loggerContext;
+ }
+
+ @Override
+ public Set<String> getSupportedLevels() {
+ return levels;
+ }
+
+ @Override
+ public Map<String, Optional<String>> getLoggerLevels() {
+ return loggerContext.getLoggerList().stream()
+ .collect(Collectors.toMap(Logger::getName, LogbackAdmin::getLoggerLevel));
+ }
+
+ @Override
+ public Optional<String> getLoggerLevel(String loggerName) {
+ return getLoggerLevel(loggerContext.getLogger(loggerName));
+ }
+
+ private static Optional<String> getLoggerLevel(ch.qos.logback.classic.Logger logger) {
+ return Optional.ofNullable(logger.getLevel()).map(Level::toString);
+ }
+
+ @Override
+ public void setLoggerLevel(String loggerName, @Nullable String level) {
+ loggerContext.getLogger(loggerName).setLevel(level != null ? Level.valueOf(level) : null);
+ }
+}
diff --git a/logback/src/main/java/org/apache/logging/admin/logback/internal/LogbackFactory.java b/logback/src/main/java/org/apache/logging/admin/logback/internal/LogbackFactory.java
new file mode 100644
index 0000000..44dc5e1
--- /dev/null
+++ b/logback/src/main/java/org/apache/logging/admin/logback/internal/LogbackFactory.java
@@ -0,0 +1,34 @@
+/*
+ * 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.admin.logback.internal;
+
+import ch.qos.logback.classic.LoggerContext;
+import org.apache.logging.admin.LoggingConfigurationAdmin;
+import org.apache.logging.admin.spi.LoggingConfigurationAdminFactory;
+import org.slf4j.LoggerFactory;
+
+public class LogbackFactory implements LoggingConfigurationAdminFactory {
+ @Override
+ public boolean isActive(ClassLoader classLoader) {
+ return LoggerFactory.getILoggerFactory() instanceof ch.qos.logback.classic.LoggerContext;
+ }
+
+ @Override
+ public LoggingConfigurationAdmin createLoggingConfigurationAdmin(ClassLoader classLoader) {
+ return new LogbackAdmin((LoggerContext) LoggerFactory.getILoggerFactory());
+ }
+}
diff --git a/logback/src/main/java/org/apache/logging/admin/logback/internal/package-info.java b/logback/src/main/java/org/apache/logging/admin/logback/internal/package-info.java
new file mode 100644
index 0000000..9155808
--- /dev/null
+++ b/logback/src/main/java/org/apache/logging/admin/logback/internal/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+@NullMarked
+package org.apache.logging.admin.logback.internal;
+
+import org.jspecify.annotations.NullMarked;
diff --git a/parent/pom.xml b/parent/pom.xml
index 74849ad..d4bf5fb 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -1,15 +1,72 @@
<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to you under the Apache License, Version 2.0
+ ~ (the "License"); you may not use this file except in compliance with
+ ~ the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
- <groupId>org.apache.logging.log4j</groupId>
- <artifactId>log4j-config-admin-bom</artifactId>
+ <groupId>org.apache.logging.admin</groupId>
+ <artifactId>logging-admin-bom</artifactId>
<version>${revision}</version>
</parent>
- <artifactId>log4j-config-admin-parent</artifactId>
+ <artifactId>logging-admin-parent</artifactId>
<packaging>pom</packaging>
+ <name>Apache Logging Admin: Parent</name>
-</project>
\ No newline at end of file
+ <properties>
+ <!-- Ignore BND Baseline until the first release -->
+ <bnd.baseline.skip>true</bnd.baseline.skip>
+ </properties>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.jspecify</groupId>
+ <artifactId>jspecify</artifactId>
+ <version>1.0.0</version>
+ </dependency>
+
+ <dependency>
+ <groupId>biz.aQute.bnd</groupId>
+ <artifactId>biz.aQute.bnd.annotation</artifactId>
+ <version>7.0.0</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.annotation.bundle</artifactId>
+ <version>2.0.0</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.annotation.versioning</artifactId>
+ <version>1.1.2</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>com.github.spotbugs</groupId>
+ <artifactId>spotbugs-annotations</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ </dependencies>
+
+</project>
diff --git a/pom.xml b/pom.xml
index 7573eb3..f64a94f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,8 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
- child.project.url.inherit.append.path="false">
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to you under the Apache License, Version 2.0
+ ~ (the "License"); you may not use this file except in compliance with
+ ~ the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" child.project.url.inherit.append.path="false" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<!-- ██ ██ █████ ██████ ███ ██ ██ ███ ██ ██████ ██
██ ██ ██ ██ ██ ██ ████ ██ ██ ████ ██ ██ ██
@@ -10,8 +23,8 @@
██ ███ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
███ ███ ██ ██ ██ ██ ██ ████ ██ ██ ████ ██████ ██
- `log4j-config-admin` project modules should use `log4j-config-admin-parent` as their parents, not this POM!
- This POM constitutes the BOM to be imported by applications using `log4j-config-admin` project modules. -->
+ `logging-admin` project modules should use `logging-admin-parent` as their parents, not this POM!
+ This POM constitutes the BOM to be imported by applications using `logging-admin` project modules. -->
<modelVersion>4.0.0</modelVersion>
@@ -21,8 +34,8 @@
<version>10.5.0</version>
</parent>
- <groupId>org.apache.logging.log4j</groupId>
- <artifactId>log4j-config-admin-bom</artifactId>
+ <groupId>org.apache.logging.admin</groupId>
+ <artifactId>logging-admin-bom</artifactId>
<version>${revision}</version>
<packaging>pom</packaging>
@@ -53,26 +66,25 @@
</modules>
- <scm child.scm.connection.inherit.append.path="false" child.scm.developerConnection.inherit.append.path="false"
- child.scm.url.inherit.append.path="false">
- <connection>scm:git:git@github.com:apache/logging-log4j-config-admin.git</connection>
- <developerConnection>scm:git:git@github.com:apache/logging-log4j-config-admin.git</developerConnection>
+ <scm child.scm.connection.inherit.append.path="false" child.scm.developerConnection.inherit.append.path="false" child.scm.url.inherit.append.path="false">
+ <connection>scm:git:git@github.com:apache/logging-logging-admin.git</connection>
+ <developerConnection>scm:git:git@github.com:apache/logging-logging-admin.git</developerConnection>
<tag>HEAD</tag>
- <url>https://github.com/apache/logging-log4j-config-admin</url>
+ <url>https://github.com/apache/logging-admin</url>
</scm>
<issueManagement>
<system>GitHub Issues</system>
- <url>https://github.com/apache/logging-log4j-config-admin/issues</url>
+ <url>https://github.com/apache/logging-admin/issues</url>
</issueManagement>
<ciManagement>
<system>GitHub Actions</system>
- <url>https://github.com/apache/logging-log4j-config-admin/actions</url>
+ <url>https://github.com/apache/logging-admin/actions</url>
</ciManagement>
<distributionManagement>
- <downloadUrl>https://logging.apache.org/log4j/config-admin/latest/#distribution</downloadUrl>
+ <downloadUrl>https://logging.apache.org/admin/#distribution</downloadUrl>
</distributionManagement>
<properties>
@@ -86,33 +98,32 @@
</properties>
-
<!-- `dependencyManagement` must only contain `log4j-transform` modules and nothing else!
Modules here must have a corresponding entry in `modules` block above! -->
<dependencyManagement>
<dependencies>
<dependency>
- <groupId>org.apache.logging.log4j</groupId>
- <artifactId>log4j-config-admin-api</artifactId>
+ <groupId>org.apache.logging.admin</groupId>
+ <artifactId>logging-admin-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
- <groupId>org.apache.logging.log4j</groupId>
- <artifactId>log4j-config-admin-jul</artifactId>
+ <groupId>org.apache.logging.admin</groupId>
+ <artifactId>logging-admin-jul</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
- <groupId>org.apache.logging.log4j</groupId>
- <artifactId>log4j-config-admin-log4j-core</artifactId>
+ <groupId>org.apache.logging.admin</groupId>
+ <artifactId>logging-admin-log4j-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
- <groupId>org.apache.logging.log4j</groupId>
- <artifactId>log4j-config-admin-logback</artifactId>
+ <groupId>org.apache.logging.admin</groupId>
+ <artifactId>logging-admin-logback</artifactId>
<version>${project.version}</version>
</dependency>
@@ -142,4 +153,4 @@
</plugins>
</build>
-</project>
\ No newline at end of file
+</project>
(logging-admin) 08/08: Add unit tests
Posted by pk...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
pkarwasz pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/logging-admin.git
commit 363c0c4ef78fbcf97385d9f0f2bb3403efb5ea85
Author: Piotr P. Karwasz <pi...@karwasz.org>
AuthorDate: Sun Nov 3 19:21:25 2024 +0100
Add unit tests
---
README.adoc | 2 +-
pom.xml | 120 ++++++++++++++++++-
.../org/apache/logging/admin/LoggingAdmin.java | 54 +++------
.../logging/admin/internal/FactoryHolder.java | 79 -------------
.../apache/logging/admin/internal/FactoryUtil.java | 53 +++++++++
.../apache/logging/admin/internal/JulAdmin.java | 131 +++++++++++++++++++++
.../{jul/JulFactory.java => JulAdminFactory.java} | 23 +++-
.../{log4j/CoreAdmin.java => Log4jCoreAdmin.java} | 64 +++++++---
...CoreFactory.java => Log4jCoreAdminFactory.java} | 24 ++--
.../logging/admin/internal/LogbackAdmin.java | 103 ++++++++++++++++
.../{logback => }/LogbackAdminFactory.java | 23 ++--
.../logging/admin/internal/jul/JulAdmin.java | 117 ------------------
.../admin/internal/logback/LogbackAdmin.java | 72 -----------
.../org/apache/logging/admin/package-info.java | 4 +
.../logging/admin/spi/LoggingAdminFactory.java | 26 ++--
.../org/apache/logging/admin/spi/package-info.java | 4 +
.../org/apache/logging/admin/LoggingAdminTest.java | 111 +++++++++++++++++
src/test/resources/log4j2.xml | 28 +++++
src/test/resources/logback.xml | 22 ++++
src/test/resources/logging.properties | 19 +++
20 files changed, 718 insertions(+), 361 deletions(-)
diff --git a/README.adoc b/README.adoc
index e8df97e..eb361d2 100644
--- a/README.adoc
+++ b/README.adoc
@@ -30,7 +30,7 @@ public final class Main {
while (i < args.length) {
if ("--logLevel".equals(args[i]) && ++i < args.length) {
LoggingAdmin admin = LoggingAdmin.getInstance(TOKEN);
- admin.setLoggerLevel("", args[i]);
+ admin.setLevel("", args[i]);
}
i++;
}
diff --git a/pom.xml b/pom.xml
index ac6eef5..93fd52e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -70,12 +70,44 @@
<!-- project version -->
<revision>0.1.0-SNAPSHOT</revision>
+ <!-- Ignore BND Baseline until the first release -->
+ <bnd.baseline.skip>true</bnd.baseline.skip>
+
+ <bnd-module-name>org.apache.logging.admin</bnd-module-name>
+ <bnd-extra-package-options>
+ <!-- Optional dependencies -->
+ ch.qos.logback.*;resolution:=optional,
+ java.util.logging;resolution:=optional,
+ org.slf4j;resolution:=optional,
+ org.apache.logging.log4j.*;resolution:=optional,
+ </bnd-extra-package-options>
+
<!-- disable `maven-site-plugin`-->
<maven.site.skip>true</maven.site.skip>
<maven.site.deploy.skip>true</maven.site.deploy.skip>
</properties>
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.assertj</groupId>
+ <artifactId>assertj-bom</artifactId>
+ <version>3.26.3</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.junit</groupId>
+ <artifactId>junit-bom</artifactId>
+ <version>5.11.3</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
<dependencies>
<dependency>
@@ -99,12 +131,6 @@
<scope>provided</scope>
</dependency>
- <dependency>
- <groupId>com.github.spotbugs</groupId>
- <artifactId>spotbugs-annotations</artifactId>
- <scope>provided</scope>
- </dependency>
-
<dependency>
<groupId>org.jspecify</groupId>
<artifactId>jspecify</artifactId>
@@ -125,5 +151,87 @@
<optional>true</optional>
</dependency>
+ <dependency>
+ <groupId>org.assertj</groupId>
+ <artifactId>assertj-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter-api</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter-params</artifactId>
+ <scope>test</scope>
+ </dependency>
+
</dependencies>
+
+ <build>
+ <plugins>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <executions>
+ <!-- Disable default execution to properly name each execution -->
+ <execution>
+ <id>default-test</id>
+ <phase>none</phase>
+ </execution>
+ <execution>
+ <id>jul-test</id>
+ <goals>
+ <goal>test</goal>
+ </goals>
+ <configuration>
+ <classpathDependencyExcludes>
+ <exclude>ch.qos.logback:*</exclude>
+ <exclude>org.apache.logging.log4j:*</exclude>
+ <exclude>org.slf4j:*</exclude>
+ </classpathDependencyExcludes>
+ <systemPropertyVariables>
+ <admin.implementation>jul</admin.implementation>
+ <java.util.logging.config.file>${project.basedir}/src/test/resources/logging.properties</java.util.logging.config.file>
+ </systemPropertyVariables>
+ </configuration>
+ </execution>
+ <execution>
+ <id>log4j-core-test</id>
+ <goals>
+ <goal>test</goal>
+ </goals>
+ <configuration>
+ <classpathDependencyExcludes>
+ <exclude>ch.qos.logback:*</exclude>
+ <exclude>org.slf4j:*</exclude>
+ </classpathDependencyExcludes>
+ <systemPropertyVariables>
+ <admin.implementation>log4j-core</admin.implementation>
+ </systemPropertyVariables>
+ </configuration>
+ </execution>
+ <execution>
+ <id>logback-test</id>
+ <goals>
+ <goal>test</goal>
+ </goals>
+ <configuration>
+ <classpathDependencyExcludes>
+ <exclude>org.apache.logging.log4j:*</exclude>
+ </classpathDependencyExcludes>
+ <systemPropertyVariables>
+ <admin.implementation>logback</admin.implementation>
+ </systemPropertyVariables>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+
+ </plugins>
+ </build>
</project>
diff --git a/src/main/java/org/apache/logging/admin/LoggingAdmin.java b/src/main/java/org/apache/logging/admin/LoggingAdmin.java
index ce2be20..0954b05 100644
--- a/src/main/java/org/apache/logging/admin/LoggingAdmin.java
+++ b/src/main/java/org/apache/logging/admin/LoggingAdmin.java
@@ -16,11 +16,11 @@
*/
package org.apache.logging.admin;
+import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
-import java.util.Set;
-import org.apache.logging.admin.internal.FactoryHolder;
+import org.apache.logging.admin.internal.FactoryUtil;
import org.jspecify.annotations.Nullable;
/**
@@ -48,7 +48,7 @@ import org.jspecify.annotations.Nullable;
* while (i < args.length) {
* if ("--logLevel".equals(args[i]) && ++i < args.length) {
* LoggingAdmin admin = LoggingAdmin.getInstance(TOKEN);
- * admin.setLoggerLevel("", args[i]);
+ * admin.setLevel("", args[i]);
* }
* i++;
* }
@@ -57,26 +57,23 @@ import org.jspecify.annotations.Nullable;
* </pre>
*/
public interface LoggingAdmin {
-
/**
- * The logger context that this interface will be configuring.
- *
- * @return A logger context.
+ * Implementation independent name for the root logger.
*/
- Object getLoggerContext();
+ String ROOT_LOGGER_NAME = "";
/**
- * The names of the available log levels.
+ * The names of the available log levels in decreasing severity order.
*/
- Set<String> getSupportedLevels();
+ List<String> getSupportedLevels();
/**
* A map associating logger names with the configured log levels.
* <p>
- * Loggers that inherit their configuration from the parent logger will be associated with {@link Optional#empty()}.
+ * Loggers that inherit their configuration from the parent logger will be associated with {@code null}.
* </p>
*/
- Map<String, Optional<String>> getLoggerLevels();
+ Map<String, @Nullable String> getLevels();
/**
* The configured log level for the given logger.
@@ -85,7 +82,8 @@ public interface LoggingAdmin {
* </p>
* @param loggerName The name of the logger.
*/
- Optional<String> getLoggerLevel(String loggerName);
+ @Nullable
+ String getLevel(String loggerName);
/**
* Sets the level for a logger.
@@ -93,41 +91,21 @@ public interface LoggingAdmin {
* @param loggerName The name of the logger.
* @param level The level to use or {@code null} to inherit the level of the parent logger.
*/
- void setLoggerLevel(String loggerName, @Nullable String level);
-
- /**
- * Retrieves the logging configuration admin for the given classloader.
- * <p>
- * If {@code token} is not null, it also sets a security token for the appropriate logger context.
- * All future invocations of this method will need to use the same token.
- * Tokens are compared using object equality.
- * </p>
- * @param token The security token.
- * @param classLoader A class loader.
- * @return A logging configuration admin.
- * @throws IllegalStateException If no implementation of the Apache Logging Admin API is present on the classpath.
- * @throws SecurityException If a security token is set for the associated logger context and the provided token
- * does not match.
- */
- static LoggingAdmin getInstance(Object token, ClassLoader classLoader) {
- return FactoryHolder.getLoggingConfigurationAdmin(
- Objects.requireNonNull(token), Objects.requireNonNull(classLoader));
- }
+ void setLevel(String loggerName, @Nullable String level);
/**
- * Retrieves the logging configuration admin for the classloader that loaded this class.
+ * Retrieves the logging configuration admin appropriate for the caller
* <p>
- * If {@code token} is not null, it also sets a security token for the appropriate logger context.
+ * The {@code token} parameter sets a security token for the appropriate logger context.
* All future invocations of this method will need to use the same token.
* Tokens are compared using object equality.
* </p>
+ * @param token Any Java object.
* @return A logging configuration admin.
- * @throws IllegalStateException If no implementation of the Apache Logging Admin API is present on the classpath.
* @throws SecurityException If a security token is set for the associated logger context and the provided token
* does not match.
*/
static LoggingAdmin getInstance(Object token) {
- return FactoryHolder.getLoggingConfigurationAdmin(
- Objects.requireNonNull(token), LoggingAdmin.class.getClassLoader());
+ return FactoryUtil.getLoggingAdmin(Objects.requireNonNull(token));
}
}
diff --git a/src/main/java/org/apache/logging/admin/internal/FactoryHolder.java b/src/main/java/org/apache/logging/admin/internal/FactoryHolder.java
deleted file mode 100644
index 08a94c3..0000000
--- a/src/main/java/org/apache/logging/admin/internal/FactoryHolder.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * 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.admin.internal;
-
-import aQute.bnd.annotation.Cardinality;
-import aQute.bnd.annotation.Resolution;
-import aQute.bnd.annotation.spi.ServiceConsumer;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Map;
-import java.util.ServiceLoader;
-import java.util.WeakHashMap;
-import java.util.concurrent.locks.ReentrantLock;
-import org.apache.logging.admin.LoggingAdmin;
-import org.apache.logging.admin.spi.LoggingAdminFactory;
-
-@ServiceConsumer(
- value = LoggingAdminFactory.class,
- cardinality = Cardinality.MULTIPLE,
- resolution = Resolution.MANDATORY)
-public final class FactoryHolder {
-
- private static final Collection<LoggingAdminFactory> factories = new ArrayList<>();
- private static final ReentrantLock lock = new ReentrantLock();
- private static final Map<ClassLoader, LoggingAdmin> instances = new WeakHashMap<>();
- private static final Map<Object, Object> tokensByLoggerContext = new WeakHashMap<>();
-
- static {
- ServiceLoader.load(LoggingAdminFactory.class, FactoryHolder.class.getClassLoader())
- .forEach(factories::add);
- }
-
- private static void checkSecurityToken(Object token, Object loggerContext) {
- Object oldToken = tokensByLoggerContext.get(loggerContext);
- if (oldToken == null) {
- tokensByLoggerContext.put(loggerContext, token);
- return;
- }
- if (token != oldToken) {
- throw new SecurityException("Security token changed from " + oldToken + " to " + token);
- }
- }
-
- public static LoggingAdmin getLoggingConfigurationAdmin(Object token, ClassLoader classLoader) {
- lock.lock();
- try {
- LoggingAdmin instance = instances.get(classLoader);
- if (instance == null) {
- instance = factories.stream()
- .filter(f -> f.isActive(classLoader))
- .findAny()
- .map(f -> f.createLoggingConfigurationAdmin(classLoader))
- .orElseThrow(() ->
- new IllegalStateException("No " + LoggingAdminFactory.class.getName() + " found."));
- instances.put(classLoader, instance);
- }
- checkSecurityToken(token, instance.getLoggerContext());
- return instance;
- } finally {
- lock.unlock();
- }
- }
-
- private FactoryHolder() {}
-}
diff --git a/src/main/java/org/apache/logging/admin/internal/FactoryUtil.java b/src/main/java/org/apache/logging/admin/internal/FactoryUtil.java
new file mode 100644
index 0000000..5719b57
--- /dev/null
+++ b/src/main/java/org/apache/logging/admin/internal/FactoryUtil.java
@@ -0,0 +1,53 @@
+/*
+ * 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.admin.internal;
+
+import aQute.bnd.annotation.Cardinality;
+import aQute.bnd.annotation.Resolution;
+import aQute.bnd.annotation.spi.ServiceConsumer;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.ServiceLoader;
+import org.apache.logging.admin.LoggingAdmin;
+import org.apache.logging.admin.spi.LoggingAdminFactory;
+
+@ServiceConsumer(
+ value = LoggingAdminFactory.class,
+ cardinality = Cardinality.MULTIPLE,
+ resolution = Resolution.MANDATORY)
+public final class FactoryUtil {
+
+ private static final Collection<LoggingAdminFactory> factories = new ArrayList<>();
+
+ static {
+ ServiceLoader.load(LoggingAdminFactory.class, FactoryUtil.class.getClassLoader())
+ .forEach(factories::add);
+ }
+
+ public static LoggingAdmin getLoggingAdmin(Object token) {
+ LoggingAdminFactory factory = factories.stream()
+ .filter(LoggingAdminFactory::isActive)
+ .sorted(Comparator.comparing(LoggingAdminFactory::getPriority))
+ .findAny()
+ .orElseThrow(() ->
+ new IllegalStateException("No active " + LoggingAdminFactory.class.getName() + " found."));
+ return factory.getLoggingAdmin(token);
+ }
+
+ private FactoryUtil() {}
+}
diff --git a/src/main/java/org/apache/logging/admin/internal/JulAdmin.java b/src/main/java/org/apache/logging/admin/internal/JulAdmin.java
new file mode 100644
index 0000000..5d49388
--- /dev/null
+++ b/src/main/java/org/apache/logging/admin/internal/JulAdmin.java
@@ -0,0 +1,131 @@
+/*
+ * 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.admin.internal;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.WeakHashMap;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.logging.Level;
+import java.util.logging.LogManager;
+import java.util.logging.Logger;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import org.apache.logging.admin.LoggingAdmin;
+import org.jspecify.annotations.Nullable;
+
+class JulAdmin implements LoggingAdmin {
+
+ private static final ReentrantLock lock = new ReentrantLock();
+ private static final Map<Logger, Object> tokensByRootLogger = new WeakHashMap<>();
+
+ private static final List<String> levels = Collections.unmodifiableList(Stream.of(
+ Level.OFF,
+ Level.SEVERE,
+ Level.WARNING,
+ Level.INFO,
+ Level.CONFIG,
+ Level.FINE,
+ Level.FINER,
+ Level.FINEST,
+ Level.ALL)
+ .map(Level::toString)
+ .collect(Collectors.toList()));
+
+ private final LogManager logManager = LogManager.getLogManager();
+ private final Logger rootLogger;
+
+ JulAdmin(Logger rootLogger) {
+ this.rootLogger = rootLogger;
+ }
+
+ @Override
+ public List<String> getSupportedLevels() {
+ return levels;
+ }
+
+ @Override
+ public Map<String, @Nullable String> getLevels() {
+ final Map<String, @Nullable String> loggerLevels = new HashMap<>();
+ Collections.list(logManager.getLoggerNames()).forEach(loggerName -> fillLoggerLevels(loggerName, loggerLevels));
+ return loggerLevels;
+ }
+
+ @Override
+ public @Nullable String getLevel(String loggerName) {
+ return Optional.ofNullable(logManager.getLogger(loggerName))
+ .map(Logger::getLevel)
+ .map(Level::getName)
+ .orElse(null);
+ }
+
+ @Override
+ public void setLevel(String loggerName, @Nullable String level) {
+ Logger logger = logManager.getLogger(loggerName);
+ Logger rootLogger = findRootLogger(logger);
+ // Prevents setting the log level of a different "logger context"
+ if (this.rootLogger.equals(rootLogger)) {
+ logger.setLevel(level != null ? Level.parse(level) : null);
+ }
+ }
+
+ private void fillLoggerLevels(String loggerName, Map<String, @Nullable String> loggerLevels) {
+ String currentName = loggerName;
+ while (loggerLevels.putIfAbsent(currentName, getLevel(currentName)) == null) {
+ if (currentName.isEmpty()) {
+ break;
+ }
+ int idx = currentName.lastIndexOf('.');
+ currentName = idx == -1 ? "" : currentName.substring(0, idx);
+ }
+ }
+
+ private static Logger findRootLogger(Logger logger) {
+ Logger current = logger;
+ while (current != null) {
+ if ("".equals(current.getName()) || current.getParent() == null) {
+ return current;
+ }
+ current = current.getParent();
+ }
+ throw new IllegalStateException("Unable to find root logger for " + logger);
+ }
+
+ /**
+ * Checks if the `java.logging` module is present.
+ * @throws LinkageError If `java.logging` is absent.
+ */
+ static boolean isActive() {
+ return LogManager.getLogManager() != null;
+ }
+
+ static LoggingAdmin newInstance(Object token) {
+ lock.lock();
+ try {
+ Logger rootLogger = Logger.getLogger("");
+ if (tokensByRootLogger.computeIfAbsent(rootLogger, k -> token) != token) {
+ throw new SecurityException("The security token does not match: " + token);
+ }
+ return new JulAdmin(rootLogger);
+ } finally {
+ lock.unlock();
+ }
+ }
+}
diff --git a/src/main/java/org/apache/logging/admin/internal/jul/JulFactory.java b/src/main/java/org/apache/logging/admin/internal/JulAdminFactory.java
similarity index 67%
rename from src/main/java/org/apache/logging/admin/internal/jul/JulFactory.java
rename to src/main/java/org/apache/logging/admin/internal/JulAdminFactory.java
index 7c257df..d0d22dc 100644
--- a/src/main/java/org/apache/logging/admin/internal/jul/JulFactory.java
+++ b/src/main/java/org/apache/logging/admin/internal/JulAdminFactory.java
@@ -14,22 +14,33 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.logging.admin.internal.jul;
+package org.apache.logging.admin.internal;
import aQute.bnd.annotation.spi.ServiceProvider;
import org.apache.logging.admin.LoggingAdmin;
import org.apache.logging.admin.spi.LoggingAdminFactory;
+/**
+ * Logging admin factory for `java.util.logging`.
+ */
@ServiceProvider(LoggingAdminFactory.class)
-public class JulFactory implements LoggingAdminFactory {
+public class JulAdminFactory implements LoggingAdminFactory {
+ @Override
+ public int getPriority() {
+ return Integer.MAX_VALUE;
+ }
@Override
- public boolean isActive(ClassLoader classLoader) {
- return true;
+ public boolean isActive() {
+ try {
+ return JulAdmin.isActive();
+ } catch (LinkageError e) {
+ return false;
+ }
}
@Override
- public LoggingAdmin createLoggingConfigurationAdmin(ClassLoader classLoader) {
- return new JulAdmin(classLoader);
+ public LoggingAdmin getLoggingAdmin(Object token) {
+ return JulAdmin.newInstance(token);
}
}
diff --git a/src/main/java/org/apache/logging/admin/internal/log4j/CoreAdmin.java b/src/main/java/org/apache/logging/admin/internal/Log4jCoreAdmin.java
similarity index 59%
rename from src/main/java/org/apache/logging/admin/internal/log4j/CoreAdmin.java
rename to src/main/java/org/apache/logging/admin/internal/Log4jCoreAdmin.java
index 7edd685..3ed3a99 100644
--- a/src/main/java/org/apache/logging/admin/internal/log4j/CoreAdmin.java
+++ b/src/main/java/org/apache/logging/admin/internal/Log4jCoreAdmin.java
@@ -14,44 +14,45 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.logging.admin.internal.log4j;
+package org.apache.logging.admin.internal;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
-import java.util.Set;
+import java.util.WeakHashMap;
+import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.logging.admin.LoggingAdmin;
import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.LoggerConfig;
import org.apache.logging.log4j.core.util.NameUtil;
import org.jspecify.annotations.Nullable;
-class CoreAdmin implements LoggingAdmin {
+class Log4jCoreAdmin implements LoggingAdmin {
+
+ private static final ReentrantLock lock = new ReentrantLock();
+ private static final Map<LoggerContext, Object> tokensByLoggerContext = new WeakHashMap<>();
private final LoggerContext loggerContext;
- CoreAdmin(LoggerContext loggerContext) {
+ Log4jCoreAdmin(LoggerContext loggerContext) {
this.loggerContext = loggerContext;
}
@Override
- public Object getLoggerContext() {
- return loggerContext;
- }
-
- @Override
- public Set<String> getSupportedLevels() {
- return Stream.of(Level.values()).map(Level::name).collect(Collectors.toSet());
+ public List<String> getSupportedLevels() {
+ return Stream.of(Level.values()).sorted().map(Level::name).collect(Collectors.toList());
}
@Override
- public Map<String, Optional<String>> getLoggerLevels() {
- Map<String, Optional<String>> loggerLevels = new HashMap<>();
+ public Map<String, @Nullable String> getLevels() {
+ Map<String, @Nullable String> loggerLevels = new HashMap<>();
// Insert the ancestors of all existing loggers
loggerContext.getLoggers().forEach(logger -> fillLoggerLevels(logger.getName(), loggerLevels));
// Insert the ancestors of all existing logger configurations
@@ -64,16 +65,17 @@ class CoreAdmin implements LoggingAdmin {
}
@Override
- public Optional<String> getLoggerLevel(String loggerName) {
+ public @Nullable String getLevel(String loggerName) {
Configuration config = loggerContext.getConfiguration();
return Optional.of(config.getLoggerConfig(loggerName))
.filter(lc -> loggerName.equals(lc.getName()))
.map(LoggerConfig::getLevel)
- .map(Level::name);
+ .map(Level::name)
+ .orElse(null);
}
@Override
- public void setLoggerLevel(String loggerName, @Nullable String level) {
+ public void setLevel(String loggerName, @Nullable String level) {
boolean changed;
Configuration config = loggerContext.getConfiguration();
Level levelObj = level != null ? Level.valueOf(level) : null;
@@ -91,10 +93,36 @@ class CoreAdmin implements LoggingAdmin {
}
}
- private void fillLoggerLevels(String loggerName, Map<String, Optional<String>> loggerLevels) {
+ private void fillLoggerLevels(String loggerName, Map<String, @Nullable String> loggerLevels) {
String currentName = loggerName;
- while (currentName != null && loggerLevels.computeIfAbsent(currentName, this::getLoggerLevel) == null) {
+ while (currentName != null && loggerLevels.putIfAbsent(currentName, getLevel(currentName)) == null) {
currentName = NameUtil.getSubName(currentName);
}
}
+
+ static boolean isActive() {
+ org.apache.logging.log4j.spi.LoggerContext loggerContext = PrivateLogManager.getContext();
+ return loggerContext instanceof org.apache.logging.log4j.core.LoggerContext;
+ }
+
+ static LoggingAdmin newInstance(Object token) {
+ lock.lock();
+ try {
+ LoggerContext loggerContext = (LoggerContext) PrivateLogManager.getContext();
+ if (tokensByLoggerContext.computeIfAbsent(loggerContext, k -> token) != token) {
+ throw new SecurityException("The security token does not match: " + token);
+ }
+ return new Log4jCoreAdmin(loggerContext);
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ private static final class PrivateLogManager extends LogManager {
+ private PrivateLogManager() {}
+
+ public static org.apache.logging.log4j.spi.LoggerContext getContext() {
+ return LogManager.getContext(LoggingAdmin.class.getName(), false);
+ }
+ }
}
diff --git a/src/main/java/org/apache/logging/admin/internal/log4j/CoreFactory.java b/src/main/java/org/apache/logging/admin/internal/Log4jCoreAdminFactory.java
similarity index 60%
rename from src/main/java/org/apache/logging/admin/internal/log4j/CoreFactory.java
rename to src/main/java/org/apache/logging/admin/internal/Log4jCoreAdminFactory.java
index 9b9c82a..8f46127 100644
--- a/src/main/java/org/apache/logging/admin/internal/log4j/CoreFactory.java
+++ b/src/main/java/org/apache/logging/admin/internal/Log4jCoreAdminFactory.java
@@ -14,26 +14,30 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.logging.admin.internal.log4j;
+package org.apache.logging.admin.internal;
import aQute.bnd.annotation.spi.ServiceProvider;
import org.apache.logging.admin.LoggingAdmin;
import org.apache.logging.admin.spi.LoggingAdminFactory;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.spi.LoggerContext;
@ServiceProvider(value = LoggingAdminFactory.class)
-public class CoreFactory implements LoggingAdminFactory {
+public class Log4jCoreAdminFactory implements LoggingAdminFactory {
+ @Override
+ public int getPriority() {
+ return 512;
+ }
@Override
- public boolean isActive(ClassLoader classLoader) {
- LoggerContext loggerContext = LogManager.getContext(classLoader, false);
- return loggerContext instanceof org.apache.logging.log4j.core.LoggerContext;
+ public boolean isActive() {
+ try {
+ return Log4jCoreAdmin.isActive();
+ } catch (LinkageError e) {
+ return false;
+ }
}
@Override
- public LoggingAdmin createLoggingConfigurationAdmin(ClassLoader classLoader) {
- LoggerContext loggerContext = LogManager.getContext(classLoader, false);
- return new CoreAdmin((org.apache.logging.log4j.core.LoggerContext) loggerContext);
+ public LoggingAdmin getLoggingAdmin(Object token) {
+ return Log4jCoreAdmin.newInstance(token);
}
}
diff --git a/src/main/java/org/apache/logging/admin/internal/LogbackAdmin.java b/src/main/java/org/apache/logging/admin/internal/LogbackAdmin.java
new file mode 100644
index 0000000..9aa03a6
--- /dev/null
+++ b/src/main/java/org/apache/logging/admin/internal/LogbackAdmin.java
@@ -0,0 +1,103 @@
+/*
+ * 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.admin.internal;
+
+import ch.qos.logback.classic.Level;
+import ch.qos.logback.classic.Logger;
+import ch.qos.logback.classic.LoggerContext;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.WeakHashMap;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import org.apache.logging.admin.LoggingAdmin;
+import org.jspecify.annotations.Nullable;
+import org.slf4j.LoggerFactory;
+
+class LogbackAdmin implements LoggingAdmin {
+
+ private static final ReentrantLock lock = new ReentrantLock();
+ private static final Map<LoggerContext, Object> tokensByLoggerContext = new WeakHashMap<>();
+
+ private static final List<String> levels = Collections.unmodifiableList(
+ Stream.of(Level.OFF, Level.ERROR, Level.WARN, Level.INFO, Level.DEBUG, Level.TRACE)
+ .map(Level::toString)
+ .collect(Collectors.toList()));
+
+ private final LoggerContext loggerContext;
+
+ LogbackAdmin(final LoggerContext loggerContext) {
+ this.loggerContext = loggerContext;
+ }
+
+ @Override
+ public List<String> getSupportedLevels() {
+ return levels;
+ }
+
+ @Override
+ public Map<String, @Nullable String> getLevels() {
+ Map<String, @Nullable String> loggerLevels = new HashMap<>();
+ loggerContext
+ .getLoggerList()
+ .forEach(logger -> loggerLevels.put(rootToEmpty(logger.getName()), getLevel(logger)));
+ return loggerLevels;
+ }
+
+ @Override
+ public @Nullable String getLevel(String loggerName) {
+ return getLevel(loggerContext.getLogger(emptyToRoot(loggerName)));
+ }
+
+ private static @Nullable String getLevel(Logger logger) {
+ return Optional.ofNullable(logger.getLevel()).map(Level::toString).orElse(null);
+ }
+
+ @Override
+ public void setLevel(String loggerName, @Nullable String level) {
+ loggerContext.getLogger(emptyToRoot(loggerName)).setLevel(level != null ? Level.valueOf(level) : null);
+ }
+
+ private String rootToEmpty(String loggerName) {
+ return Logger.ROOT_LOGGER_NAME.equals(loggerName) ? "" : loggerName;
+ }
+
+ private String emptyToRoot(String loggerName) {
+ return loggerName.isEmpty() ? Logger.ROOT_LOGGER_NAME : loggerName;
+ }
+
+ static boolean isActive() {
+ return LoggerFactory.getILoggerFactory() instanceof ch.qos.logback.classic.LoggerContext;
+ }
+
+ static LoggingAdmin newInstance(Object token) {
+ lock.lock();
+ try {
+ LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
+ if (tokensByLoggerContext.computeIfAbsent(loggerContext, k -> token) != token) {
+ throw new SecurityException("The security token does not match: " + token);
+ }
+ return new LogbackAdmin(loggerContext);
+ } finally {
+ lock.unlock();
+ }
+ }
+}
diff --git a/src/main/java/org/apache/logging/admin/internal/logback/LogbackAdminFactory.java b/src/main/java/org/apache/logging/admin/internal/LogbackAdminFactory.java
similarity index 67%
rename from src/main/java/org/apache/logging/admin/internal/logback/LogbackAdminFactory.java
rename to src/main/java/org/apache/logging/admin/internal/LogbackAdminFactory.java
index 3b3492a..b05a03c 100644
--- a/src/main/java/org/apache/logging/admin/internal/logback/LogbackAdminFactory.java
+++ b/src/main/java/org/apache/logging/admin/internal/LogbackAdminFactory.java
@@ -14,21 +14,30 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.logging.admin.internal.logback;
+package org.apache.logging.admin.internal;
-import ch.qos.logback.classic.LoggerContext;
+import aQute.bnd.annotation.spi.ServiceProvider;
import org.apache.logging.admin.LoggingAdmin;
import org.apache.logging.admin.spi.LoggingAdminFactory;
-import org.slf4j.LoggerFactory;
+@ServiceProvider(value = LoggingAdminFactory.class)
public class LogbackAdminFactory implements LoggingAdminFactory {
@Override
- public boolean isActive(ClassLoader classLoader) {
- return LoggerFactory.getILoggerFactory() instanceof ch.qos.logback.classic.LoggerContext;
+ public int getPriority() {
+ return 1024;
}
@Override
- public LoggingAdmin createLoggingConfigurationAdmin(ClassLoader classLoader) {
- return new LogbackAdmin((LoggerContext) LoggerFactory.getILoggerFactory());
+ public boolean isActive() {
+ try {
+ return LogbackAdmin.isActive();
+ } catch (LinkageError e) {
+ return false;
+ }
+ }
+
+ @Override
+ public LoggingAdmin getLoggingAdmin(Object token) {
+ return LogbackAdmin.newInstance(token);
}
}
diff --git a/src/main/java/org/apache/logging/admin/internal/jul/JulAdmin.java b/src/main/java/org/apache/logging/admin/internal/jul/JulAdmin.java
deleted file mode 100644
index 54fc6a8..0000000
--- a/src/main/java/org/apache/logging/admin/internal/jul/JulAdmin.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * 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.admin.internal.jul;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import java.util.logging.Level;
-import java.util.logging.LogManager;
-import java.util.logging.Logger;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-import org.apache.logging.admin.LoggingAdmin;
-import org.jspecify.annotations.Nullable;
-
-class JulAdmin implements LoggingAdmin {
-
- private static final Set<String> levels = Stream.of(
- Level.ALL,
- Level.FINEST,
- Level.FINER,
- Level.FINE,
- Level.CONFIG,
- Level.INFO,
- Level.WARNING,
- Level.SEVERE,
- Level.OFF)
- .map(Level::toString)
- .collect(Collectors.toSet());
-
- private final LogManager logManager = LogManager.getLogManager();
- private final ClassLoader classLoader;
-
- JulAdmin(final ClassLoader classLoader) {
- this.classLoader = classLoader;
- }
-
- @Override
- public Object getLoggerContext() {
- // Implementations that support multiple logger contexts can be recognized by having multiple root loggers.
- ClassLoader oldClassLoader = updateThreadContextClassLoader(classLoader);
- try {
- return Logger.getLogger("");
- } finally {
- updateThreadContextClassLoader(oldClassLoader);
- }
- }
-
- @Override
- public Set<String> getSupportedLevels() {
- return levels;
- }
-
- @Override
- public Map<String, Optional<String>> getLoggerLevels() {
- ClassLoader oldClassLoader = updateThreadContextClassLoader(classLoader);
- try {
- final Map<String, Optional<String>> loggerLevels = new HashMap<>();
- for (final String loggerName : Collections.list(logManager.getLoggerNames())) {
- loggerLevels.computeIfAbsent(loggerName, this::getLoggerLevel);
- }
- return loggerLevels;
- } finally {
- updateThreadContextClassLoader(oldClassLoader);
- }
- }
-
- @Override
- public Optional<String> getLoggerLevel(String loggerName) {
- ClassLoader oldClassLoader = updateThreadContextClassLoader(classLoader);
- try {
- return Optional.ofNullable(logManager.getLogger(loggerName))
- .map(Logger::getLevel)
- .map(Level::getName);
- } finally {
- updateThreadContextClassLoader(oldClassLoader);
- }
- }
-
- private Optional<String> doGetLoggerLevel(String loggerName) {
- return Optional.ofNullable(logManager.getLogger(loggerName))
- .map(Logger::getLevel)
- .map(Level::getName);
- }
-
- @Override
- public void setLoggerLevel(String loggerName, @Nullable String level) {
- ClassLoader oldClassLoader = updateThreadContextClassLoader(classLoader);
- try {
- logManager.getLogger(loggerName).setLevel(level != null ? Level.parse(level) : null);
- } finally {
- updateThreadContextClassLoader(oldClassLoader);
- }
- }
-
- private static ClassLoader updateThreadContextClassLoader(final ClassLoader classLoader) {
- ClassLoader old = Thread.currentThread().getContextClassLoader();
- Thread.currentThread().setContextClassLoader(classLoader);
- return old;
- }
-}
diff --git a/src/main/java/org/apache/logging/admin/internal/logback/LogbackAdmin.java b/src/main/java/org/apache/logging/admin/internal/logback/LogbackAdmin.java
deleted file mode 100644
index 3dd1fe3..0000000
--- a/src/main/java/org/apache/logging/admin/internal/logback/LogbackAdmin.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * 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.admin.internal.logback;
-
-import ch.qos.logback.classic.Level;
-import ch.qos.logback.classic.Logger;
-import ch.qos.logback.classic.LoggerContext;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-import org.apache.logging.admin.LoggingAdmin;
-import org.jspecify.annotations.Nullable;
-
-class LogbackAdmin implements LoggingAdmin {
-
- private static final Set<String> levels = Stream.of(
- Level.TRACE, Level.DEBUG, Level.INFO, Level.WARN, Level.ERROR, Level.OFF)
- .map(Level::toString)
- .collect(Collectors.toSet());
-
- private final LoggerContext loggerContext;
-
- @Override
- public Object getLoggerContext() {
- return loggerContext;
- }
-
- LogbackAdmin(final LoggerContext loggerContext) {
- this.loggerContext = loggerContext;
- }
-
- @Override
- public Set<String> getSupportedLevels() {
- return levels;
- }
-
- @Override
- public Map<String, Optional<String>> getLoggerLevels() {
- return loggerContext.getLoggerList().stream()
- .collect(Collectors.toMap(Logger::getName, LogbackAdmin::getLoggerLevel));
- }
-
- @Override
- public Optional<String> getLoggerLevel(String loggerName) {
- return getLoggerLevel(loggerContext.getLogger(loggerName));
- }
-
- private static Optional<String> getLoggerLevel(ch.qos.logback.classic.Logger logger) {
- return Optional.ofNullable(logger.getLevel()).map(Level::toString);
- }
-
- @Override
- public void setLoggerLevel(String loggerName, @Nullable String level) {
- loggerContext.getLogger(loggerName).setLevel(level != null ? Level.valueOf(level) : null);
- }
-}
diff --git a/src/main/java/org/apache/logging/admin/package-info.java b/src/main/java/org/apache/logging/admin/package-info.java
index be36b44..8c0bc7e 100644
--- a/src/main/java/org/apache/logging/admin/package-info.java
+++ b/src/main/java/org/apache/logging/admin/package-info.java
@@ -14,7 +14,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+@Export
+@Version("0.1.0")
@NullMarked
package org.apache.logging.admin;
import org.jspecify.annotations.NullMarked;
+import org.osgi.annotation.bundle.Export;
+import org.osgi.annotation.versioning.Version;
diff --git a/src/main/java/org/apache/logging/admin/spi/LoggingAdminFactory.java b/src/main/java/org/apache/logging/admin/spi/LoggingAdminFactory.java
index b6a79c4..6d11a8c 100644
--- a/src/main/java/org/apache/logging/admin/spi/LoggingAdminFactory.java
+++ b/src/main/java/org/apache/logging/admin/spi/LoggingAdminFactory.java
@@ -26,18 +26,30 @@ import org.apache.logging.admin.LoggingAdmin;
*/
public interface LoggingAdminFactory {
+ /**
+ * Provides the order in which this factory should be evaluated.
+ * <p>
+ * Lower numerical values are evaluated first.
+ * </p>
+ */
+ default int getPriority() {
+ return 0;
+ }
+
/**
* Determines whether the logging system handled by this factory is used.
- *
- * @param classLoader The class loader associated with the logger context.
*/
- boolean isActive(ClassLoader classLoader);
+ boolean isActive();
/**
* Creates a new {@link LoggingAdmin} instance associated with the given classloader.
- *
- * @param classLoader The class loader associated with the logger context.
- * @return A new instance of {@link LoggingAdmin}.
+ * <p>
+ * The {@code token} parameter sets a security token for the appropriate logger context.
+ * All future invocations of this method will need to use the same token.
+ * Tokens are compared using object equality.
+ * </p>
+ * @param token Any Java object.
+ * @return An instance of {@link LoggingAdmin}.
*/
- LoggingAdmin createLoggingConfigurationAdmin(ClassLoader classLoader);
+ LoggingAdmin getLoggingAdmin(Object token) throws SecurityException;
}
diff --git a/src/main/java/org/apache/logging/admin/spi/package-info.java b/src/main/java/org/apache/logging/admin/spi/package-info.java
index ab19b30..2751805 100644
--- a/src/main/java/org/apache/logging/admin/spi/package-info.java
+++ b/src/main/java/org/apache/logging/admin/spi/package-info.java
@@ -14,7 +14,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+@Export
+@Version("0.1.0")
@NullMarked
package org.apache.logging.admin.spi;
import org.jspecify.annotations.NullMarked;
+import org.osgi.annotation.bundle.Export;
+import org.osgi.annotation.versioning.Version;
diff --git a/src/test/java/org/apache/logging/admin/LoggingAdminTest.java b/src/test/java/org/apache/logging/admin/LoggingAdminTest.java
new file mode 100644
index 0000000..02612ec
--- /dev/null
+++ b/src/test/java/org/apache/logging/admin/LoggingAdminTest.java
@@ -0,0 +1,111 @@
+/*
+ * 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.admin;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import java.util.AbstractMap;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Logger;
+import java.util.stream.Stream;
+import org.jspecify.annotations.Nullable;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+
+class LoggingAdminTest {
+
+ private static final Map<String, List<String>> EXPECTED_LEVELS;
+
+ static {
+ final Map<String, List<String>> expectedLevels = new HashMap<>();
+ expectedLevels.put(
+ "jul", Arrays.asList("OFF", "SEVERE", "WARNING", "INFO", "CONFIG", "FINE", "FINER", "FINEST", "ALL"));
+ expectedLevels.put(
+ "log4j-core", Arrays.asList("OFF", "FATAL", "ERROR", "WARN", "INFO", "DEBUG", "TRACE", "ALL"));
+ expectedLevels.put("logback", Arrays.asList("OFF", "ERROR", "WARN", "INFO", "DEBUG", "TRACE"));
+ EXPECTED_LEVELS = Collections.unmodifiableMap(expectedLevels);
+ }
+
+ private static final Object TOKEN = new Object();
+ private static LoggingAdmin admin;
+
+ // Log4j Core is the default in the IDE
+ private static final String type = System.getProperty("admin.implementation", "log4j-core");
+
+ private static String debugLevel() {
+ return "jul".equals(type) ? "FINE" : "DEBUG";
+ }
+
+ @BeforeAll
+ static void setup() {
+ admin = LoggingAdmin.getInstance(TOKEN);
+ // JUL creates loggers lazily, so we force the creation of `foo.bar`
+ Logger.getLogger("foo.bar");
+ }
+
+ @Test
+ void should_return_correct_supported_levels() {
+ assertThat(admin.getSupportedLevels()).containsExactlyElementsOf(EXPECTED_LEVELS.get(type));
+ }
+
+ static Stream<Arguments> should_return_correct_configured_levels() {
+ return Stream.of(
+ Arguments.of(LoggingAdmin.ROOT_LOGGER_NAME, "INFO"),
+ Arguments.of("foo", null),
+ Arguments.of("foo.bar", debugLevel()));
+ }
+
+ @ParameterizedTest
+ @MethodSource
+ void should_return_correct_configured_levels(String loggerName, @Nullable String expectedLevel) {
+ assertThat(admin.getLevel(loggerName))
+ .as("Level of logger `%s`.", loggerName)
+ .isEqualTo(expectedLevel);
+ }
+
+ @Test
+ void should_return_correct_configured_level_map() {
+ assertThat(admin.getLevels())
+ .contains(
+ entry(LoggingAdmin.ROOT_LOGGER_NAME, "INFO"),
+ entry("foo", null),
+ entry("foo.bar", debugLevel()));
+ }
+
+ @Test
+ void should_return_admin_if_token_correct() {
+ assertDoesNotThrow(() -> LoggingAdmin.getInstance(TOKEN));
+ }
+
+ @Test
+ void should_throw_if_token_incorrect() {
+ assertThrows(SecurityException.class, () -> LoggingAdmin.getInstance(new Object()));
+ }
+
+ private static Map.Entry<String, @Nullable String> entry(String loggerName, @Nullable String level) {
+ return new AbstractMap.SimpleImmutableEntry<>(loggerName, level);
+ }
+}
diff --git a/src/test/resources/log4j2.xml b/src/test/resources/log4j2.xml
new file mode 100644
index 0000000..23eb4be
--- /dev/null
+++ b/src/test/resources/log4j2.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to you under the Apache License, Version 2.0
+ ~ (the "License"); you may not use this file except in compliance with
+ ~ the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<Configuration xmlns="https://logging.apache.org/xml/ns"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="
+ https://logging.apache.org/xml/ns
+ https://logging.apache.org/xml/ns/log4j-config-2.xsd">
+ <Appenders/>
+ <Loggers>
+ <Root level="INFO"/>
+ <Logger name="foo.bar" level="DEBUG"/>
+ </Loggers>
+</Configuration>
diff --git a/src/test/resources/logback.xml b/src/test/resources/logback.xml
new file mode 100644
index 0000000..5e98a3e
--- /dev/null
+++ b/src/test/resources/logback.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to you under the Apache License, Version 2.0
+ ~ (the "License"); you may not use this file except in compliance with
+ ~ the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<!DOCTYPE configuration>
+<configuration>
+ <root level="INFO"/>
+ <logger name="foo.bar" level="DEBUG"/>
+</configuration>
diff --git a/src/test/resources/logging.properties b/src/test/resources/logging.properties
new file mode 100644
index 0000000..adcc875
--- /dev/null
+++ b/src/test/resources/logging.properties
@@ -0,0 +1,19 @@
+#
+# 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.
+#
+handlers =
+.level = INFO
+foo.bar.level = FINE
(logging-admin) 07/08: Merge into a single module.
Posted by pk...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
pkarwasz pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/logging-admin.git
commit 046c6b4fe4e14b5cc213c88cedcb6cc7525d3134
Author: Piotr P. Karwasz <pi...@karwasz.org>
AuthorDate: Sun Nov 3 12:26:03 2024 +0100
Merge into a single module.
---
README.adoc | 20 ++-
api/pom.xml | 34 ------
jul/pom.xml | 43 -------
.../logging/admin/jul/internal/package-info.java | 20 ---
log4j-core/pom.xml | 50 --------
.../logging/admin/log4j/internal/package-info.java | 20 ---
logback/pom.xml | 49 --------
.../admin/logback/internal/package-info.java | 20 ---
parent/pom.xml | 72 -----------
pom.xml | 135 +++++++++------------
.../org/apache/logging/admin/LoggingAdmin.java | 18 +--
.../logging/admin/internal/FactoryHolder.java | 20 +--
.../logging/admin/internal/jul}/JulAdmin.java | 6 +-
.../logging/admin/internal/jul}/JulFactory.java | 12 +-
.../logging/admin/internal/log4j}/CoreAdmin.java | 6 +-
.../logging/admin/internal/log4j}/CoreFactory.java | 12 +-
.../admin/internal/logback}/LogbackAdmin.java | 6 +-
.../internal/logback/LogbackAdminFactory.java | 10 +-
.../logging/admin/internal/package-info.java | 0
.../org/apache/logging/admin/package-info.java | 0
.../logging/admin/spi/LoggingAdminFactory.java | 12 +-
.../org/apache/logging/admin/spi/package-info.java | 0
22 files changed, 123 insertions(+), 442 deletions(-)
diff --git a/README.adoc b/README.adoc
index 43b2fa4..e8df97e 100644
--- a/README.adoc
+++ b/README.adoc
@@ -1,10 +1,26 @@
+////
+ * 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.
+////
This repository contains an initial sketch of an *Apache Logging Admin API*.
The purpose of the API is to allow the programmatic configuration of the logging backend in an implementation independent way.
[source,java]
----
-import org.apache.logging.admin.LoggingConfigurationAdmin;
+import org.apache.logging.admin.LoggingAdmin;
public final class Main {
private static final Object TOKEN = new Object();
@@ -13,7 +29,7 @@ public final class Main {
int i = 0;
while (i < args.length) {
if ("--logLevel".equals(args[i]) && ++i < args.length) {
- LoggingConfigurationAdmin admin = LoggingConfigurationAdmin.getInstance(TOKEN);
+ LoggingAdmin admin = LoggingAdmin.getInstance(TOKEN);
admin.setLoggerLevel("", args[i]);
}
i++;
diff --git a/api/pom.xml b/api/pom.xml
deleted file mode 100644
index ae5bc61..0000000
--- a/api/pom.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Licensed to the Apache Software Foundation (ASF) under one or more
- ~ contributor license agreements. See the NOTICE file distributed with
- ~ this work for additional information regarding copyright ownership.
- ~ The ASF licenses this file to you under the Apache License, Version 2.0
- ~ (the "License"); you may not use this file except in compliance with
- ~ the License. You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.logging.admin</groupId>
- <artifactId>logging-admin-parent</artifactId>
- <version>${revision}</version>
- <relativePath>../parent</relativePath>
- </parent>
-
- <artifactId>logging-admin-api</artifactId>
- <name>Apache Logging Admin: API</name>
- <description>Implementation independent API to modify logging implementation</description>
-
- <properties>
- <bnd-module-name>org.apache.logging.admin.api</bnd-module-name>
- </properties>
-</project>
diff --git a/jul/pom.xml b/jul/pom.xml
deleted file mode 100644
index c9545e2..0000000
--- a/jul/pom.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Licensed to the Apache Software Foundation (ASF) under one or more
- ~ contributor license agreements. See the NOTICE file distributed with
- ~ this work for additional information regarding copyright ownership.
- ~ The ASF licenses this file to you under the Apache License, Version 2.0
- ~ (the "License"); you may not use this file except in compliance with
- ~ the License. You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.logging.admin</groupId>
- <artifactId>logging-admin-parent</artifactId>
- <version>${revision}</version>
- <relativePath>../parent</relativePath>
- </parent>
-
- <artifactId>logging-admin-jul</artifactId>
- <name>Apache Logging Admin: JUL implementation</name>
- <description>Implementation of the Apache Logging Admin API for `java.util.logging`.</description>
-
- <properties>
- <bnd-module-name>org.apache.logging.admin.jul</bnd-module-name>
- </properties>
-
- <dependencies>
-
- <dependency>
- <groupId>org.apache.logging.admin</groupId>
- <artifactId>logging-admin-api</artifactId>
- </dependency>
-
- </dependencies>
-</project>
diff --git a/jul/src/main/java/org/apache/logging/admin/jul/internal/package-info.java b/jul/src/main/java/org/apache/logging/admin/jul/internal/package-info.java
deleted file mode 100644
index cbca3c2..0000000
--- a/jul/src/main/java/org/apache/logging/admin/jul/internal/package-info.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * 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.
- */
-@NullMarked
-package org.apache.logging.admin.jul.internal;
-
-import org.jspecify.annotations.NullMarked;
diff --git a/log4j-core/pom.xml b/log4j-core/pom.xml
deleted file mode 100644
index 4953404..0000000
--- a/log4j-core/pom.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Licensed to the Apache Software Foundation (ASF) under one or more
- ~ contributor license agreements. See the NOTICE file distributed with
- ~ this work for additional information regarding copyright ownership.
- ~ The ASF licenses this file to you under the Apache License, Version 2.0
- ~ (the "License"); you may not use this file except in compliance with
- ~ the License. You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.logging.admin</groupId>
- <artifactId>logging-admin-parent</artifactId>
- <version>${revision}</version>
- <relativePath>../parent</relativePath>
- </parent>
-
- <artifactId>logging-admin-log4j-core</artifactId>
- <name>Apache Logging Admin: Log4j Core implementation</name>
- <description>Implementation of the Apache Logging Admin API for Log4j Core.</description>
-
- <properties>
- <bnd-module-name>org.apache.logging.admin.log4j</bnd-module-name>
- </properties>
-
- <dependencies>
-
- <dependency>
- <groupId>org.apache.logging.admin</groupId>
- <artifactId>logging-admin-api</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.apache.logging.log4j</groupId>
- <artifactId>log4j-core</artifactId>
- <version>2.24.1</version>
- </dependency>
-
- </dependencies>
-
-</project>
diff --git a/log4j-core/src/main/java/org/apache/logging/admin/log4j/internal/package-info.java b/log4j-core/src/main/java/org/apache/logging/admin/log4j/internal/package-info.java
deleted file mode 100644
index 9cd5c0c..0000000
--- a/log4j-core/src/main/java/org/apache/logging/admin/log4j/internal/package-info.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * 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.
- */
-@NullMarked
-package org.apache.logging.admin.log4j.internal;
-
-import org.jspecify.annotations.NullMarked;
diff --git a/logback/pom.xml b/logback/pom.xml
deleted file mode 100644
index 313fa04..0000000
--- a/logback/pom.xml
+++ /dev/null
@@ -1,49 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Licensed to the Apache Software Foundation (ASF) under one or more
- ~ contributor license agreements. See the NOTICE file distributed with
- ~ this work for additional information regarding copyright ownership.
- ~ The ASF licenses this file to you under the Apache License, Version 2.0
- ~ (the "License"); you may not use this file except in compliance with
- ~ the License. You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.logging.admin</groupId>
- <artifactId>logging-admin-parent</artifactId>
- <version>${revision}</version>
- <relativePath>../parent</relativePath>
- </parent>
-
- <artifactId>logging-admin-logback</artifactId>
- <name>Apache Logging Admin: Logback</name>
- <description>Implementation of the Apache Logging Admin API for Logback.</description>
-
- <properties>
- <bnd-module-name>org.apache.logging.admin.logback</bnd-module-name>
- </properties>
-
- <dependencies>
-
- <dependency>
- <groupId>org.apache.logging.admin</groupId>
- <artifactId>logging-admin-api</artifactId>
- </dependency>
-
- <dependency>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-classic</artifactId>
- <version>1.5.11</version>
- </dependency>
-
- </dependencies>
-</project>
diff --git a/logback/src/main/java/org/apache/logging/admin/logback/internal/package-info.java b/logback/src/main/java/org/apache/logging/admin/logback/internal/package-info.java
deleted file mode 100644
index 9155808..0000000
--- a/logback/src/main/java/org/apache/logging/admin/logback/internal/package-info.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * 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.
- */
-@NullMarked
-package org.apache.logging.admin.logback.internal;
-
-import org.jspecify.annotations.NullMarked;
diff --git a/parent/pom.xml b/parent/pom.xml
deleted file mode 100644
index d4bf5fb..0000000
--- a/parent/pom.xml
+++ /dev/null
@@ -1,72 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Licensed to the Apache Software Foundation (ASF) under one or more
- ~ contributor license agreements. See the NOTICE file distributed with
- ~ this work for additional information regarding copyright ownership.
- ~ The ASF licenses this file to you under the Apache License, Version 2.0
- ~ (the "License"); you may not use this file except in compliance with
- ~ the License. You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.logging.admin</groupId>
- <artifactId>logging-admin-bom</artifactId>
- <version>${revision}</version>
- </parent>
-
- <artifactId>logging-admin-parent</artifactId>
- <packaging>pom</packaging>
- <name>Apache Logging Admin: Parent</name>
-
- <properties>
- <!-- Ignore BND Baseline until the first release -->
- <bnd.baseline.skip>true</bnd.baseline.skip>
- </properties>
-
- <dependencies>
-
- <dependency>
- <groupId>org.jspecify</groupId>
- <artifactId>jspecify</artifactId>
- <version>1.0.0</version>
- </dependency>
-
- <dependency>
- <groupId>biz.aQute.bnd</groupId>
- <artifactId>biz.aQute.bnd.annotation</artifactId>
- <version>7.0.0</version>
- <scope>provided</scope>
- </dependency>
-
- <dependency>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.annotation.bundle</artifactId>
- <version>2.0.0</version>
- <scope>provided</scope>
- </dependency>
-
- <dependency>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.annotation.versioning</artifactId>
- <version>1.1.2</version>
- <scope>provided</scope>
- </dependency>
-
- <dependency>
- <groupId>com.github.spotbugs</groupId>
- <artifactId>spotbugs-annotations</artifactId>
- <scope>provided</scope>
- </dependency>
-
- </dependencies>
-
-</project>
diff --git a/pom.xml b/pom.xml
index f64a94f..ac6eef5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -16,16 +16,6 @@
~ limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" child.project.url.inherit.append.path="false" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
- <!-- ██ ██ █████ ██████ ███ ██ ██ ███ ██ ██████ ██
- ██ ██ ██ ██ ██ ██ ████ ██ ██ ████ ██ ██ ██
- ██ █ ██ ███████ ██████ ██ ██ ██ ██ ██ ██ ██ ██ ███ ██
- ██ ███ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
- ███ ███ ██ ██ ██ ██ ██ ████ ██ ██ ████ ██████ ██
-
- `logging-admin` project modules should use `logging-admin-parent` as their parents, not this POM!
- This POM constitutes the BOM to be imported by applications using `logging-admin` project modules. -->
-
<modelVersion>4.0.0</modelVersion>
<parent>
@@ -35,11 +25,12 @@
</parent>
<groupId>org.apache.logging.admin</groupId>
- <artifactId>logging-admin-bom</artifactId>
+ <artifactId>logging-admin-api</artifactId>
<version>${revision}</version>
- <packaging>pom</packaging>
- <url>https://logging.apache.org/log4j/config-admin</url>
+ <name>Apache Logging Admin API</name>
+ <description>Implementation independent API to modify logging implementation</description>
+ <url>https://logging.apache.org/admin</url>
<inceptionYear>2024</inceptionYear>
@@ -53,19 +44,6 @@
</developers>
- <modules>
-
- <!-- the parent POM must come first: -->
- <module>parent</module>
-
- <!-- Modules here must have a corresponding entry in `dependencyManagement > dependencies` block below! -->
- <module>api</module>
- <module>log4j-core</module>
- <module>logback</module>
- <module>jul</module>
-
- </modules>
-
<scm child.scm.connection.inherit.append.path="false" child.scm.developerConnection.inherit.append.path="false" child.scm.url.inherit.append.path="false">
<connection>scm:git:git@github.com:apache/logging-logging-admin.git</connection>
<developerConnection>scm:git:git@github.com:apache/logging-logging-admin.git</developerConnection>
@@ -98,59 +76,54 @@
</properties>
- <!-- `dependencyManagement` must only contain `log4j-transform` modules and nothing else!
- Modules here must have a corresponding entry in `modules` block above! -->
- <dependencyManagement>
- <dependencies>
-
- <dependency>
- <groupId>org.apache.logging.admin</groupId>
- <artifactId>logging-admin-api</artifactId>
- <version>${project.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.apache.logging.admin</groupId>
- <artifactId>logging-admin-jul</artifactId>
- <version>${project.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.apache.logging.admin</groupId>
- <artifactId>logging-admin-log4j-core</artifactId>
- <version>${project.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.apache.logging.admin</groupId>
- <artifactId>logging-admin-logback</artifactId>
- <version>${project.version}</version>
- </dependency>
-
- </dependencies>
- </dependencyManagement>
-
- <build>
- <plugins>
-
- <!-- Enable BOM flattening -->
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>flatten-maven-plugin</artifactId>
- <version>${flatten-maven-plugin.version}</version>
- <executions>
- <execution>
- <id>flatten-bom</id>
- <goals>
- <goal>flatten</goal>
- </goals>
- <phase>process-resources</phase>
- <inherited>false</inherited>
- </execution>
- </executions>
- </plugin>
-
- </plugins>
- </build>
-
+ <dependencies>
+
+ <dependency>
+ <groupId>biz.aQute.bnd</groupId>
+ <artifactId>biz.aQute.bnd.annotation</artifactId>
+ <version>7.0.0</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.annotation.bundle</artifactId>
+ <version>2.0.0</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.annotation.versioning</artifactId>
+ <version>1.1.2</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>com.github.spotbugs</groupId>
+ <artifactId>spotbugs-annotations</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jspecify</groupId>
+ <artifactId>jspecify</artifactId>
+ <version>1.0.0</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-core</artifactId>
+ <version>2.24.1</version>
+ <optional>true</optional>
+ </dependency>
+
+ <dependency>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-classic</artifactId>
+ <version>1.5.11</version>
+ <optional>true</optional>
+ </dependency>
+
+ </dependencies>
</project>
diff --git a/api/src/main/java/org/apache/logging/admin/LoggingConfigurationAdmin.java b/src/main/java/org/apache/logging/admin/LoggingAdmin.java
similarity index 87%
rename from api/src/main/java/org/apache/logging/admin/LoggingConfigurationAdmin.java
rename to src/main/java/org/apache/logging/admin/LoggingAdmin.java
index 50be2d8..ce2be20 100644
--- a/api/src/main/java/org/apache/logging/admin/LoggingConfigurationAdmin.java
+++ b/src/main/java/org/apache/logging/admin/LoggingAdmin.java
@@ -16,16 +16,15 @@
*/
package org.apache.logging.admin;
-import static java.util.Objects.requireNonNull;
-
import java.util.Map;
+import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import org.apache.logging.admin.internal.FactoryHolder;
import org.jspecify.annotations.Nullable;
/**
- * The {@code LoggingConfigurationAdmin} interface provides a logging implementation independent support to:
+ * The {@code LoggingAdmin} interface provides a logging implementation independent support to:
* <ul>
* <li>Query the logging implementation for the configured level of each logger.</li>
* <li>Change the configured level of a logger.</li>
@@ -48,7 +47,7 @@ import org.jspecify.annotations.Nullable;
* int i = 0;
* while (i < args.length) {
* if ("--logLevel".equals(args[i]) && ++i < args.length) {
- * LoggingConfigurationAdmin admin = LoggingConfigurationAdmin.getInstance(TOKEN);
+ * LoggingAdmin admin = LoggingAdmin.getInstance(TOKEN);
* admin.setLoggerLevel("", args[i]);
* }
* i++;
@@ -57,7 +56,7 @@ import org.jspecify.annotations.Nullable;
* }
* </pre>
*/
-public interface LoggingConfigurationAdmin {
+public interface LoggingAdmin {
/**
* The logger context that this interface will be configuring.
@@ -110,8 +109,9 @@ public interface LoggingConfigurationAdmin {
* @throws SecurityException If a security token is set for the associated logger context and the provided token
* does not match.
*/
- static LoggingConfigurationAdmin getInstance(Object token, ClassLoader classLoader) {
- return FactoryHolder.getLoggingConfigurationAdmin(requireNonNull(token), requireNonNull(classLoader));
+ static LoggingAdmin getInstance(Object token, ClassLoader classLoader) {
+ return FactoryHolder.getLoggingConfigurationAdmin(
+ Objects.requireNonNull(token), Objects.requireNonNull(classLoader));
}
/**
@@ -126,8 +126,8 @@ public interface LoggingConfigurationAdmin {
* @throws SecurityException If a security token is set for the associated logger context and the provided token
* does not match.
*/
- static LoggingConfigurationAdmin getInstance(Object token) {
+ static LoggingAdmin getInstance(Object token) {
return FactoryHolder.getLoggingConfigurationAdmin(
- requireNonNull(token), LoggingConfigurationAdmin.class.getClassLoader());
+ Objects.requireNonNull(token), LoggingAdmin.class.getClassLoader());
}
}
diff --git a/api/src/main/java/org/apache/logging/admin/internal/FactoryHolder.java b/src/main/java/org/apache/logging/admin/internal/FactoryHolder.java
similarity index 74%
rename from api/src/main/java/org/apache/logging/admin/internal/FactoryHolder.java
rename to src/main/java/org/apache/logging/admin/internal/FactoryHolder.java
index e42b784..08a94c3 100644
--- a/api/src/main/java/org/apache/logging/admin/internal/FactoryHolder.java
+++ b/src/main/java/org/apache/logging/admin/internal/FactoryHolder.java
@@ -25,22 +25,22 @@ import java.util.Map;
import java.util.ServiceLoader;
import java.util.WeakHashMap;
import java.util.concurrent.locks.ReentrantLock;
-import org.apache.logging.admin.LoggingConfigurationAdmin;
-import org.apache.logging.admin.spi.LoggingConfigurationAdminFactory;
+import org.apache.logging.admin.LoggingAdmin;
+import org.apache.logging.admin.spi.LoggingAdminFactory;
@ServiceConsumer(
- value = LoggingConfigurationAdminFactory.class,
+ value = LoggingAdminFactory.class,
cardinality = Cardinality.MULTIPLE,
resolution = Resolution.MANDATORY)
public final class FactoryHolder {
- private static final Collection<LoggingConfigurationAdminFactory> factories = new ArrayList<>();
+ private static final Collection<LoggingAdminFactory> factories = new ArrayList<>();
private static final ReentrantLock lock = new ReentrantLock();
- private static final Map<ClassLoader, LoggingConfigurationAdmin> instances = new WeakHashMap<>();
+ private static final Map<ClassLoader, LoggingAdmin> instances = new WeakHashMap<>();
private static final Map<Object, Object> tokensByLoggerContext = new WeakHashMap<>();
static {
- ServiceLoader.load(LoggingConfigurationAdminFactory.class, FactoryHolder.class.getClassLoader())
+ ServiceLoader.load(LoggingAdminFactory.class, FactoryHolder.class.getClassLoader())
.forEach(factories::add);
}
@@ -55,17 +55,17 @@ public final class FactoryHolder {
}
}
- public static LoggingConfigurationAdmin getLoggingConfigurationAdmin(Object token, ClassLoader classLoader) {
+ public static LoggingAdmin getLoggingConfigurationAdmin(Object token, ClassLoader classLoader) {
lock.lock();
try {
- LoggingConfigurationAdmin instance = instances.get(classLoader);
+ LoggingAdmin instance = instances.get(classLoader);
if (instance == null) {
instance = factories.stream()
.filter(f -> f.isActive(classLoader))
.findAny()
.map(f -> f.createLoggingConfigurationAdmin(classLoader))
- .orElseThrow(() -> new IllegalStateException(
- "No " + LoggingConfigurationAdminFactory.class.getName() + " found."));
+ .orElseThrow(() ->
+ new IllegalStateException("No " + LoggingAdminFactory.class.getName() + " found."));
instances.put(classLoader, instance);
}
checkSecurityToken(token, instance.getLoggerContext());
diff --git a/jul/src/main/java/org/apache/logging/admin/jul/internal/JulAdmin.java b/src/main/java/org/apache/logging/admin/internal/jul/JulAdmin.java
similarity index 96%
rename from jul/src/main/java/org/apache/logging/admin/jul/internal/JulAdmin.java
rename to src/main/java/org/apache/logging/admin/internal/jul/JulAdmin.java
index ecb833e..54fc6a8 100644
--- a/jul/src/main/java/org/apache/logging/admin/jul/internal/JulAdmin.java
+++ b/src/main/java/org/apache/logging/admin/internal/jul/JulAdmin.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.logging.admin.jul.internal;
+package org.apache.logging.admin.internal.jul;
import java.util.Collections;
import java.util.HashMap;
@@ -26,10 +26,10 @@ import java.util.logging.LogManager;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import java.util.stream.Stream;
-import org.apache.logging.admin.LoggingConfigurationAdmin;
+import org.apache.logging.admin.LoggingAdmin;
import org.jspecify.annotations.Nullable;
-class JulAdmin implements LoggingConfigurationAdmin {
+class JulAdmin implements LoggingAdmin {
private static final Set<String> levels = Stream.of(
Level.ALL,
diff --git a/jul/src/main/java/org/apache/logging/admin/jul/internal/JulFactory.java b/src/main/java/org/apache/logging/admin/internal/jul/JulFactory.java
similarity index 71%
rename from jul/src/main/java/org/apache/logging/admin/jul/internal/JulFactory.java
rename to src/main/java/org/apache/logging/admin/internal/jul/JulFactory.java
index baff61b..7c257df 100644
--- a/jul/src/main/java/org/apache/logging/admin/jul/internal/JulFactory.java
+++ b/src/main/java/org/apache/logging/admin/internal/jul/JulFactory.java
@@ -14,14 +14,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.logging.admin.jul.internal;
+package org.apache.logging.admin.internal.jul;
import aQute.bnd.annotation.spi.ServiceProvider;
-import org.apache.logging.admin.LoggingConfigurationAdmin;
-import org.apache.logging.admin.spi.LoggingConfigurationAdminFactory;
+import org.apache.logging.admin.LoggingAdmin;
+import org.apache.logging.admin.spi.LoggingAdminFactory;
-@ServiceProvider(LoggingConfigurationAdminFactory.class)
-public class JulFactory implements LoggingConfigurationAdminFactory {
+@ServiceProvider(LoggingAdminFactory.class)
+public class JulFactory implements LoggingAdminFactory {
@Override
public boolean isActive(ClassLoader classLoader) {
@@ -29,7 +29,7 @@ public class JulFactory implements LoggingConfigurationAdminFactory {
}
@Override
- public LoggingConfigurationAdmin createLoggingConfigurationAdmin(ClassLoader classLoader) {
+ public LoggingAdmin createLoggingConfigurationAdmin(ClassLoader classLoader) {
return new JulAdmin(classLoader);
}
}
diff --git a/log4j-core/src/main/java/org/apache/logging/admin/log4j/internal/CoreAdmin.java b/src/main/java/org/apache/logging/admin/internal/log4j/CoreAdmin.java
similarity index 95%
rename from log4j-core/src/main/java/org/apache/logging/admin/log4j/internal/CoreAdmin.java
rename to src/main/java/org/apache/logging/admin/internal/log4j/CoreAdmin.java
index 43393d2..7edd685 100644
--- a/log4j-core/src/main/java/org/apache/logging/admin/log4j/internal/CoreAdmin.java
+++ b/src/main/java/org/apache/logging/admin/internal/log4j/CoreAdmin.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.logging.admin.log4j.internal;
+package org.apache.logging.admin.internal.log4j;
import java.util.HashMap;
import java.util.Map;
@@ -23,7 +23,7 @@ import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
-import org.apache.logging.admin.LoggingConfigurationAdmin;
+import org.apache.logging.admin.LoggingAdmin;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.config.Configuration;
@@ -31,7 +31,7 @@ import org.apache.logging.log4j.core.config.LoggerConfig;
import org.apache.logging.log4j.core.util.NameUtil;
import org.jspecify.annotations.Nullable;
-class CoreAdmin implements LoggingConfigurationAdmin {
+class CoreAdmin implements LoggingAdmin {
private final LoggerContext loggerContext;
diff --git a/log4j-core/src/main/java/org/apache/logging/admin/log4j/internal/CoreFactory.java b/src/main/java/org/apache/logging/admin/internal/log4j/CoreFactory.java
similarity index 77%
rename from log4j-core/src/main/java/org/apache/logging/admin/log4j/internal/CoreFactory.java
rename to src/main/java/org/apache/logging/admin/internal/log4j/CoreFactory.java
index a1c8db5..9b9c82a 100644
--- a/log4j-core/src/main/java/org/apache/logging/admin/log4j/internal/CoreFactory.java
+++ b/src/main/java/org/apache/logging/admin/internal/log4j/CoreFactory.java
@@ -14,16 +14,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.logging.admin.log4j.internal;
+package org.apache.logging.admin.internal.log4j;
import aQute.bnd.annotation.spi.ServiceProvider;
-import org.apache.logging.admin.LoggingConfigurationAdmin;
-import org.apache.logging.admin.spi.LoggingConfigurationAdminFactory;
+import org.apache.logging.admin.LoggingAdmin;
+import org.apache.logging.admin.spi.LoggingAdminFactory;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.spi.LoggerContext;
-@ServiceProvider(value = LoggingConfigurationAdminFactory.class)
-public class CoreFactory implements LoggingConfigurationAdminFactory {
+@ServiceProvider(value = LoggingAdminFactory.class)
+public class CoreFactory implements LoggingAdminFactory {
@Override
public boolean isActive(ClassLoader classLoader) {
@@ -32,7 +32,7 @@ public class CoreFactory implements LoggingConfigurationAdminFactory {
}
@Override
- public LoggingConfigurationAdmin createLoggingConfigurationAdmin(ClassLoader classLoader) {
+ public LoggingAdmin createLoggingConfigurationAdmin(ClassLoader classLoader) {
LoggerContext loggerContext = LogManager.getContext(classLoader, false);
return new CoreAdmin((org.apache.logging.log4j.core.LoggerContext) loggerContext);
}
diff --git a/logback/src/main/java/org/apache/logging/admin/logback/internal/LogbackAdmin.java b/src/main/java/org/apache/logging/admin/internal/logback/LogbackAdmin.java
similarity index 93%
rename from logback/src/main/java/org/apache/logging/admin/logback/internal/LogbackAdmin.java
rename to src/main/java/org/apache/logging/admin/internal/logback/LogbackAdmin.java
index 477cca2..3dd1fe3 100644
--- a/logback/src/main/java/org/apache/logging/admin/logback/internal/LogbackAdmin.java
+++ b/src/main/java/org/apache/logging/admin/internal/logback/LogbackAdmin.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.logging.admin.logback.internal;
+package org.apache.logging.admin.internal.logback;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
@@ -24,10 +24,10 @@ import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
-import org.apache.logging.admin.LoggingConfigurationAdmin;
+import org.apache.logging.admin.LoggingAdmin;
import org.jspecify.annotations.Nullable;
-class LogbackAdmin implements LoggingConfigurationAdmin {
+class LogbackAdmin implements LoggingAdmin {
private static final Set<String> levels = Stream.of(
Level.TRACE, Level.DEBUG, Level.INFO, Level.WARN, Level.ERROR, Level.OFF)
diff --git a/logback/src/main/java/org/apache/logging/admin/logback/internal/LogbackFactory.java b/src/main/java/org/apache/logging/admin/internal/logback/LogbackAdminFactory.java
similarity index 76%
rename from logback/src/main/java/org/apache/logging/admin/logback/internal/LogbackFactory.java
rename to src/main/java/org/apache/logging/admin/internal/logback/LogbackAdminFactory.java
index 44dc5e1..3b3492a 100644
--- a/logback/src/main/java/org/apache/logging/admin/logback/internal/LogbackFactory.java
+++ b/src/main/java/org/apache/logging/admin/internal/logback/LogbackAdminFactory.java
@@ -14,21 +14,21 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.logging.admin.logback.internal;
+package org.apache.logging.admin.internal.logback;
import ch.qos.logback.classic.LoggerContext;
-import org.apache.logging.admin.LoggingConfigurationAdmin;
-import org.apache.logging.admin.spi.LoggingConfigurationAdminFactory;
+import org.apache.logging.admin.LoggingAdmin;
+import org.apache.logging.admin.spi.LoggingAdminFactory;
import org.slf4j.LoggerFactory;
-public class LogbackFactory implements LoggingConfigurationAdminFactory {
+public class LogbackAdminFactory implements LoggingAdminFactory {
@Override
public boolean isActive(ClassLoader classLoader) {
return LoggerFactory.getILoggerFactory() instanceof ch.qos.logback.classic.LoggerContext;
}
@Override
- public LoggingConfigurationAdmin createLoggingConfigurationAdmin(ClassLoader classLoader) {
+ public LoggingAdmin createLoggingConfigurationAdmin(ClassLoader classLoader) {
return new LogbackAdmin((LoggerContext) LoggerFactory.getILoggerFactory());
}
}
diff --git a/api/src/main/java/org/apache/logging/admin/internal/package-info.java b/src/main/java/org/apache/logging/admin/internal/package-info.java
similarity index 100%
rename from api/src/main/java/org/apache/logging/admin/internal/package-info.java
rename to src/main/java/org/apache/logging/admin/internal/package-info.java
diff --git a/api/src/main/java/org/apache/logging/admin/package-info.java b/src/main/java/org/apache/logging/admin/package-info.java
similarity index 100%
rename from api/src/main/java/org/apache/logging/admin/package-info.java
rename to src/main/java/org/apache/logging/admin/package-info.java
diff --git a/api/src/main/java/org/apache/logging/admin/spi/LoggingConfigurationAdminFactory.java b/src/main/java/org/apache/logging/admin/spi/LoggingAdminFactory.java
similarity index 74%
rename from api/src/main/java/org/apache/logging/admin/spi/LoggingConfigurationAdminFactory.java
rename to src/main/java/org/apache/logging/admin/spi/LoggingAdminFactory.java
index e10fd90..b6a79c4 100644
--- a/api/src/main/java/org/apache/logging/admin/spi/LoggingConfigurationAdminFactory.java
+++ b/src/main/java/org/apache/logging/admin/spi/LoggingAdminFactory.java
@@ -16,15 +16,15 @@
*/
package org.apache.logging.admin.spi;
-import org.apache.logging.admin.LoggingConfigurationAdmin;
+import org.apache.logging.admin.LoggingAdmin;
/**
- * Factory class for {@link LoggingConfigurationAdmin} instances.
+ * Factory class for {@link LoggingAdmin} instances.
* <p>
* Implementations of this class should be registered using {@link java.util.ServiceLoader}.
* </p>
*/
-public interface LoggingConfigurationAdminFactory {
+public interface LoggingAdminFactory {
/**
* Determines whether the logging system handled by this factory is used.
@@ -34,10 +34,10 @@ public interface LoggingConfigurationAdminFactory {
boolean isActive(ClassLoader classLoader);
/**
- * Creates a new {@link LoggingConfigurationAdmin} instance associated with the given classloader.
+ * Creates a new {@link LoggingAdmin} instance associated with the given classloader.
*
* @param classLoader The class loader associated with the logger context.
- * @return A new instance of {@link LoggingConfigurationAdmin}.
+ * @return A new instance of {@link LoggingAdmin}.
*/
- LoggingConfigurationAdmin createLoggingConfigurationAdmin(ClassLoader classLoader);
+ LoggingAdmin createLoggingConfigurationAdmin(ClassLoader classLoader);
}
diff --git a/api/src/main/java/org/apache/logging/admin/spi/package-info.java b/src/main/java/org/apache/logging/admin/spi/package-info.java
similarity index 100%
rename from api/src/main/java/org/apache/logging/admin/spi/package-info.java
rename to src/main/java/org/apache/logging/admin/spi/package-info.java
(logging-admin) 02/08: Setup repository configuration
Posted by pk...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
pkarwasz pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/logging-admin.git
commit 8ef61ac397c03d1ec6a99f36b51c74ef6c0490cc
Author: Piotr P. Karwasz <pi...@karwasz.org>
AuthorDate: Thu Oct 31 19:48:55 2024 +0100
Setup repository configuration
---
.gitattributes | 21 +++++++++++++++++++++
.gitignore | 28 ++++++++++++++++++++++++++++
api/pom.xml | 20 ++++++++++++++++++++
jul/pom.xml | 20 ++++++++++++++++++++
log4j-core/pom.xml | 20 ++++++++++++++++++++
logback/pom.xml | 20 ++++++++++++++++++++
parent/pom.xml | 20 ++++++++++++++++++++
pom.xml | 17 +++++++++++++++++
8 files changed, 166 insertions(+)
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..bc0e569
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,21 @@
+# 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.
+
+# All text files with LF line endings
+* text=auto eol=lf
+# Maven Wrapper cmd script
+/mvnw.cmd eol=crlf
+# Maven Wrapper need LF line endings
+/.mvn/wrapper/maven-wrapper.properties eol=lf
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..4846736
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,28 @@
+# 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.
+
+# IntelliJ IDEA
+.idea
+*.iml
+*.iws
+# Eclipse
+.project
+.classpath
+.settings/
+# Generated by Maven
+.flattened-pom.xml
+dependency-reduced-pom.xml
+/.mvn/wrapper/maven-wrapper.jar
+target/
diff --git a/api/pom.xml b/api/pom.xml
new file mode 100644
index 0000000..c91c07b
--- /dev/null
+++ b/api/pom.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-config-admin-bom</artifactId>
+ <version>0.2.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>api</artifactId>
+
+ <properties>
+ <maven.compiler.source>17</maven.compiler.source>
+ <maven.compiler.target>17</maven.compiler.target>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+
+</project>
\ No newline at end of file
diff --git a/jul/pom.xml b/jul/pom.xml
new file mode 100644
index 0000000..a51f55c
--- /dev/null
+++ b/jul/pom.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-config-admin-bom</artifactId>
+ <version>0.1.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>jul</artifactId>
+
+ <properties>
+ <maven.compiler.source>17</maven.compiler.source>
+ <maven.compiler.target>17</maven.compiler.target>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+
+</project>
\ No newline at end of file
diff --git a/log4j-core/pom.xml b/log4j-core/pom.xml
new file mode 100644
index 0000000..d48f011
--- /dev/null
+++ b/log4j-core/pom.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-config-admin-bom</artifactId>
+ <version>0.1.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>log4j-core</artifactId>
+
+ <properties>
+ <maven.compiler.source>17</maven.compiler.source>
+ <maven.compiler.target>17</maven.compiler.target>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+
+</project>
\ No newline at end of file
diff --git a/logback/pom.xml b/logback/pom.xml
new file mode 100644
index 0000000..b11edff
--- /dev/null
+++ b/logback/pom.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-config-admin-bom</artifactId>
+ <version>0.1.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>logback</artifactId>
+
+ <properties>
+ <maven.compiler.source>17</maven.compiler.source>
+ <maven.compiler.target>17</maven.compiler.target>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+
+</project>
\ No newline at end of file
diff --git a/parent/pom.xml b/parent/pom.xml
new file mode 100644
index 0000000..d4a1352
--- /dev/null
+++ b/parent/pom.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>config</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>log4j-config-admin-parent</artifactId>
+
+ <properties>
+ <maven.compiler.source>17</maven.compiler.source>
+ <maven.compiler.target>17</maven.compiler.target>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+
+</project>
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..253c2e2
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>config</artifactId>
+ <version>1.0-SNAPSHOT</version>
+
+ <properties>
+ <maven.compiler.source>17</maven.compiler.source>
+ <maven.compiler.target>17</maven.compiler.target>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+
+</project>
\ No newline at end of file
(logging-admin) 03/08: Add Maven wrapper
Posted by pk...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
pkarwasz pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/logging-admin.git
commit 16e8404e1f5dc9c5374574182ac6e80bae749cd1
Author: Piotr P. Karwasz <pi...@karwasz.org>
AuthorDate: Thu Oct 31 19:49:46 2024 +0100
Add Maven wrapper
---
.mvn/wrapper/maven-wrapper.properties | 19 +++
api/pom.xml | 13 +-
jul/pom.xml | 13 +-
log4j-core/pom.xml | 13 +-
logback/pom.xml | 13 +-
mvnw | 259 ++++++++++++++++++++++++++++++++++
mvnw.cmd | 149 +++++++++++++++++++
parent/pom.xml | 11 +-
pom.xml | 140 +++++++++++++++++-
9 files changed, 580 insertions(+), 50 deletions(-)
diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties
new file mode 100644
index 0000000..d58dfb7
--- /dev/null
+++ b/.mvn/wrapper/maven-wrapper.properties
@@ -0,0 +1,19 @@
+# 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.
+wrapperVersion=3.3.2
+distributionType=only-script
+distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip
diff --git a/api/pom.xml b/api/pom.xml
index c91c07b..f84b48f 100644
--- a/api/pom.xml
+++ b/api/pom.xml
@@ -5,16 +5,11 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.logging.log4j</groupId>
- <artifactId>log4j-config-admin-bom</artifactId>
- <version>0.2.0-SNAPSHOT</version>
+ <artifactId>log4j-config-admin-parent</artifactId>
+ <version>${revision}</version>
+ <relativePath>../parent</relativePath>
</parent>
- <artifactId>api</artifactId>
-
- <properties>
- <maven.compiler.source>17</maven.compiler.source>
- <maven.compiler.target>17</maven.compiler.target>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- </properties>
+ <artifactId>log4j-config-admin-api</artifactId>
</project>
\ No newline at end of file
diff --git a/jul/pom.xml b/jul/pom.xml
index a51f55c..44d4c9e 100644
--- a/jul/pom.xml
+++ b/jul/pom.xml
@@ -5,16 +5,11 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.logging.log4j</groupId>
- <artifactId>log4j-config-admin-bom</artifactId>
- <version>0.1.0-SNAPSHOT</version>
+ <artifactId>log4j-config-admin-parent</artifactId>
+ <version>${revision}</version>
+ <relativePath>../parent</relativePath>
</parent>
- <artifactId>jul</artifactId>
-
- <properties>
- <maven.compiler.source>17</maven.compiler.source>
- <maven.compiler.target>17</maven.compiler.target>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- </properties>
+ <artifactId>log4j-config-admin-jul</artifactId>
</project>
\ No newline at end of file
diff --git a/log4j-core/pom.xml b/log4j-core/pom.xml
index d48f011..ef27846 100644
--- a/log4j-core/pom.xml
+++ b/log4j-core/pom.xml
@@ -5,16 +5,11 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.logging.log4j</groupId>
- <artifactId>log4j-config-admin-bom</artifactId>
- <version>0.1.0-SNAPSHOT</version>
+ <artifactId>log4j-config-admin-parent</artifactId>
+ <version>${revision}</version>
+ <relativePath>../parent</relativePath>
</parent>
- <artifactId>log4j-core</artifactId>
-
- <properties>
- <maven.compiler.source>17</maven.compiler.source>
- <maven.compiler.target>17</maven.compiler.target>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- </properties>
+ <artifactId>log4j-config-admin-log4j-core</artifactId>
</project>
\ No newline at end of file
diff --git a/logback/pom.xml b/logback/pom.xml
index b11edff..c1862e5 100644
--- a/logback/pom.xml
+++ b/logback/pom.xml
@@ -5,16 +5,11 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.logging.log4j</groupId>
- <artifactId>log4j-config-admin-bom</artifactId>
- <version>0.1.0-SNAPSHOT</version>
+ <artifactId>log4j-config-admin-parent</artifactId>
+ <version>${revision}</version>
+ <relativePath>../parent</relativePath>
</parent>
- <artifactId>logback</artifactId>
-
- <properties>
- <maven.compiler.source>17</maven.compiler.source>
- <maven.compiler.target>17</maven.compiler.target>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- </properties>
+ <artifactId>log4j-config-admin-logback</artifactId>
</project>
\ No newline at end of file
diff --git a/mvnw b/mvnw
new file mode 100755
index 0000000..19529dd
--- /dev/null
+++ b/mvnw
@@ -0,0 +1,259 @@
+#!/bin/sh
+# ----------------------------------------------------------------------------
+# 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.
+# ----------------------------------------------------------------------------
+
+# ----------------------------------------------------------------------------
+# Apache Maven Wrapper startup batch script, version 3.3.2
+#
+# Optional ENV vars
+# -----------------
+# JAVA_HOME - location of a JDK home dir, required when download maven via java source
+# MVNW_REPOURL - repo url base for downloading maven distribution
+# MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
+# MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output
+# ----------------------------------------------------------------------------
+
+set -euf
+[ "${MVNW_VERBOSE-}" != debug ] || set -x
+
+# OS specific support.
+native_path() { printf %s\\n "$1"; }
+case "$(uname)" in
+CYGWIN* | MINGW*)
+ [ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")"
+ native_path() { cygpath --path --windows "$1"; }
+ ;;
+esac
+
+# set JAVACMD and JAVACCMD
+set_java_home() {
+ # For Cygwin and MinGW, ensure paths are in Unix format before anything is touched
+ if [ -n "${JAVA_HOME-}" ]; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ]; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ JAVACCMD="$JAVA_HOME/jre/sh/javac"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ JAVACCMD="$JAVA_HOME/bin/javac"
+
+ if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then
+ echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2
+ echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2
+ return 1
+ fi
+ fi
+ else
+ JAVACMD="$(
+ 'set' +e
+ 'unset' -f command 2>/dev/null
+ 'command' -v java
+ )" || :
+ JAVACCMD="$(
+ 'set' +e
+ 'unset' -f command 2>/dev/null
+ 'command' -v javac
+ )" || :
+
+ if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then
+ echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2
+ return 1
+ fi
+ fi
+}
+
+# hash string like Java String::hashCode
+hash_string() {
+ str="${1:-}" h=0
+ while [ -n "$str" ]; do
+ char="${str%"${str#?}"}"
+ h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296))
+ str="${str#?}"
+ done
+ printf %x\\n $h
+}
+
+verbose() { :; }
+[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; }
+
+die() {
+ printf %s\\n "$1" >&2
+ exit 1
+}
+
+trim() {
+ # MWRAPPER-139:
+ # Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds.
+ # Needed for removing poorly interpreted newline sequences when running in more
+ # exotic environments such as mingw bash on Windows.
+ printf "%s" "${1}" | tr -d '[:space:]'
+}
+
+# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties
+while IFS="=" read -r key value; do
+ case "${key-}" in
+ distributionUrl) distributionUrl=$(trim "${value-}") ;;
+ distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;;
+ esac
+done <"${0%/*}/.mvn/wrapper/maven-wrapper.properties"
+[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in ${0%/*}/.mvn/wrapper/maven-wrapper.properties"
+
+case "${distributionUrl##*/}" in
+maven-mvnd-*bin.*)
+ MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/
+ case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in
+ *AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;;
+ :Darwin*x86_64) distributionPlatform=darwin-amd64 ;;
+ :Darwin*arm64) distributionPlatform=darwin-aarch64 ;;
+ :Linux*x86_64*) distributionPlatform=linux-amd64 ;;
+ *)
+ echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2
+ distributionPlatform=linux-amd64
+ ;;
+ esac
+ distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip"
+ ;;
+maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;;
+*) MVN_CMD="mvn${0##*/mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;;
+esac
+
+# apply MVNW_REPOURL and calculate MAVEN_HOME
+# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash>
+[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}"
+distributionUrlName="${distributionUrl##*/}"
+distributionUrlNameMain="${distributionUrlName%.*}"
+distributionUrlNameMain="${distributionUrlNameMain%-bin}"
+MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}"
+MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")"
+
+exec_maven() {
+ unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || :
+ exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD"
+}
+
+if [ -d "$MAVEN_HOME" ]; then
+ verbose "found existing MAVEN_HOME at $MAVEN_HOME"
+ exec_maven "$@"
+fi
+
+case "${distributionUrl-}" in
+*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;;
+*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;;
+esac
+
+# prepare tmp dir
+if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then
+ clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; }
+ trap clean HUP INT TERM EXIT
+else
+ die "cannot create temp dir"
+fi
+
+mkdir -p -- "${MAVEN_HOME%/*}"
+
+# Download and Install Apache Maven
+verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
+verbose "Downloading from: $distributionUrl"
+verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
+
+# select .zip or .tar.gz
+if ! command -v unzip >/dev/null; then
+ distributionUrl="${distributionUrl%.zip}.tar.gz"
+ distributionUrlName="${distributionUrl##*/}"
+fi
+
+# verbose opt
+__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR=''
+[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v
+
+# normalize http auth
+case "${MVNW_PASSWORD:+has-password}" in
+'') MVNW_USERNAME='' MVNW_PASSWORD='' ;;
+has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;;
+esac
+
+if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then
+ verbose "Found wget ... using wget"
+ wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl"
+elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then
+ verbose "Found curl ... using curl"
+ curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl"
+elif set_java_home; then
+ verbose "Falling back to use Java to download"
+ javaSource="$TMP_DOWNLOAD_DIR/Downloader.java"
+ targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName"
+ cat >"$javaSource" <<-END
+ public class Downloader extends java.net.Authenticator
+ {
+ protected java.net.PasswordAuthentication getPasswordAuthentication()
+ {
+ return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() );
+ }
+ public static void main( String[] args ) throws Exception
+ {
+ setDefault( new Downloader() );
+ java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() );
+ }
+ }
+ END
+ # For Cygwin/MinGW, switch paths to Windows format before running javac and java
+ verbose " - Compiling Downloader.java ..."
+ "$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java"
+ verbose " - Running Downloader.java ..."
+ "$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")"
+fi
+
+# If specified, validate the SHA-256 sum of the Maven distribution zip file
+if [ -n "${distributionSha256Sum-}" ]; then
+ distributionSha256Result=false
+ if [ "$MVN_CMD" = mvnd.sh ]; then
+ echo "Checksum validation is not supported for maven-mvnd." >&2
+ echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2
+ exit 1
+ elif command -v sha256sum >/dev/null; then
+ if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c >/dev/null 2>&1; then
+ distributionSha256Result=true
+ fi
+ elif command -v shasum >/dev/null; then
+ if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then
+ distributionSha256Result=true
+ fi
+ else
+ echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2
+ echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2
+ exit 1
+ fi
+ if [ $distributionSha256Result = false ]; then
+ echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2
+ echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2
+ exit 1
+ fi
+fi
+
+# unzip and move
+if command -v unzip >/dev/null; then
+ unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip"
+else
+ tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar"
+fi
+printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/mvnw.url"
+mv -- "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME"
+
+clean || :
+exec_maven "$@"
diff --git a/mvnw.cmd b/mvnw.cmd
new file mode 100644
index 0000000..249bdf3
--- /dev/null
+++ b/mvnw.cmd
@@ -0,0 +1,149 @@
+<# : batch portion
+@REM ----------------------------------------------------------------------------
+@REM Licensed to the Apache Software Foundation (ASF) under one
+@REM or more contributor license agreements. See the NOTICE file
+@REM distributed with this work for additional information
+@REM regarding copyright ownership. The ASF licenses this file
+@REM to you under the Apache License, Version 2.0 (the
+@REM "License"); you may not use this file except in compliance
+@REM with the License. You may obtain a copy of the License at
+@REM
+@REM http://www.apache.org/licenses/LICENSE-2.0
+@REM
+@REM Unless required by applicable law or agreed to in writing,
+@REM software distributed under the License is distributed on an
+@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+@REM KIND, either express or implied. See the License for the
+@REM specific language governing permissions and limitations
+@REM under the License.
+@REM ----------------------------------------------------------------------------
+
+@REM ----------------------------------------------------------------------------
+@REM Apache Maven Wrapper startup batch script, version 3.3.2
+@REM
+@REM Optional ENV vars
+@REM MVNW_REPOURL - repo url base for downloading maven distribution
+@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
+@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output
+@REM ----------------------------------------------------------------------------
+
+@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0)
+@SET __MVNW_CMD__=
+@SET __MVNW_ERROR__=
+@SET __MVNW_PSMODULEP_SAVE=%PSModulePath%
+@SET PSModulePath=
+@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @(
+ IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B)
+)
+@SET PSModulePath=%__MVNW_PSMODULEP_SAVE%
+@SET __MVNW_PSMODULEP_SAVE=
+@SET __MVNW_ARG0_NAME__=
+@SET MVNW_USERNAME=
+@SET MVNW_PASSWORD=
+@IF NOT "%__MVNW_CMD__%"=="" (%__MVNW_CMD__% %*)
+@echo Cannot start maven from wrapper >&2 && exit /b 1
+@GOTO :EOF
+: end batch / begin powershell #>
+
+$ErrorActionPreference = "Stop"
+if ($env:MVNW_VERBOSE -eq "true") {
+ $VerbosePreference = "Continue"
+}
+
+# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties
+$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl
+if (!$distributionUrl) {
+ Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties"
+}
+
+switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) {
+ "maven-mvnd-*" {
+ $USE_MVND = $true
+ $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip"
+ $MVN_CMD = "mvnd.cmd"
+ break
+ }
+ default {
+ $USE_MVND = $false
+ $MVN_CMD = $script -replace '^mvnw','mvn'
+ break
+ }
+}
+
+# apply MVNW_REPOURL and calculate MAVEN_HOME
+# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash>
+if ($env:MVNW_REPOURL) {
+ $MVNW_REPO_PATTERN = if ($USE_MVND) { "/org/apache/maven/" } else { "/maven/mvnd/" }
+ $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace '^.*'+$MVNW_REPO_PATTERN,'')"
+}
+$distributionUrlName = $distributionUrl -replace '^.*/',''
+$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$',''
+$MAVEN_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain"
+if ($env:MAVEN_USER_HOME) {
+ $MAVEN_HOME_PARENT = "$env:MAVEN_USER_HOME/wrapper/dists/$distributionUrlNameMain"
+}
+$MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join ''
+$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME"
+
+if (Test-Path -Path "$MAVEN_HOME" -PathType Container) {
+ Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME"
+ Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"
+ exit $?
+}
+
+if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) {
+ Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl"
+}
+
+# prepare tmp dir
+$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile
+$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir"
+$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null
+trap {
+ if ($TMP_DOWNLOAD_DIR.Exists) {
+ try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
+ catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
+ }
+}
+
+New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null
+
+# Download and Install Apache Maven
+Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
+Write-Verbose "Downloading from: $distributionUrl"
+Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
+
+$webclient = New-Object System.Net.WebClient
+if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) {
+ $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD)
+}
+[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
+$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null
+
+# If specified, validate the SHA-256 sum of the Maven distribution zip file
+$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum
+if ($distributionSha256Sum) {
+ if ($USE_MVND) {
+ Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties."
+ }
+ Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash
+ if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) {
+ Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property."
+ }
+}
+
+# unzip and move
+Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null
+Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -NewName $MAVEN_HOME_NAME | Out-Null
+try {
+ Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null
+} catch {
+ if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) {
+ Write-Error "fail to move MAVEN_HOME"
+ }
+} finally {
+ try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
+ catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
+}
+
+Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"
diff --git a/parent/pom.xml b/parent/pom.xml
index d4a1352..74849ad 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -5,16 +5,11 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.logging.log4j</groupId>
- <artifactId>config</artifactId>
- <version>1.0-SNAPSHOT</version>
+ <artifactId>log4j-config-admin-bom</artifactId>
+ <version>${revision}</version>
</parent>
<artifactId>log4j-config-admin-parent</artifactId>
-
- <properties>
- <maven.compiler.source>17</maven.compiler.source>
- <maven.compiler.target>17</maven.compiler.target>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- </properties>
+ <packaging>pom</packaging>
</project>
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 253c2e2..7573eb3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,17 +1,145 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+ child.project.url.inherit.append.path="false">
+
+ <!-- ██ ██ █████ ██████ ███ ██ ██ ███ ██ ██████ ██
+ ██ ██ ██ ██ ██ ██ ████ ██ ██ ████ ██ ██ ██
+ ██ █ ██ ███████ ██████ ██ ██ ██ ██ ██ ██ ██ ██ ███ ██
+ ██ ███ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
+ ███ ███ ██ ██ ██ ██ ██ ████ ██ ██ ████ ██████ ██
+
+ `log4j-config-admin` project modules should use `log4j-config-admin-parent` as their parents, not this POM!
+ This POM constitutes the BOM to be imported by applications using `log4j-config-admin` project modules. -->
+
<modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.logging</groupId>
+ <artifactId>logging-parent</artifactId>
+ <version>10.5.0</version>
+ </parent>
+
<groupId>org.apache.logging.log4j</groupId>
- <artifactId>config</artifactId>
- <version>1.0-SNAPSHOT</version>
+ <artifactId>log4j-config-admin-bom</artifactId>
+ <version>${revision}</version>
+ <packaging>pom</packaging>
+
+ <url>https://logging.apache.org/log4j/config-admin</url>
+
+ <inceptionYear>2024</inceptionYear>
+
+ <developers>
+
+ <developer>
+ <name>Apache Logging Services team</name>
+ <email>dev@logging.apache.org</email>
+ <url>https://logging.apache.org/team-list.html</url>
+ </developer>
+
+ </developers>
+
+ <modules>
+
+ <!-- the parent POM must come first: -->
+ <module>parent</module>
+
+ <!-- Modules here must have a corresponding entry in `dependencyManagement > dependencies` block below! -->
+ <module>api</module>
+ <module>log4j-core</module>
+ <module>logback</module>
+ <module>jul</module>
+
+ </modules>
+
+ <scm child.scm.connection.inherit.append.path="false" child.scm.developerConnection.inherit.append.path="false"
+ child.scm.url.inherit.append.path="false">
+ <connection>scm:git:git@github.com:apache/logging-log4j-config-admin.git</connection>
+ <developerConnection>scm:git:git@github.com:apache/logging-log4j-config-admin.git</developerConnection>
+ <tag>HEAD</tag>
+ <url>https://github.com/apache/logging-log4j-config-admin</url>
+ </scm>
+
+ <issueManagement>
+ <system>GitHub Issues</system>
+ <url>https://github.com/apache/logging-log4j-config-admin/issues</url>
+ </issueManagement>
+
+ <ciManagement>
+ <system>GitHub Actions</system>
+ <url>https://github.com/apache/logging-log4j-config-admin/actions</url>
+ </ciManagement>
+
+ <distributionManagement>
+ <downloadUrl>https://logging.apache.org/log4j/config-admin/latest/#distribution</downloadUrl>
+ </distributionManagement>
<properties>
- <maven.compiler.source>17</maven.compiler.source>
- <maven.compiler.target>17</maven.compiler.target>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+
+ <!-- project version -->
+ <revision>0.1.0-SNAPSHOT</revision>
+
+ <!-- disable `maven-site-plugin`-->
+ <maven.site.skip>true</maven.site.skip>
+ <maven.site.deploy.skip>true</maven.site.deploy.skip>
+
</properties>
+
+ <!-- `dependencyManagement` must only contain `log4j-transform` modules and nothing else!
+ Modules here must have a corresponding entry in `modules` block above! -->
+ <dependencyManagement>
+ <dependencies>
+
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-config-admin-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-config-admin-jul</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-config-admin-log4j-core</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-config-admin-logback</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ </dependencies>
+ </dependencyManagement>
+
+ <build>
+ <plugins>
+
+ <!-- Enable BOM flattening -->
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>flatten-maven-plugin</artifactId>
+ <version>${flatten-maven-plugin.version}</version>
+ <executions>
+ <execution>
+ <id>flatten-bom</id>
+ <goals>
+ <goal>flatten</goal>
+ </goals>
+ <phase>process-resources</phase>
+ <inherited>false</inherited>
+ </execution>
+ </executions>
+ </plugin>
+
+ </plugins>
+ </build>
+
</project>
\ No newline at end of file
(logging-admin) 05/08: Add short README.adoc
Posted by pk...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
pkarwasz pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/logging-admin.git
commit 0ad3df2370926a4de7125ebc1b48138e4a28c7b6
Author: Piotr P. Karwasz <pi...@karwasz.org>
AuthorDate: Sat Nov 2 12:01:17 2024 +0100
Add short README.adoc
---
README.adoc | 23 ++++++++++++++++++++++
.../logging/admin/LoggingConfigurationAdmin.java | 10 +++++++---
2 files changed, 30 insertions(+), 3 deletions(-)
diff --git a/README.adoc b/README.adoc
new file mode 100644
index 0000000..43b2fa4
--- /dev/null
+++ b/README.adoc
@@ -0,0 +1,23 @@
+This repository contains an initial sketch of an *Apache Logging Admin API*.
+
+The purpose of the API is to allow the programmatic configuration of the logging backend in an implementation independent way.
+
+[source,java]
+----
+import org.apache.logging.admin.LoggingConfigurationAdmin;
+
+public final class Main {
+ private static final Object TOKEN = new Object();
+
+ public static void main(String[] args) {
+ int i = 0;
+ while (i < args.length) {
+ if ("--logLevel".equals(args[i]) && ++i < args.length) {
+ LoggingConfigurationAdmin admin = LoggingConfigurationAdmin.getInstance(TOKEN);
+ admin.setLoggerLevel("", args[i]);
+ }
+ i++;
+ }
+ }
+}
+----
\ No newline at end of file
diff --git a/api/src/main/java/org/apache/logging/admin/LoggingConfigurationAdmin.java b/api/src/main/java/org/apache/logging/admin/LoggingConfigurationAdmin.java
index 0e366f1..50be2d8 100644
--- a/api/src/main/java/org/apache/logging/admin/LoggingConfigurationAdmin.java
+++ b/api/src/main/java/org/apache/logging/admin/LoggingConfigurationAdmin.java
@@ -45,9 +45,13 @@ import org.jspecify.annotations.Nullable;
* private static final Object TOKEN = new Object();
*
* public static void main(String[] args) {
- * if (args.length == 2 && "--logLevel".equals(args[0])) {
- * LoggingConfigurationAdmin admin = LoggingConfigurationAdmin.getInstance(TOKEN);
- * admin.setLoggerLevel("", args[1]);
+ * int i = 0;
+ * while (i < args.length) {
+ * if ("--logLevel".equals(args[i]) && ++i < args.length) {
+ * LoggingConfigurationAdmin admin = LoggingConfigurationAdmin.getInstance(TOKEN);
+ * admin.setLoggerLevel("", args[i]);
+ * }
+ * i++;
* }
* }
* }