1
0

Introduce end-of-line normalization

This commit is contained in:
Alex Herbert
2023-09-02 13:36:58 +01:00
parent 2e0bd27487
commit acd4893d89
15 changed files with 3631 additions and 3630 deletions

1
.gitattributes vendored Normal file
View File

@@ -0,0 +1 @@
* text=auto

View File

@@ -1,85 +1,85 @@
# 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.
name: "CodeQL"
on:
push:
branches: [ master ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ master ]
schedule:
- cron: '33 9 * * 4'
permissions:
contents: read
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'java' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
# Learn more about CodeQL language support at https://git.io/codeql-language-support
steps:
- name: Checkout repository
uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744
# 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.
name: "CodeQL"
on:
push:
branches: [ master ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ master ]
schedule:
- cron: '33 9 * * 4'
permissions:
contents: read
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'java' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
# Learn more about CodeQL language support at https://git.io/codeql-language-support
steps:
- name: Checkout repository
uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744
with:
persist-credentials: false
- uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
restore-keys: |
${{ runner.os }}-maven-
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
- uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
restore-keys: |
${{ runner.os }}-maven-
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@00e563ead9f72a8461b24876bee2d0c2e8bd2ee8 # v2.21.5
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@00e563ead9f72a8461b24876bee2d0c2e8bd2ee8 # v2.21.5
# Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
#- run: |
# make bootstrap
# make release
- name: Perform CodeQL Analysis
# Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
#- run: |
# make bootstrap
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@00e563ead9f72a8461b24876bee2d0c2e8bd2ee8 # v2.21.5

View File

@@ -1,52 +1,52 @@
# 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.
name: Java CI
on: [push, pull_request]
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
continue-on-error: ${{ matrix.experimental }}
strategy:
matrix:
java: [ 8, 11, 17 ]
experimental: [false]
# include:
# - java: 18-ea
# experimental: true
steps:
- uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744
# 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.
name: Java CI
on: [push, pull_request]
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
continue-on-error: ${{ matrix.experimental }}
strategy:
matrix:
java: [ 8, 11, 17 ]
experimental: [false]
# include:
# - java: 18-ea
# experimental: true
steps:
- uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744
with:
persist-credentials: false
- uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
restore-keys: |
${{ runner.os }}-maven-
- name: Set up JDK ${{ matrix.java }}
- uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
restore-keys: |
${{ runner.os }}-maven-
- name: Set up JDK ${{ matrix.java }}
uses: actions/setup-java@cd89f46ac9d01407894225f350157564c9c7cee2 # v3.12.0
with:
distribution: 'temurin'
java-version: ${{ matrix.java }}
- name: Build with Maven
run: mvn -V --no-transfer-progress -D doclint=none --file pom.xml
with:
distribution: 'temurin'
java-version: ${{ matrix.java }}
- name: Build with Maven
run: mvn -V --no-transfer-progress -D doclint=none --file pom.xml

206
README.md
View File

@@ -1,103 +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.
-->
<!---
+======================================================================+
|**** ****|
|**** THIS FILE IS GENERATED BY THE COMMONS BUILD PLUGIN ****|
|**** DO NOT EDIT DIRECTLY ****|
|**** ****|
+======================================================================+
| TEMPLATE FILE: readme-md-template.md |
| commons-build-plugin/trunk/src/main/resources/commons-xdoc-templates |
+======================================================================+
| |
| 1) Re-generate using: mvn commons:readme-md |
| |
| 2) Set the following properties in the component's pom: |
| - commons.componentid (required, alphabetic, lower case) |
| - commons.release.version (required) |
| |
| 3) Example Properties |
| |
| <properties> |
| <commons.componentid>math</commons.componentid> |
| <commons.release.version>1.2</commons.release.version> |
| </properties> |
| |
+======================================================================+
--->
Apache Commons Logging
===================
[![GitHub Actions Status](https://github.com/apache/commons-logging/workflows/Java%20CI/badge.svg)](https://github.com/apache/commons-logging/actions)
[![Maven Central](https://maven-badges.herokuapp.com/maven-central/commons-logging/commons-logging/badge.svg?gav=true)](https://maven-badges.herokuapp.com/maven-central/commons-logging/commons-logging/?gav=true)
[![CodeQL](https://github.com/apache/commons-logging/workflows/CodeQL/badge.svg)](https://github.com/apache/commons-logging/actions/workflows/codeql-analysis.yml?query=workflow%3ACodeQL)
Apache Commons Logging is a thin adapter allowing configurable bridging to other, well known logging systems.
Documentation
-------------
More information can be found on the [Apache Commons Logging homepage](https://commons.apache.org/proper/commons-logging).
The [Javadoc](https://commons.apache.org/proper/commons-logging/javadocs/api-release) can be browsed.
Questions related to the usage of Apache Commons Logging should be posted to the [user mailing list][ml].
Where can I get the latest release?
-----------------------------------
You can download source and binaries from our [download page](https://commons.apache.org/proper/commons-logging/download_logging.cgi).
Alternatively, you can pull it from the central Maven repositories:
```xml
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
```
Contributing
------------
We accept Pull Requests via GitHub. The [developer mailing list][ml] is the main channel of communication for contributors.
There are some guidelines which will make applying PRs easier for us:
+ No tabs! Please use spaces for indentation.
+ Respect the code style.
+ Create minimal diffs - disable on save actions like reformat source code or organize imports. If you feel the source code should be reformatted create a separate PR for this change.
+ Provide JUnit tests for your changes and make sure your changes don't break any existing tests by running ```mvn```.
If you plan to contribute on a regular basis, please consider filing a [contributor license agreement](https://www.apache.org/licenses/#clas).
You can learn more about contributing via GitHub in our [contribution guidelines](CONTRIBUTING.md).
License
-------
This code is under the [Apache License v2](https://www.apache.org/licenses/LICENSE-2.0).
See the `NOTICE.txt` file for required notices and attributions.
Donations
---------
You like Apache Commons Logging? Then [donate back to the ASF](https://www.apache.org/foundation/contributing.html) to support the development.
Additional Resources
--------------------
+ [Apache Commons Homepage](https://commons.apache.org/)
+ [Apache Issue Tracker (JIRA)](https://issues.apache.org/jira/browse/LOGGING)
+ [Apache Commons Twitter Account](https://twitter.com/ApacheCommons)
+ `#apache-commons` IRC channel on `irc.freenode.org`
[ml]:https://commons.apache.org/mail-lists.html
<!---
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 FILE IS GENERATED BY THE COMMONS BUILD PLUGIN ****|
|**** DO NOT EDIT DIRECTLY ****|
|**** ****|
+======================================================================+
| TEMPLATE FILE: readme-md-template.md |
| commons-build-plugin/trunk/src/main/resources/commons-xdoc-templates |
+======================================================================+
| |
| 1) Re-generate using: mvn commons:readme-md |
| |
| 2) Set the following properties in the component's pom: |
| - commons.componentid (required, alphabetic, lower case) |
| - commons.release.version (required) |
| |
| 3) Example Properties |
| |
| <properties> |
| <commons.componentid>math</commons.componentid> |
| <commons.release.version>1.2</commons.release.version> |
| </properties> |
| |
+======================================================================+
--->
Apache Commons Logging
===================
[![GitHub Actions Status](https://github.com/apache/commons-logging/workflows/Java%20CI/badge.svg)](https://github.com/apache/commons-logging/actions)
[![Maven Central](https://maven-badges.herokuapp.com/maven-central/commons-logging/commons-logging/badge.svg?gav=true)](https://maven-badges.herokuapp.com/maven-central/commons-logging/commons-logging/?gav=true)
[![CodeQL](https://github.com/apache/commons-logging/workflows/CodeQL/badge.svg)](https://github.com/apache/commons-logging/actions/workflows/codeql-analysis.yml?query=workflow%3ACodeQL)
Apache Commons Logging is a thin adapter allowing configurable bridging to other, well known logging systems.
Documentation
-------------
More information can be found on the [Apache Commons Logging homepage](https://commons.apache.org/proper/commons-logging).
The [Javadoc](https://commons.apache.org/proper/commons-logging/javadocs/api-release) can be browsed.
Questions related to the usage of Apache Commons Logging should be posted to the [user mailing list][ml].
Where can I get the latest release?
-----------------------------------
You can download source and binaries from our [download page](https://commons.apache.org/proper/commons-logging/download_logging.cgi).
Alternatively, you can pull it from the central Maven repositories:
```xml
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
```
Contributing
------------
We accept Pull Requests via GitHub. The [developer mailing list][ml] is the main channel of communication for contributors.
There are some guidelines which will make applying PRs easier for us:
+ No tabs! Please use spaces for indentation.
+ Respect the code style.
+ Create minimal diffs - disable on save actions like reformat source code or organize imports. If you feel the source code should be reformatted create a separate PR for this change.
+ Provide JUnit tests for your changes and make sure your changes don't break any existing tests by running ```mvn```.
If you plan to contribute on a regular basis, please consider filing a [contributor license agreement](https://www.apache.org/licenses/#clas).
You can learn more about contributing via GitHub in our [contribution guidelines](CONTRIBUTING.md).
License
-------
This code is under the [Apache License v2](https://www.apache.org/licenses/LICENSE-2.0).
See the `NOTICE.txt` file for required notices and attributions.
Donations
---------
You like Apache Commons Logging? Then [donate back to the ASF](https://www.apache.org/foundation/contributing.html) to support the development.
Additional Resources
--------------------
+ [Apache Commons Homepage](https://commons.apache.org/)
+ [Apache Issue Tracker (JIRA)](https://issues.apache.org/jira/browse/LOGGING)
+ [Apache Commons Twitter Account](https://twitter.com/ApacheCommons)
+ `#apache-commons` IRC channel on `irc.freenode.org`
[ml]:https://commons.apache.org/mail-lists.html

View File

@@ -1,191 +1,191 @@
<?xml version="1.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.
-->
<!--
This file is also used by the maven-changes-plugin to generate the release notes.
Useful ways of finding items to add to this file are:
1. Add items when you fix a bug or add a feature (this makes the
release process easy :-).
2. Do a JIRA search for tickets closed since the previous release.
3. Use the report generated by the maven-changelog-plugin to see all
SVN commits. TBA how to use this with SVN.
To generate the release notes from this file:
mvn changes:announcement-generate -Prelease-notes [-Dchanges.version=nn]
then tweak the formatting if necessary
and commit
The <action> type attribute can be add,update,fix,remove.
-->
<document xmlns="http://maven.apache.org/changes/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/changes/1.0.0 http://maven.apache.org/xsd/changes-1.0.0.xsd">
<properties>
<title>Release Notes</title>
</properties>
<body>
<release version="1.3.0" date="TBD" description="This is a maintenance release containing bug fixes. Java 8 or later is required.">
<!-- FIXES -->
<action issue="LOGGING-165" dev="britter" type="add">
Add Automatic-Module-Name Manifest Header for Java 9 compatibility.
</action>
<action issue="LOGGING-163" dev="ggregory" type="fix" due-to="Kaloyan Spiridonov">
BufferedReader is not closed properly.
</action>
<action issue="LOGGING-177" dev="ggregory" type="fix" due-to="Arturo Bernal">
Remove redundant initializer #46
</action>
<action dev="ggregory" type="fix" due-to="Jakob van Kruijssen, Bruno P. Kinoshita, Gary Gregory">
Use a weak reference for the cached class loader #71.
</action>
<action dev="ggregory" type="fix" due-to="xiaozhiliaoo">
Add more entries to .gitignore file #25.
</action>
<action dev="ggregory" type="fix" due-to="Arturo Bernal">
Minor Improvements #34.
</action>
<action type="fix" dev="ggregory" due-to="step-security-bot, Gary Gregory">
[StepSecurity] ci: Harden GitHub Actions #145.
</action>
<!-- UPDATES -->
<action dev="ggregory" type="update" due-to="Gary Gregory">
Bump Java from 6 to 8.
</action>
<action dev="ggregory" type="update" due-to="Dependabot, Gary Gregory">
Bump actions/cache from 2 to 3.0.10 #50, #77, #95, #98, #107, #110.
</action>
<action dev="ggregory" type="update" due-to="Dependabot, Gary Gregory">
Bump actions/checkout from 2.3.1 to 3.1.0, #24, #63, #75, #109.
</action>
<action dev="ggregory" type="update" due-to="Dependabot, Gary Gregory">
Bump actions/setup-java from 1.4.0 to 3.5.1 #21.
</action>
<action dev="ggregory" type="update" due-to="Dependabot, Gary Gregory">
Bump junit from 3.8.1 to 5.9.1 Vintage #23, #38.
</action>
<action dev="ggregory" type="update" due-to="Dependabot">
Bump clirr-maven-plugin from 2.2.2 to 2.8 #14.
</action>
<action dev="ggregory" type="update" due-to="Dependabot">
Bump findbugs-maven-plugin from 2.5.2 to 3.0.5 #8.
</action>
<action dev="ggregory" type="update" due-to="Dependabot, Gary Gregory">
Bump maven-failsafe-plugin from 2.12 to 3.0.0-M7 #31, #91.
</action>
<action dev="ggregory" type="update" due-to="Gary Gregory">
Bump spotbugs-surefire-plugin from 2.22.2 to 3.0.0-M5.
</action>
<action dev="ggregory" type="update" due-to="Dependabot">
Bump maven-dependency-plugin from 2.4 to 3.5.0 #29, #79, #117, #131.
</action>
<action dev="ggregory" type="update" due-to="Dependabot">
Bump maven-pmd-plugin from 3.3 to 3.19.0 #28, #90, #100, #103.
</action>
<action dev="ggregory" type="update" due-to="Dependabot">
Bump maven-assembly-plugin from 2.5 to 3.4.2 #30, #94, #96.
</action>
<action dev="ggregory" type="update" due-to="Dependabot">
Bump servlet-api from 2.3 to 2.5 #27.
</action>
<action dev="ggregory" type="update" due-to="Gary Gregory, Dependabot">
Bump maven-checkstyle-plugin from 2.7 to 3.2.1 #35, #101, #130.
</action>
<action dev="ggregory" type="update" due-to="Dependabot">
Bump spotbugs-maven-plugin from 4.1.4 to 4.7.2.1 #33, #70, #78, #93, #97, #102, #112.
</action>
<action dev="ggregory" type="update" due-to="Dependabot">
Bump spotbugs from 4.5.3 to 4.7.3 #81, #87, #92, #104, #115.
</action>
<action dev="kinow" type="update" due-to="Dependabot, Gary Gregory">
Bump commons-parent from 52 to 59 #82, #106, #122, #126, #143.
</action>
<action dev="kinow" type="update" due-to="Dependabot">
Bump github/codeql-action from 1 to 2 #86.
</action>
</release>
<release version="1.2" date="2014-07-11" description="This is a maintenance release containing bug fixes. Java 6 or later is required.">
<action issue="LOGGING-37" dev="tn" type="fix" due-to="Matthias Ernst,Archie Cobbs">
Improve performance of LogFactory#getFactory() by calling Thread#currentThread()#getContextClassLoader()
directly instead of using reflection. As a consequence support for JDK 1.1 has been dropped.
</action>
<action issue="LOGGING-156" dev="tn" type="fix" due-to="Mikolaj Izdebski">
Fix SecurityAllowedTestCase when executed with OpenJDK 1.7 due to an additional required RuntimePermission.
</action>
<action issue="LOGGING-157" dev="tn" type="fix" due-to="Ville Skyttä">
Fix javadoc to comply with javadoc tool from jdk 1.8.
</action>
</release>
<release version="1.1.3" date="2013-05-23" description="This is a maintenance release containing bug fixes.">
<action issue="LOGGING-151" dev="tn" type="fix" due-to="Krzysztof Daniel">
Use "org.apache.commons.logging" as bundle symbolic name.
</action>
</release>
<release version="1.1.2" date="2013-03-20" description="This is a maintenance release containing bug fixes.">
<action issue="LOGGING-124" dev="tn" type="fix" due-to="Christian Schneider">
The jar manifest now contains proper OSGi-related metadata information.
</action>
<action issue="LOGGING-144" dev="tn" type="fix" due-to="Sebastian Bazley">
LogFactory and LogFactoryImpl will not swallow certain errors anymore (ThreadDeath
and VirtualMachineError).
</action>
<action issue="LOGGING-135" dev="tn" type="update" due-to="Sebastian Bazley">
Improved thread-safety for several log adapters, including AvalonLogger, SimpleLog,
Log4JLogger, LogKitLogger.
</action>
<action issue="LOGGING-138" dev="tn" type="update" due-to="Luke Lu">
In case of a discovery failure now also the stacktrace of the cause will be
added to the diagnostic message.
</action>
<action issue="LOGGING-132" dev="tn" type="fix" due-to="Nathan Niesen">
Jdk14Logger now correctly uses the specified logger name.
</action>
<action issue="LOGGING-133" dev="tn" type="update" due-to="Shevek">
Change scope of Jdk14Logger.log(Level, String, Throwable) to protected, allowing
subclasses to modify the logging output.
</action>
<action issue="LOGGING-146" dev="tn" type="fix" due-to="Sebastian Bazley">
Properly synchronize access to protected static field LogFactory.nullClassLoaderFactory.
</action>
<action issue="LOGGING-119" dev="tn" type="fix" due-to="Nitzan Niv, Philippe Mouawad">
Prevent potential deadlock scenario in WeakHashtable.
</action>
<action issue="LOGGING-130" dev="sebb" type="fix" due-to="Matthew P. Del Buono">
Potential missing privileged block for class loader.
</action>
<action issue="LOGGING-145" dev="sebb" type="fix">
LogFactoryImpl.setAttribute - possible NPE.
</action>
<action issue="LOGGING-142" dev="sebb" type="fix" due-to="Jingguo Yao">
Log4JLogger uses deprecated static members of Priority such as INFO.
</action>
<action issue="LOGGING-128" dev="sebb" type="fix" due-to="Peter Lawrey">
Static analysis suggests a number of potential improvements.
</action>
<action issue="LOGGING-147" dev="sebb" type="fix">
SimpleLog.log - unsafe update of shortLogName.
</action>
<action issue="LOGGING-148" dev="sebb" type="fix">
LogFactory.diagnosticPrefix and diagnosticsStream could be final.
</action>
</release>
</body>
</document>
<?xml version="1.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.
-->
<!--
This file is also used by the maven-changes-plugin to generate the release notes.
Useful ways of finding items to add to this file are:
1. Add items when you fix a bug or add a feature (this makes the
release process easy :-).
2. Do a JIRA search for tickets closed since the previous release.
3. Use the report generated by the maven-changelog-plugin to see all
SVN commits. TBA how to use this with SVN.
To generate the release notes from this file:
mvn changes:announcement-generate -Prelease-notes [-Dchanges.version=nn]
then tweak the formatting if necessary
and commit
The <action> type attribute can be add,update,fix,remove.
-->
<document xmlns="http://maven.apache.org/changes/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/changes/1.0.0 http://maven.apache.org/xsd/changes-1.0.0.xsd">
<properties>
<title>Release Notes</title>
</properties>
<body>
<release version="1.3.0" date="TBD" description="This is a maintenance release containing bug fixes. Java 8 or later is required.">
<!-- FIXES -->
<action issue="LOGGING-165" dev="britter" type="add">
Add Automatic-Module-Name Manifest Header for Java 9 compatibility.
</action>
<action issue="LOGGING-163" dev="ggregory" type="fix" due-to="Kaloyan Spiridonov">
BufferedReader is not closed properly.
</action>
<action issue="LOGGING-177" dev="ggregory" type="fix" due-to="Arturo Bernal">
Remove redundant initializer #46
</action>
<action dev="ggregory" type="fix" due-to="Jakob van Kruijssen, Bruno P. Kinoshita, Gary Gregory">
Use a weak reference for the cached class loader #71.
</action>
<action dev="ggregory" type="fix" due-to="xiaozhiliaoo">
Add more entries to .gitignore file #25.
</action>
<action dev="ggregory" type="fix" due-to="Arturo Bernal">
Minor Improvements #34.
</action>
<action type="fix" dev="ggregory" due-to="step-security-bot, Gary Gregory">
[StepSecurity] ci: Harden GitHub Actions #145.
</action>
<!-- UPDATES -->
<action dev="ggregory" type="update" due-to="Gary Gregory">
Bump Java from 6 to 8.
</action>
<action dev="ggregory" type="update" due-to="Dependabot, Gary Gregory">
Bump actions/cache from 2 to 3.0.10 #50, #77, #95, #98, #107, #110.
</action>
<action dev="ggregory" type="update" due-to="Dependabot, Gary Gregory">
Bump actions/checkout from 2.3.1 to 3.1.0, #24, #63, #75, #109.
</action>
<action dev="ggregory" type="update" due-to="Dependabot, Gary Gregory">
Bump actions/setup-java from 1.4.0 to 3.5.1 #21.
</action>
<action dev="ggregory" type="update" due-to="Dependabot, Gary Gregory">
Bump junit from 3.8.1 to 5.9.1 Vintage #23, #38.
</action>
<action dev="ggregory" type="update" due-to="Dependabot">
Bump clirr-maven-plugin from 2.2.2 to 2.8 #14.
</action>
<action dev="ggregory" type="update" due-to="Dependabot">
Bump findbugs-maven-plugin from 2.5.2 to 3.0.5 #8.
</action>
<action dev="ggregory" type="update" due-to="Dependabot, Gary Gregory">
Bump maven-failsafe-plugin from 2.12 to 3.0.0-M7 #31, #91.
</action>
<action dev="ggregory" type="update" due-to="Gary Gregory">
Bump spotbugs-surefire-plugin from 2.22.2 to 3.0.0-M5.
</action>
<action dev="ggregory" type="update" due-to="Dependabot">
Bump maven-dependency-plugin from 2.4 to 3.5.0 #29, #79, #117, #131.
</action>
<action dev="ggregory" type="update" due-to="Dependabot">
Bump maven-pmd-plugin from 3.3 to 3.19.0 #28, #90, #100, #103.
</action>
<action dev="ggregory" type="update" due-to="Dependabot">
Bump maven-assembly-plugin from 2.5 to 3.4.2 #30, #94, #96.
</action>
<action dev="ggregory" type="update" due-to="Dependabot">
Bump servlet-api from 2.3 to 2.5 #27.
</action>
<action dev="ggregory" type="update" due-to="Gary Gregory, Dependabot">
Bump maven-checkstyle-plugin from 2.7 to 3.2.1 #35, #101, #130.
</action>
<action dev="ggregory" type="update" due-to="Dependabot">
Bump spotbugs-maven-plugin from 4.1.4 to 4.7.2.1 #33, #70, #78, #93, #97, #102, #112.
</action>
<action dev="ggregory" type="update" due-to="Dependabot">
Bump spotbugs from 4.5.3 to 4.7.3 #81, #87, #92, #104, #115.
</action>
<action dev="kinow" type="update" due-to="Dependabot, Gary Gregory">
Bump commons-parent from 52 to 59 #82, #106, #122, #126, #143.
</action>
<action dev="kinow" type="update" due-to="Dependabot">
Bump github/codeql-action from 1 to 2 #86.
</action>
</release>
<release version="1.2" date="2014-07-11" description="This is a maintenance release containing bug fixes. Java 6 or later is required.">
<action issue="LOGGING-37" dev="tn" type="fix" due-to="Matthias Ernst,Archie Cobbs">
Improve performance of LogFactory#getFactory() by calling Thread#currentThread()#getContextClassLoader()
directly instead of using reflection. As a consequence support for JDK 1.1 has been dropped.
</action>
<action issue="LOGGING-156" dev="tn" type="fix" due-to="Mikolaj Izdebski">
Fix SecurityAllowedTestCase when executed with OpenJDK 1.7 due to an additional required RuntimePermission.
</action>
<action issue="LOGGING-157" dev="tn" type="fix" due-to="Ville Skyttä">
Fix javadoc to comply with javadoc tool from jdk 1.8.
</action>
</release>
<release version="1.1.3" date="2013-05-23" description="This is a maintenance release containing bug fixes.">
<action issue="LOGGING-151" dev="tn" type="fix" due-to="Krzysztof Daniel">
Use "org.apache.commons.logging" as bundle symbolic name.
</action>
</release>
<release version="1.1.2" date="2013-03-20" description="This is a maintenance release containing bug fixes.">
<action issue="LOGGING-124" dev="tn" type="fix" due-to="Christian Schneider">
The jar manifest now contains proper OSGi-related metadata information.
</action>
<action issue="LOGGING-144" dev="tn" type="fix" due-to="Sebastian Bazley">
LogFactory and LogFactoryImpl will not swallow certain errors anymore (ThreadDeath
and VirtualMachineError).
</action>
<action issue="LOGGING-135" dev="tn" type="update" due-to="Sebastian Bazley">
Improved thread-safety for several log adapters, including AvalonLogger, SimpleLog,
Log4JLogger, LogKitLogger.
</action>
<action issue="LOGGING-138" dev="tn" type="update" due-to="Luke Lu">
In case of a discovery failure now also the stacktrace of the cause will be
added to the diagnostic message.
</action>
<action issue="LOGGING-132" dev="tn" type="fix" due-to="Nathan Niesen">
Jdk14Logger now correctly uses the specified logger name.
</action>
<action issue="LOGGING-133" dev="tn" type="update" due-to="Shevek">
Change scope of Jdk14Logger.log(Level, String, Throwable) to protected, allowing
subclasses to modify the logging output.
</action>
<action issue="LOGGING-146" dev="tn" type="fix" due-to="Sebastian Bazley">
Properly synchronize access to protected static field LogFactory.nullClassLoaderFactory.
</action>
<action issue="LOGGING-119" dev="tn" type="fix" due-to="Nitzan Niv, Philippe Mouawad">
Prevent potential deadlock scenario in WeakHashtable.
</action>
<action issue="LOGGING-130" dev="sebb" type="fix" due-to="Matthew P. Del Buono">
Potential missing privileged block for class loader.
</action>
<action issue="LOGGING-145" dev="sebb" type="fix">
LogFactoryImpl.setAttribute - possible NPE.
</action>
<action issue="LOGGING-142" dev="sebb" type="fix" due-to="Jingguo Yao">
Log4JLogger uses deprecated static members of Priority such as INFO.
</action>
<action issue="LOGGING-128" dev="sebb" type="fix" due-to="Peter Lawrey">
Static analysis suggests a number of potential improvements.
</action>
<action issue="LOGGING-147" dev="sebb" type="fix">
SimpleLog.log - unsafe update of shortLogName.
</action>
<action issue="LOGGING-148" dev="sebb" type="fix">
LogFactory.diagnosticPrefix and diagnosticsStream could be final.
</action>
</release>
</body>
</document>

File diff suppressed because it is too large Load Diff

View File

@@ -1,66 +1,66 @@
/*
* 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.commons.logging;
import junit.framework.TestCase;
/**
* Generic tests that can be applied to any log adapter by
* subclassing this class and defining method getLogObject
* appropriately.
*/
public abstract class AbstractLogTest extends TestCase {
public abstract Log getLogObject();
public void testLoggingWithNullParameters()
{
final Log log = this.getLogObject();
assertNotNull(log);
log.debug(null);
log.debug(null, null);
log.debug(log.getClass().getName() + ": debug statement");
log.debug(log.getClass().getName() + ": debug statement w/ null exception", new RuntimeException());
log.error(null);
log.error(null, null);
log.error(log.getClass().getName() + ": error statement");
log.error(log.getClass().getName() + ": error statement w/ null exception", new RuntimeException());
log.fatal(null);
log.fatal(null, null);
log.fatal(log.getClass().getName() + ": fatal statement");
log.fatal(log.getClass().getName() + ": fatal statement w/ null exception", new RuntimeException());
log.info(null);
log.info(null, null);
log.info(log.getClass().getName() + ": info statement");
log.info(log.getClass().getName() + ": info statement w/ null exception", new RuntimeException());
log.trace(null);
log.trace(null, null);
log.trace(log.getClass().getName() + ": trace statement");
log.trace(log.getClass().getName() + ": trace statement w/ null exception", new RuntimeException());
log.warn(null);
log.warn(null, null);
log.warn(log.getClass().getName() + ": warn statement");
log.warn(log.getClass().getName() + ": warn statement w/ null exception", new RuntimeException());
}
}
/*
* 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.commons.logging;
import junit.framework.TestCase;
/**
* Generic tests that can be applied to any log adapter by
* subclassing this class and defining method getLogObject
* appropriately.
*/
public abstract class AbstractLogTest extends TestCase {
public abstract Log getLogObject();
public void testLoggingWithNullParameters()
{
final Log log = this.getLogObject();
assertNotNull(log);
log.debug(null);
log.debug(null, null);
log.debug(log.getClass().getName() + ": debug statement");
log.debug(log.getClass().getName() + ": debug statement w/ null exception", new RuntimeException());
log.error(null);
log.error(null, null);
log.error(log.getClass().getName() + ": error statement");
log.error(log.getClass().getName() + ": error statement w/ null exception", new RuntimeException());
log.fatal(null);
log.fatal(null, null);
log.fatal(log.getClass().getName() + ": fatal statement");
log.fatal(log.getClass().getName() + ": fatal statement w/ null exception", new RuntimeException());
log.info(null);
log.info(null, null);
log.info(log.getClass().getName() + ": info statement");
log.info(log.getClass().getName() + ": info statement w/ null exception", new RuntimeException());
log.trace(null);
log.trace(null, null);
log.trace(log.getClass().getName() + ": trace statement");
log.trace(log.getClass().getName() + ": trace statement w/ null exception", new RuntimeException());
log.warn(null);
log.warn(null, null);
log.warn(log.getClass().getName() + ": warn statement");
log.warn(log.getClass().getName() + ": warn statement w/ null exception", new RuntimeException());
}
}

View File

@@ -1,216 +1,216 @@
/*
* 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.commons.logging;
import junit.framework.TestCase;
/**
* test to emulate container and application isolated from container
*/
public class LoadTestCase extends TestCase{
//TODO: need some way to add service provider packages
static private String[] LOG_PCKG = {"org.apache.commons.logging",
"org.apache.commons.logging.impl"};
/**
* A custom classloader which "duplicates" logging classes available
* in the parent classloader into itself.
* <p>
* When asked to load a class that is in one of the LOG_PCKG packages,
* it loads the class itself (child-first). This class doesn't need
* to be set up with a classpath, as it simply uses the same classpath
* as the classloader that loaded it.
*/
static class AppClassLoader extends ClassLoader {
java.util.Map classes = new java.util.HashMap();
AppClassLoader(final ClassLoader parent) {
super(parent);
}
private Class def(final String name) throws ClassNotFoundException {
Class result = (Class) classes.get(name);
if (result != null) {
return result;
}
try {
final ClassLoader cl = this.getClass().getClassLoader();
final String classFileName = name.replace('.', '/') + ".class";
final java.io.InputStream is = cl.getResourceAsStream(classFileName);
final java.io.ByteArrayOutputStream out = new java.io.ByteArrayOutputStream();
while (is.available() > 0) {
out.write(is.read());
}
final byte[] data = out.toByteArray();
result = super.defineClass(name, data, 0, data.length);
classes.put(name, result);
return result;
} catch (final java.io.IOException ioe) {
throw new ClassNotFoundException(name + " caused by " + ioe.getMessage());
}
}
// not very trivial to emulate we must implement "findClass",
// but it will delegate to JUnit class loader first
@Override
public Class loadClass(final String name) throws ClassNotFoundException {
// isolates all logging classes, application in the same classloader too.
// filters exceptions to simplify handling in test
for (final String element : LOG_PCKG) {
if (name.startsWith(element) && name.indexOf("Exception") == -1) {
return def(name);
}
}
return super.loadClass(name);
}
}
/**
* Call the static setAllowFlawedContext method on the specified class
* (expected to be a UserClass loaded via a custom classloader), passing
* it the specified state parameter.
*/
private void setAllowFlawedContext(final Class c, final String state) throws Exception {
final Class[] params = {String.class};
final java.lang.reflect.Method m = c.getDeclaredMethod("setAllowFlawedContext", params);
m.invoke(null, state);
}
/**
* Test what happens when we play various classloader tricks like those
* that happen in web and j2ee containers.
* <p>
* Note that this test assumes that commons-logging.jar and log4j.jar
* are available via the system classpath.
*/
public void testInContainer()throws Exception{
//problem can be in this step (broken app container or missconfiguration)
//1. Thread.currentThread().setContextClassLoader(ClassLoader.getSystemClassLoader());
//2. Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
// we expect this :
// 1. Thread.currentThread().setContextClassLoader(appLoader);
// 2. Thread.currentThread().setContextClassLoader(null);
// Context classloader is same as class calling into log
Class cls = reload();
Thread.currentThread().setContextClassLoader(cls.getClassLoader());
execute(cls);
// Context classloader is the "bootclassloader". This is technically
// bad, but LogFactoryImpl.ALLOW_FLAWED_CONTEXT defaults to true so
// this test should pass.
cls = reload();
Thread.currentThread().setContextClassLoader(null);
execute(cls);
// Context classloader is the "bootclassloader". This is same as above
// except that ALLOW_FLAWED_CONTEXT is set to false; an error should
// now be reported.
cls = reload();
Thread.currentThread().setContextClassLoader(null);
try {
setAllowFlawedContext(cls, "false");
execute(cls);
fail("Logging config succeeded when context classloader was null!");
} catch (final LogConfigurationException ex) {
// expected; the boot classloader doesn't *have* JCL available
}
// Context classloader is the system classloader.
//
// This is expected to cause problems, as LogFactoryImpl will attempt
// to use the system classloader to load the Log4JLogger class, which
// will then be unable to cast that object to the Log interface loaded
// via the child classloader. However as ALLOW_FLAWED_CONTEXT defaults
// to true this test should pass.
cls = reload();
Thread.currentThread().setContextClassLoader(ClassLoader.getSystemClassLoader());
execute(cls);
// Context classloader is the system classloader. This is the same
// as above except that ALLOW_FLAWED_CONTEXT is set to false; an error
// should now be reported.
cls = reload();
Thread.currentThread().setContextClassLoader(ClassLoader.getSystemClassLoader());
try {
setAllowFlawedContext(cls, "false");
execute(cls);
fail("Error: somehow downcast a Logger loaded via system classloader"
+ " to the Log interface loaded via a custom classloader");
} catch (final LogConfigurationException ex) {
// expected
}
}
/**
* Load class UserClass via a temporary classloader which is a child of
* the classloader used to load this test class.
*/
private Class reload() throws Exception {
Class testObjCls = null;
final AppClassLoader appLoader = new AppClassLoader(this.getClass().getClassLoader());
try {
testObjCls = appLoader.loadClass(UserClass.class.getName());
} catch (final ClassNotFoundException cnfe) {
throw cnfe;
} catch (final Throwable t) {
t.printStackTrace();
fail("AppClassLoader failed ");
}
assertSame("app isolated", testObjCls.getClassLoader(), appLoader);
return testObjCls;
}
private void execute(final Class cls) throws Exception {
cls.newInstance();
}
@Override
public void setUp() {
// save state before test starts so we can restore it when test ends
origContextClassLoader = Thread.currentThread().getContextClassLoader();
}
@Override
public void tearDown() {
// restore original state so a test can't stuff up later tests.
Thread.currentThread().setContextClassLoader(origContextClassLoader);
}
private ClassLoader origContextClassLoader;
}
/*
* 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.commons.logging;
import junit.framework.TestCase;
/**
* test to emulate container and application isolated from container
*/
public class LoadTestCase extends TestCase{
//TODO: need some way to add service provider packages
static private String[] LOG_PCKG = {"org.apache.commons.logging",
"org.apache.commons.logging.impl"};
/**
* A custom classloader which "duplicates" logging classes available
* in the parent classloader into itself.
* <p>
* When asked to load a class that is in one of the LOG_PCKG packages,
* it loads the class itself (child-first). This class doesn't need
* to be set up with a classpath, as it simply uses the same classpath
* as the classloader that loaded it.
*/
static class AppClassLoader extends ClassLoader {
java.util.Map classes = new java.util.HashMap();
AppClassLoader(final ClassLoader parent) {
super(parent);
}
private Class def(final String name) throws ClassNotFoundException {
Class result = (Class) classes.get(name);
if (result != null) {
return result;
}
try {
final ClassLoader cl = this.getClass().getClassLoader();
final String classFileName = name.replace('.', '/') + ".class";
final java.io.InputStream is = cl.getResourceAsStream(classFileName);
final java.io.ByteArrayOutputStream out = new java.io.ByteArrayOutputStream();
while (is.available() > 0) {
out.write(is.read());
}
final byte[] data = out.toByteArray();
result = super.defineClass(name, data, 0, data.length);
classes.put(name, result);
return result;
} catch (final java.io.IOException ioe) {
throw new ClassNotFoundException(name + " caused by " + ioe.getMessage());
}
}
// not very trivial to emulate we must implement "findClass",
// but it will delegate to JUnit class loader first
@Override
public Class loadClass(final String name) throws ClassNotFoundException {
// isolates all logging classes, application in the same classloader too.
// filters exceptions to simplify handling in test
for (final String element : LOG_PCKG) {
if (name.startsWith(element) && name.indexOf("Exception") == -1) {
return def(name);
}
}
return super.loadClass(name);
}
}
/**
* Call the static setAllowFlawedContext method on the specified class
* (expected to be a UserClass loaded via a custom classloader), passing
* it the specified state parameter.
*/
private void setAllowFlawedContext(final Class c, final String state) throws Exception {
final Class[] params = {String.class};
final java.lang.reflect.Method m = c.getDeclaredMethod("setAllowFlawedContext", params);
m.invoke(null, state);
}
/**
* Test what happens when we play various classloader tricks like those
* that happen in web and j2ee containers.
* <p>
* Note that this test assumes that commons-logging.jar and log4j.jar
* are available via the system classpath.
*/
public void testInContainer()throws Exception{
//problem can be in this step (broken app container or missconfiguration)
//1. Thread.currentThread().setContextClassLoader(ClassLoader.getSystemClassLoader());
//2. Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
// we expect this :
// 1. Thread.currentThread().setContextClassLoader(appLoader);
// 2. Thread.currentThread().setContextClassLoader(null);
// Context classloader is same as class calling into log
Class cls = reload();
Thread.currentThread().setContextClassLoader(cls.getClassLoader());
execute(cls);
// Context classloader is the "bootclassloader". This is technically
// bad, but LogFactoryImpl.ALLOW_FLAWED_CONTEXT defaults to true so
// this test should pass.
cls = reload();
Thread.currentThread().setContextClassLoader(null);
execute(cls);
// Context classloader is the "bootclassloader". This is same as above
// except that ALLOW_FLAWED_CONTEXT is set to false; an error should
// now be reported.
cls = reload();
Thread.currentThread().setContextClassLoader(null);
try {
setAllowFlawedContext(cls, "false");
execute(cls);
fail("Logging config succeeded when context classloader was null!");
} catch (final LogConfigurationException ex) {
// expected; the boot classloader doesn't *have* JCL available
}
// Context classloader is the system classloader.
//
// This is expected to cause problems, as LogFactoryImpl will attempt
// to use the system classloader to load the Log4JLogger class, which
// will then be unable to cast that object to the Log interface loaded
// via the child classloader. However as ALLOW_FLAWED_CONTEXT defaults
// to true this test should pass.
cls = reload();
Thread.currentThread().setContextClassLoader(ClassLoader.getSystemClassLoader());
execute(cls);
// Context classloader is the system classloader. This is the same
// as above except that ALLOW_FLAWED_CONTEXT is set to false; an error
// should now be reported.
cls = reload();
Thread.currentThread().setContextClassLoader(ClassLoader.getSystemClassLoader());
try {
setAllowFlawedContext(cls, "false");
execute(cls);
fail("Error: somehow downcast a Logger loaded via system classloader"
+ " to the Log interface loaded via a custom classloader");
} catch (final LogConfigurationException ex) {
// expected
}
}
/**
* Load class UserClass via a temporary classloader which is a child of
* the classloader used to load this test class.
*/
private Class reload() throws Exception {
Class testObjCls = null;
final AppClassLoader appLoader = new AppClassLoader(this.getClass().getClassLoader());
try {
testObjCls = appLoader.loadClass(UserClass.class.getName());
} catch (final ClassNotFoundException cnfe) {
throw cnfe;
} catch (final Throwable t) {
t.printStackTrace();
fail("AppClassLoader failed ");
}
assertSame("app isolated", testObjCls.getClassLoader(), appLoader);
return testObjCls;
}
private void execute(final Class cls) throws Exception {
cls.newInstance();
}
@Override
public void setUp() {
// save state before test starts so we can restore it when test ends
origContextClassLoader = Thread.currentThread().getContextClassLoader();
}
@Override
public void tearDown() {
// restore original state so a test can't stuff up later tests.
Thread.currentThread().setContextClassLoader(origContextClassLoader);
}
private ClassLoader origContextClassLoader;
}

View File

@@ -1,43 +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.commons.logging.avalon;
import org.apache.avalon.framework.logger.NullLogger;
import org.apache.commons.logging.impl.AvalonLogger;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.AbstractLogTest;
import junit.framework.Test;
import junit.framework.TestSuite;
/**
*/
public class AvalonLoggerTestCase extends AbstractLogTest {
public static Test suite() {
final TestSuite suite = new TestSuite();
suite.addTestSuite(AvalonLoggerTestCase.class);
return suite;
}
@Override
public Log getLogObject() {
// Output does not seem to be used, so don't display it.
final Log log = new AvalonLogger(new NullLogger());
return log;
}
}
/*
* 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.commons.logging.avalon;
import org.apache.avalon.framework.logger.NullLogger;
import org.apache.commons.logging.impl.AvalonLogger;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.AbstractLogTest;
import junit.framework.Test;
import junit.framework.TestSuite;
/**
*/
public class AvalonLoggerTestCase extends AbstractLogTest {
public static Test suite() {
final TestSuite suite = new TestSuite();
suite.addTestSuite(AvalonLoggerTestCase.class);
return suite;
}
@Override
public Log getLogObject() {
// Output does not seem to be used, so don't display it.
final Log log = new AvalonLogger(new NullLogger());
return log;
}
}

View File

@@ -1,396 +1,396 @@
/*
* 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.commons.logging.jdk14;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.Iterator;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogManager;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
import junit.framework.Test;
import org.apache.commons.logging.DummyException;
import org.apache.commons.logging.PathableClassLoader;
import org.apache.commons.logging.PathableTestSuite;
/**
* <p>TestCase for JDK 1.4 logging when running on a JDK 1.4 system with
* custom configuration, so that JDK 1.4 should be selected and an appropriate
* logger configured per the configuration properties.</p>
*/
public class CustomConfigTestCase extends DefaultConfigTestCase {
protected static final String HANDLER_NAME = "org.apache.commons.logging.jdk14.TestHandler";
// ----------------------------------------------------------- Constructors
/**
* <p>Construct a new instance of this test case.</p>
*
* @param name Name of the test case
*/
public CustomConfigTestCase(final String name) {
super(name);
}
// ----------------------------------------------------- Instance Variables
/**
* <p>The customized {@code Handler} we will be using.</p>
*/
protected TestHandler handler;
/**
* <p>The underlying {@code Handler}s we will be using.</p>
*/
protected Handler handlers[];
/**
* <p>The underlying {@code Logger} we will be using.</p>
*/
protected Logger logger;
/**
* <p>The underlying {@code LogManager} we will be using.</p>
*/
protected LogManager manager;
/**
* <p>The message levels that should have been logged.</p>
*/
protected Level[] testLevels =
{ Level.FINE, Level.INFO, Level.WARNING, Level.SEVERE, Level.SEVERE };
/**
* <p>The message strings that should have been logged.</p>
*/
protected String[] testMessages =
{ "debug", "info", "warn", "error", "fatal" };
// ------------------------------------------- JUnit Infrastructure Methods
/**
* Given the name of a class that is somewhere in the classpath of the provided
* classloader, return the contents of the corresponding .class file.
*/
protected static byte[] readClass(final String name, final ClassLoader srcCL) throws Exception {
final String resName = name.replace('.', '/') + ".class";
System.err.println("Trying to load resource [" + resName + "]");
final InputStream is = srcCL.getResourceAsStream(resName);
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
System.err.println("Reading resource [" + resName + "]");
final byte[] buf = new byte[1000];
for(;;) {
final int read = is.read(buf);
if (read <= 0) {
break;
}
baos.write(buf, 0, read);
}
is.close();
return baos.toByteArray();
}
/**
* Make a class available in the system classloader even when its classfile is
* not present in the classpath configured for that classloader. This only
* works for classes for which all dependencies are already loaded in
* that classloader.
*/
protected static void loadTestHandler(final String className, final ClassLoader targetCL) {
try {
targetCL.loadClass(className);
// fail("Class already in target classloader");
return;
} catch (final ClassNotFoundException ex) {
// ok, go ahead and load it
}
try {
final ClassLoader srcCL = CustomConfigAPITestCase.class.getClassLoader();
final byte[] classData = readClass(className, srcCL);
final Class[] params = new Class[] { String.class, classData.getClass(), Integer.TYPE, Integer.TYPE };
final Method m = ClassLoader.class.getDeclaredMethod("defineClass", params);
final Object[] args = new Object[4];
args[0] = className;
args[1] = classData;
args[2] = new Integer(0);
args[3] = new Integer(classData.length);
m.setAccessible(true);
m.invoke(targetCL, args);
} catch (final Exception e) {
e.printStackTrace();
fail("Unable to load class " + className);
}
}
/**
* Set up instance variables required by this test case.
*/
@Override
public void setUp() throws Exception {
setUpManager
("org/apache/commons/logging/jdk14/CustomConfig.properties");
setUpLogger(this.getClass().getName());
setUpHandlers();
setUpFactory();
setUpLog(this.getClass().getName());
}
/**
* Return the tests included in this test suite.
*/
public static Test suite() throws Exception {
final PathableClassLoader cl = new PathableClassLoader(null);
cl.useExplicitLoader("junit.", Test.class.getClassLoader());
// the TestHandler class must be accessable from the System classloader
// in order for java.util.logging.LogManager.readConfiguration to
// be able to instantiate it. And this test case must see the same
// class in order to be able to access its data. Yes this is ugly
// but the whole jdk14 API is a ******* mess anyway.
final ClassLoader scl = ClassLoader.getSystemClassLoader();
loadTestHandler(HANDLER_NAME, scl);
cl.useExplicitLoader(HANDLER_NAME, scl);
cl.addLogicalLib("commons-logging");
cl.addLogicalLib("testclasses");
final Class testClass = cl.loadClass(CustomConfigTestCase.class.getName());
return new PathableTestSuite(testClass, cl);
}
/**
* Tear down instance variables required by this test case.
*/
@Override
public void tearDown() {
super.tearDown();
handlers = null;
logger = null;
manager = null;
}
// ----------------------------------------------------------- Test Methods
// Test logging message strings with exceptions
public void testExceptionMessages() throws Exception {
logExceptionMessages();
checkLogRecords(true);
}
// Test logging plain message strings
public void testPlainMessages() throws Exception {
logPlainMessages();
checkLogRecords(false);
}
// Test pristine Handlers instances
public void testPristineHandlers() {
assertNotNull(handlers);
assertEquals(1, handlers.length);
assertTrue(handlers[0] instanceof TestHandler);
assertNotNull(handler);
}
// Test pristine Logger instance
public void testPristineLogger() {
assertNotNull("Logger exists", logger);
assertEquals("Logger name", this.getClass().getName(), logger.getName());
// Assert which logging levels have been enabled
assertTrue(logger.isLoggable(Level.SEVERE));
assertTrue(logger.isLoggable(Level.WARNING));
assertTrue(logger.isLoggable(Level.INFO));
assertTrue(logger.isLoggable(Level.CONFIG));
assertTrue(logger.isLoggable(Level.FINE));
assertFalse(logger.isLoggable(Level.FINER));
assertFalse(logger.isLoggable(Level.FINEST));
}
// Test Serializability of Log instance
@Override
public void testSerializable() throws Exception {
super.testSerializable();
testExceptionMessages();
}
// -------------------------------------------------------- Support Methods
// Check the log instance
@Override
protected void checkLog() {
assertNotNull("Log exists", log);
assertEquals("Log class",
"org.apache.commons.logging.impl.Jdk14Logger",
log.getClass().getName());
// Assert which logging levels have been enabled
assertTrue(log.isFatalEnabled());
assertTrue(log.isErrorEnabled());
assertTrue(log.isWarnEnabled());
assertTrue(log.isInfoEnabled());
assertTrue(log.isDebugEnabled());
assertFalse(log.isTraceEnabled());
}
// Check the recorded messages
protected void checkLogRecords(final boolean thrown) {
final Iterator records = handler.records();
for (int i = 0; i < testMessages.length; i++) {
assertTrue(records.hasNext());
final LogRecord record = (LogRecord) records.next();
assertEquals("LogRecord level",
testLevels[i], record.getLevel());
assertEquals("LogRecord message",
testMessages[i], record.getMessage());
assertTrue("LogRecord class",
record.getSourceClassName().startsWith(
"org.apache.commons.logging.jdk14.CustomConfig"));
if (thrown) {
assertEquals("LogRecord method",
"logExceptionMessages",
record.getSourceMethodName());
} else {
assertEquals("LogRecord method",
"logPlainMessages",
record.getSourceMethodName());
}
if (thrown) {
assertNotNull("LogRecord thrown", record.getThrown());
assertTrue("LogRecord thrown type",
record.getThrown() instanceof DummyException);
} else {
assertNull("LogRecord thrown",
record.getThrown());
}
}
assertFalse(records.hasNext());
handler.flush();
}
// Log the messages with exceptions
protected void logExceptionMessages() {
final Throwable t = new DummyException();
log.trace("trace", t); // Should not actually get logged
log.debug("debug", t);
log.info("info", t);
log.warn("warn", t);
log.error("error", t);
log.fatal("fatal", t);
}
// Log the plain messages
protected void logPlainMessages() {
log.trace("trace"); // Should not actually get logged
log.debug("debug");
log.info("info");
log.warn("warn");
log.error("error");
log.fatal("fatal");
}
// Set up handlers instance
protected void setUpHandlers() throws Exception {
Logger parent = logger;
while (parent.getParent() != null) {
parent = parent.getParent();
}
handlers = parent.getHandlers();
// The CustomConfig.properties file explicitly defines one handler class
// to be attached to the root logger, so if it isn't there then
// something is badly wrong...
//
// Yes this testing is also done in testPristineHandlers but
// unfortunately:
// * we need to set up the handlers variable here,
// * we don't want that to be set up incorrectly, as that can
// produce weird error messages in other tests, and
// * we can't rely on testPristineHandlers being the first
// test to run.
// so we need to test things here too.
assertNotNull("No Handlers defined for JDK14 logging", handlers);
assertEquals("Unexpected number of handlers for JDK14 logging", 1, handlers.length);
assertNotNull("Handler is null", handlers[0]);
assertTrue("Handler not of expected type", handlers[0] instanceof TestHandler);
handler = (TestHandler) handlers[0];
}
// Set up logger instance
protected void setUpLogger(final String name) throws Exception {
logger = Logger.getLogger(name);
}
// Set up LogManager instance
protected void setUpManager(final String config) throws Exception {
manager = LogManager.getLogManager();
final InputStream is =
this.getClass().getClassLoader().getResourceAsStream(config);
manager.readConfiguration(is);
is.close();
}
}
/*
* 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.commons.logging.jdk14;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.Iterator;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogManager;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
import junit.framework.Test;
import org.apache.commons.logging.DummyException;
import org.apache.commons.logging.PathableClassLoader;
import org.apache.commons.logging.PathableTestSuite;
/**
* <p>TestCase for JDK 1.4 logging when running on a JDK 1.4 system with
* custom configuration, so that JDK 1.4 should be selected and an appropriate
* logger configured per the configuration properties.</p>
*/
public class CustomConfigTestCase extends DefaultConfigTestCase {
protected static final String HANDLER_NAME = "org.apache.commons.logging.jdk14.TestHandler";
// ----------------------------------------------------------- Constructors
/**
* <p>Construct a new instance of this test case.</p>
*
* @param name Name of the test case
*/
public CustomConfigTestCase(final String name) {
super(name);
}
// ----------------------------------------------------- Instance Variables
/**
* <p>The customized {@code Handler} we will be using.</p>
*/
protected TestHandler handler;
/**
* <p>The underlying {@code Handler}s we will be using.</p>
*/
protected Handler handlers[];
/**
* <p>The underlying {@code Logger} we will be using.</p>
*/
protected Logger logger;
/**
* <p>The underlying {@code LogManager} we will be using.</p>
*/
protected LogManager manager;
/**
* <p>The message levels that should have been logged.</p>
*/
protected Level[] testLevels =
{ Level.FINE, Level.INFO, Level.WARNING, Level.SEVERE, Level.SEVERE };
/**
* <p>The message strings that should have been logged.</p>
*/
protected String[] testMessages =
{ "debug", "info", "warn", "error", "fatal" };
// ------------------------------------------- JUnit Infrastructure Methods
/**
* Given the name of a class that is somewhere in the classpath of the provided
* classloader, return the contents of the corresponding .class file.
*/
protected static byte[] readClass(final String name, final ClassLoader srcCL) throws Exception {
final String resName = name.replace('.', '/') + ".class";
System.err.println("Trying to load resource [" + resName + "]");
final InputStream is = srcCL.getResourceAsStream(resName);
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
System.err.println("Reading resource [" + resName + "]");
final byte[] buf = new byte[1000];
for(;;) {
final int read = is.read(buf);
if (read <= 0) {
break;
}
baos.write(buf, 0, read);
}
is.close();
return baos.toByteArray();
}
/**
* Make a class available in the system classloader even when its classfile is
* not present in the classpath configured for that classloader. This only
* works for classes for which all dependencies are already loaded in
* that classloader.
*/
protected static void loadTestHandler(final String className, final ClassLoader targetCL) {
try {
targetCL.loadClass(className);
// fail("Class already in target classloader");
return;
} catch (final ClassNotFoundException ex) {
// ok, go ahead and load it
}
try {
final ClassLoader srcCL = CustomConfigAPITestCase.class.getClassLoader();
final byte[] classData = readClass(className, srcCL);
final Class[] params = new Class[] { String.class, classData.getClass(), Integer.TYPE, Integer.TYPE };
final Method m = ClassLoader.class.getDeclaredMethod("defineClass", params);
final Object[] args = new Object[4];
args[0] = className;
args[1] = classData;
args[2] = new Integer(0);
args[3] = new Integer(classData.length);
m.setAccessible(true);
m.invoke(targetCL, args);
} catch (final Exception e) {
e.printStackTrace();
fail("Unable to load class " + className);
}
}
/**
* Set up instance variables required by this test case.
*/
@Override
public void setUp() throws Exception {
setUpManager
("org/apache/commons/logging/jdk14/CustomConfig.properties");
setUpLogger(this.getClass().getName());
setUpHandlers();
setUpFactory();
setUpLog(this.getClass().getName());
}
/**
* Return the tests included in this test suite.
*/
public static Test suite() throws Exception {
final PathableClassLoader cl = new PathableClassLoader(null);
cl.useExplicitLoader("junit.", Test.class.getClassLoader());
// the TestHandler class must be accessable from the System classloader
// in order for java.util.logging.LogManager.readConfiguration to
// be able to instantiate it. And this test case must see the same
// class in order to be able to access its data. Yes this is ugly
// but the whole jdk14 API is a ******* mess anyway.
final ClassLoader scl = ClassLoader.getSystemClassLoader();
loadTestHandler(HANDLER_NAME, scl);
cl.useExplicitLoader(HANDLER_NAME, scl);
cl.addLogicalLib("commons-logging");
cl.addLogicalLib("testclasses");
final Class testClass = cl.loadClass(CustomConfigTestCase.class.getName());
return new PathableTestSuite(testClass, cl);
}
/**
* Tear down instance variables required by this test case.
*/
@Override
public void tearDown() {
super.tearDown();
handlers = null;
logger = null;
manager = null;
}
// ----------------------------------------------------------- Test Methods
// Test logging message strings with exceptions
public void testExceptionMessages() throws Exception {
logExceptionMessages();
checkLogRecords(true);
}
// Test logging plain message strings
public void testPlainMessages() throws Exception {
logPlainMessages();
checkLogRecords(false);
}
// Test pristine Handlers instances
public void testPristineHandlers() {
assertNotNull(handlers);
assertEquals(1, handlers.length);
assertTrue(handlers[0] instanceof TestHandler);
assertNotNull(handler);
}
// Test pristine Logger instance
public void testPristineLogger() {
assertNotNull("Logger exists", logger);
assertEquals("Logger name", this.getClass().getName(), logger.getName());
// Assert which logging levels have been enabled
assertTrue(logger.isLoggable(Level.SEVERE));
assertTrue(logger.isLoggable(Level.WARNING));
assertTrue(logger.isLoggable(Level.INFO));
assertTrue(logger.isLoggable(Level.CONFIG));
assertTrue(logger.isLoggable(Level.FINE));
assertFalse(logger.isLoggable(Level.FINER));
assertFalse(logger.isLoggable(Level.FINEST));
}
// Test Serializability of Log instance
@Override
public void testSerializable() throws Exception {
super.testSerializable();
testExceptionMessages();
}
// -------------------------------------------------------- Support Methods
// Check the log instance
@Override
protected void checkLog() {
assertNotNull("Log exists", log);
assertEquals("Log class",
"org.apache.commons.logging.impl.Jdk14Logger",
log.getClass().getName());
// Assert which logging levels have been enabled
assertTrue(log.isFatalEnabled());
assertTrue(log.isErrorEnabled());
assertTrue(log.isWarnEnabled());
assertTrue(log.isInfoEnabled());
assertTrue(log.isDebugEnabled());
assertFalse(log.isTraceEnabled());
}
// Check the recorded messages
protected void checkLogRecords(final boolean thrown) {
final Iterator records = handler.records();
for (int i = 0; i < testMessages.length; i++) {
assertTrue(records.hasNext());
final LogRecord record = (LogRecord) records.next();
assertEquals("LogRecord level",
testLevels[i], record.getLevel());
assertEquals("LogRecord message",
testMessages[i], record.getMessage());
assertTrue("LogRecord class",
record.getSourceClassName().startsWith(
"org.apache.commons.logging.jdk14.CustomConfig"));
if (thrown) {
assertEquals("LogRecord method",
"logExceptionMessages",
record.getSourceMethodName());
} else {
assertEquals("LogRecord method",
"logPlainMessages",
record.getSourceMethodName());
}
if (thrown) {
assertNotNull("LogRecord thrown", record.getThrown());
assertTrue("LogRecord thrown type",
record.getThrown() instanceof DummyException);
} else {
assertNull("LogRecord thrown",
record.getThrown());
}
}
assertFalse(records.hasNext());
handler.flush();
}
// Log the messages with exceptions
protected void logExceptionMessages() {
final Throwable t = new DummyException();
log.trace("trace", t); // Should not actually get logged
log.debug("debug", t);
log.info("info", t);
log.warn("warn", t);
log.error("error", t);
log.fatal("fatal", t);
}
// Log the plain messages
protected void logPlainMessages() {
log.trace("trace"); // Should not actually get logged
log.debug("debug");
log.info("info");
log.warn("warn");
log.error("error");
log.fatal("fatal");
}
// Set up handlers instance
protected void setUpHandlers() throws Exception {
Logger parent = logger;
while (parent.getParent() != null) {
parent = parent.getParent();
}
handlers = parent.getHandlers();
// The CustomConfig.properties file explicitly defines one handler class
// to be attached to the root logger, so if it isn't there then
// something is badly wrong...
//
// Yes this testing is also done in testPristineHandlers but
// unfortunately:
// * we need to set up the handlers variable here,
// * we don't want that to be set up incorrectly, as that can
// produce weird error messages in other tests, and
// * we can't rely on testPristineHandlers being the first
// test to run.
// so we need to test things here too.
assertNotNull("No Handlers defined for JDK14 logging", handlers);
assertEquals("Unexpected number of handlers for JDK14 logging", 1, handlers.length);
assertNotNull("Handler is null", handlers[0]);
assertTrue("Handler not of expected type", handlers[0] instanceof TestHandler);
handler = (TestHandler) handlers[0];
}
// Set up logger instance
protected void setUpLogger(final String name) throws Exception {
logger = Logger.getLogger(name);
}
// Set up LogManager instance
protected void setUpManager(final String config) throws Exception {
manager = LogManager.getLogManager();
final InputStream is =
this.getClass().getClassLoader().getResourceAsStream(config);
manager.readConfiguration(is);
is.close();
}
}

View File

@@ -1,158 +1,158 @@
/*
* 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.commons.logging.jdk14;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import junit.framework.Test;
import junit.framework.TestCase;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.logging.PathableClassLoader;
import org.apache.commons.logging.PathableTestSuite;
/**
* <p>TestCase for JDK 1.4 logging when running on a JDK 1.4 system with
* zero configuration, and with Log4J not present (so JDK 1.4 logging
* should be automatically configured.</p>
*/
public class DefaultConfigTestCase extends TestCase {
/**
* <p>Construct a new instance of this test case.</p>
*
* @param name Name of the test case
*/
public DefaultConfigTestCase(final String name) {
super(name);
}
/**
* <p>The {@link LogFactory} implementation we have selected.</p>
*/
protected LogFactory factory;
/**
* <p>The {@link Log} implementation we have selected.</p>
*/
protected Log log;
/**
* Set up instance variables required by this test case.
*/
@Override
public void setUp() throws Exception {
setUpFactory();
setUpLog("TestLogger");
}
/**
* Return the tests included in this test suite.
*/
public static Test suite() throws Exception {
final PathableClassLoader loader = new PathableClassLoader(null);
loader.useExplicitLoader("junit.", Test.class.getClassLoader());
loader.addLogicalLib("testclasses");
loader.addLogicalLib("commons-logging");
final Class testClass = loader.loadClass(DefaultConfigTestCase.class.getName());
return new PathableTestSuite(testClass, loader);
}
/**
* Tear down instance variables required by this test case.
*/
@Override
public void tearDown() {
log = null;
factory = null;
LogFactory.releaseAll();
}
// Test pristine Log instance
public void testPristineLog() {
checkLog();
}
// Test pristine LogFactory instance
public void testPristineFactory() {
assertNotNull("LogFactory exists", factory);
assertEquals("LogFactory class",
"org.apache.commons.logging.impl.LogFactoryImpl",
factory.getClass().getName());
final String[] names = factory.getAttributeNames();
assertNotNull("Names exists", names);
assertEquals("Names empty", 0, names.length);
}
// Test Serializability of Log instance
public void testSerializable() throws Exception {
// Serialize and deserialize the instance
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
final ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(log);
oos.close();
final ByteArrayInputStream bais =
new ByteArrayInputStream(baos.toByteArray());
final ObjectInputStream ois = new ObjectInputStream(bais);
log = (Log) ois.readObject();
ois.close();
// Check the characteristics of the resulting object
checkLog();
}
// Check the log instance
protected void checkLog() {
assertNotNull("Log exists", log);
assertEquals("Log class",
"org.apache.commons.logging.impl.Jdk14Logger",
log.getClass().getName());
// Can we call level checkers with no exceptions?
log.isDebugEnabled();
log.isErrorEnabled();
log.isFatalEnabled();
log.isInfoEnabled();
log.isTraceEnabled();
log.isWarnEnabled();
}
// Set up factory instance
protected void setUpFactory() throws Exception {
factory = LogFactory.getFactory();
}
// Set up log instance
protected void setUpLog(final String name) throws Exception {
log = LogFactory.getLog(name);
}
}
/*
* 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.commons.logging.jdk14;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import junit.framework.Test;
import junit.framework.TestCase;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.logging.PathableClassLoader;
import org.apache.commons.logging.PathableTestSuite;
/**
* <p>TestCase for JDK 1.4 logging when running on a JDK 1.4 system with
* zero configuration, and with Log4J not present (so JDK 1.4 logging
* should be automatically configured.</p>
*/
public class DefaultConfigTestCase extends TestCase {
/**
* <p>Construct a new instance of this test case.</p>
*
* @param name Name of the test case
*/
public DefaultConfigTestCase(final String name) {
super(name);
}
/**
* <p>The {@link LogFactory} implementation we have selected.</p>
*/
protected LogFactory factory;
/**
* <p>The {@link Log} implementation we have selected.</p>
*/
protected Log log;
/**
* Set up instance variables required by this test case.
*/
@Override
public void setUp() throws Exception {
setUpFactory();
setUpLog("TestLogger");
}
/**
* Return the tests included in this test suite.
*/
public static Test suite() throws Exception {
final PathableClassLoader loader = new PathableClassLoader(null);
loader.useExplicitLoader("junit.", Test.class.getClassLoader());
loader.addLogicalLib("testclasses");
loader.addLogicalLib("commons-logging");
final Class testClass = loader.loadClass(DefaultConfigTestCase.class.getName());
return new PathableTestSuite(testClass, loader);
}
/**
* Tear down instance variables required by this test case.
*/
@Override
public void tearDown() {
log = null;
factory = null;
LogFactory.releaseAll();
}
// Test pristine Log instance
public void testPristineLog() {
checkLog();
}
// Test pristine LogFactory instance
public void testPristineFactory() {
assertNotNull("LogFactory exists", factory);
assertEquals("LogFactory class",
"org.apache.commons.logging.impl.LogFactoryImpl",
factory.getClass().getName());
final String[] names = factory.getAttributeNames();
assertNotNull("Names exists", names);
assertEquals("Names empty", 0, names.length);
}
// Test Serializability of Log instance
public void testSerializable() throws Exception {
// Serialize and deserialize the instance
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
final ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(log);
oos.close();
final ByteArrayInputStream bais =
new ByteArrayInputStream(baos.toByteArray());
final ObjectInputStream ois = new ObjectInputStream(bais);
log = (Log) ois.readObject();
ois.close();
// Check the characteristics of the resulting object
checkLog();
}
// Check the log instance
protected void checkLog() {
assertNotNull("Log exists", log);
assertEquals("Log class",
"org.apache.commons.logging.impl.Jdk14Logger",
log.getClass().getName());
// Can we call level checkers with no exceptions?
log.isDebugEnabled();
log.isErrorEnabled();
log.isFatalEnabled();
log.isInfoEnabled();
log.isTraceEnabled();
log.isWarnEnabled();
}
// Set up factory instance
protected void setUpFactory() throws Exception {
factory = LogFactory.getFactory();
}
// Set up log instance
protected void setUpLog(final String name) throws Exception {
log = LogFactory.getLog(name);
}
}

View File

@@ -1,53 +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.commons.logging.jdk14;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Handler;
import java.util.logging.LogRecord;
/**
* <p>Test implementation of {@code java.util.logging.Handler}.</p>
*/
public class TestHandler extends Handler {
// The set of logged records for this handler
private final List records = new ArrayList();
public Iterator records() {
return records.iterator();
}
@Override
public void close() {
}
@Override
public void flush() {
records.clear();
}
@Override
public void publish(final LogRecord record) {
records.add(record);
}
}
/*
* 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.commons.logging.jdk14;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Handler;
import java.util.logging.LogRecord;
/**
* <p>Test implementation of {@code java.util.logging.Handler}.</p>
*/
public class TestHandler extends Handler {
// The set of logged records for this handler
private final List records = new ArrayList();
public Iterator records() {
return records.iterator();
}
@Override
public void close() {
}
@Override
public void flush() {
records.clear();
}
@Override
public void publish(final LogRecord record) {
records.add(record);
}
}

View File

@@ -1,244 +1,244 @@
/*
* 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.commons.logging.simple;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import junit.framework.Test;
import org.apache.commons.logging.DummyException;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.logging.PathableClassLoader;
import org.apache.commons.logging.PathableTestSuite;
import org.apache.commons.logging.impl.SimpleLog;
/**
* <p>TestCase for simple logging when running with custom configuration
* properties.</p>
*/
public class CustomConfigTestCase extends DefaultConfigTestCase {
/**
* <p>The expected log records.</p>
*/
protected List expected;
/**
* <p>The message levels that should have been logged.</p>
*/
/*
protected Level[] testLevels =
{ Level.FINE, Level.INFO, Level.WARNING, Level.SEVERE, Level.SEVERE };
*/
/**
* <p>The message strings that should have been logged.</p>
*/
protected String[] testMessages =
{ "debug", "info", "warn", "error", "fatal" };
/**
* Set system properties that will control the LogFactory/Log objects
* when they are created. Subclasses can override this method to
* define properties that suit them.
*/
@Override
public void setProperties() {
System.setProperty(
"org.apache.commons.logging.Log",
"org.apache.commons.logging.simple.DecoratedSimpleLog");
System.setProperty(
"org.apache.commons.logging.simplelog.defaultlog",
"debug");
}
/**
* Set up instance variables required by this test case.
*/
@Override
public void setUp() throws Exception {
LogFactory.releaseAll();
setProperties();
expected = new ArrayList();
setUpFactory();
setUpLog("DecoratedLogger");
}
/**
* Return the tests included in this test suite.
* <p>
* We need to use a PathableClassLoader here because the SimpleLog class
* is a pile of junk and chock-full of static variables. Any other test
* (like simple.CustomConfigTestCase) that has used the SimpleLog class
* will already have caused it to do once-only initialization that we
* can't reset, even by calling LogFactory.releaseAll, because of those
* ugly statics. The only clean solution is to load a clean copy of
* commons-logging including SimpleLog via a nice clean class loader.
* Or we could fix SimpleLog to be sane...
*/
public static Test suite() throws Exception {
final Class thisClass = CustomConfigTestCase.class;
final PathableClassLoader loader = new PathableClassLoader(null);
loader.useExplicitLoader("junit.", Test.class.getClassLoader());
loader.addLogicalLib("testclasses");
loader.addLogicalLib("commons-logging");
final Class testClass = loader.loadClass(thisClass.getName());
return new PathableTestSuite(testClass, loader);
}
/**
* Tear down instance variables required by this test case.
*/
@Override
public void tearDown() {
super.tearDown();
expected = null;
}
// Test logging message strings with exceptions
public void testExceptionMessages() throws Exception {
((DecoratedSimpleLog) log).clearCache();
logExceptionMessages();
checkExpected();
}
// Test logging plain message strings
public void testPlainMessages() throws Exception {
((DecoratedSimpleLog) log).clearCache();
logPlainMessages();
checkExpected();
}
// Test Serializability of standard instance
@Override
public void testSerializable() throws Exception {
((DecoratedSimpleLog) log).clearCache();
logPlainMessages();
super.testSerializable();
logExceptionMessages();
checkExpected();
}
// Check the decorated log instance
@Override
protected void checkDecorated() {
assertNotNull("Log exists", log);
assertEquals("Log class",
"org.apache.commons.logging.simple.DecoratedSimpleLog",
log.getClass().getName());
// Can we call level checkers with no exceptions?
assertTrue(log.isDebugEnabled());
assertTrue(log.isErrorEnabled());
assertTrue(log.isFatalEnabled());
assertTrue(log.isInfoEnabled());
assertFalse(log.isTraceEnabled());
assertTrue(log.isWarnEnabled());
// Can we retrieve the current log level?
assertEquals(SimpleLog.LOG_LEVEL_DEBUG, ((SimpleLog) log).getLevel());
// Can we validate the extra exposed properties?
checkDecoratedDateTime();
assertEquals("DecoratedLogger",
((DecoratedSimpleLog) log).getLogName());
checkShowDateTime();
assertTrue(((DecoratedSimpleLog) log).getShowShortName());
}
/** Hook for subclassses */
protected void checkShowDateTime() {
assertFalse(((DecoratedSimpleLog) log).getShowDateTime());
}
/** Hook for subclasses */
protected void checkDecoratedDateTime() {
assertEquals("yyyy/MM/dd HH:mm:ss:SSS zzz",
((DecoratedSimpleLog) log).getDateTimeFormat());
}
// Check the actual log records against the expected ones
protected void checkExpected() {
final List acts = ((DecoratedSimpleLog) log).getCache();
final Iterator exps = expected.iterator();
int n = 0;
while (exps.hasNext()) {
final LogRecord exp = (LogRecord) exps.next();
final LogRecord act = (LogRecord) acts.get(n++);
assertEquals("Row " + n + " type", exp.type, act.type);
assertEquals("Row " + n + " message", exp.message, act.message);
assertEquals("Row " + n + " throwable", exp.t, act.t);
}
}
// Check the standard log instance
@Override
protected void checkStandard() {
checkDecorated();
}
// Log the messages with exceptions
protected void logExceptionMessages() {
// Generate log records
final Throwable t = new DummyException();
log.trace("trace", t); // Should not actually get logged
log.debug("debug", t);
log.info("info", t);
log.warn("warn", t);
log.error("error", t);
log.fatal("fatal", t);
// Record the log records we expect
expected.add(new LogRecord(SimpleLog.LOG_LEVEL_DEBUG, "debug", t));
expected.add(new LogRecord(SimpleLog.LOG_LEVEL_INFO, "info", t));
expected.add(new LogRecord(SimpleLog.LOG_LEVEL_WARN, "warn", t));
expected.add(new LogRecord(SimpleLog.LOG_LEVEL_ERROR, "error", t));
expected.add(new LogRecord(SimpleLog.LOG_LEVEL_FATAL, "fatal", t));
}
// Log the plain messages
protected void logPlainMessages() {
// Generate log records
log.trace("trace"); // Should not actually get logged
log.debug("debug");
log.info("info");
log.warn("warn");
log.error("error");
log.fatal("fatal");
// Record the log records we expect
expected.add(new LogRecord(SimpleLog.LOG_LEVEL_DEBUG, "debug", null));
expected.add(new LogRecord(SimpleLog.LOG_LEVEL_INFO, "info", null));
expected.add(new LogRecord(SimpleLog.LOG_LEVEL_WARN, "warn", null));
expected.add(new LogRecord(SimpleLog.LOG_LEVEL_ERROR, "error", null));
expected.add(new LogRecord(SimpleLog.LOG_LEVEL_FATAL, "fatal", null));
}
}
/*
* 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.commons.logging.simple;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import junit.framework.Test;
import org.apache.commons.logging.DummyException;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.logging.PathableClassLoader;
import org.apache.commons.logging.PathableTestSuite;
import org.apache.commons.logging.impl.SimpleLog;
/**
* <p>TestCase for simple logging when running with custom configuration
* properties.</p>
*/
public class CustomConfigTestCase extends DefaultConfigTestCase {
/**
* <p>The expected log records.</p>
*/
protected List expected;
/**
* <p>The message levels that should have been logged.</p>
*/
/*
protected Level[] testLevels =
{ Level.FINE, Level.INFO, Level.WARNING, Level.SEVERE, Level.SEVERE };
*/
/**
* <p>The message strings that should have been logged.</p>
*/
protected String[] testMessages =
{ "debug", "info", "warn", "error", "fatal" };
/**
* Set system properties that will control the LogFactory/Log objects
* when they are created. Subclasses can override this method to
* define properties that suit them.
*/
@Override
public void setProperties() {
System.setProperty(
"org.apache.commons.logging.Log",
"org.apache.commons.logging.simple.DecoratedSimpleLog");
System.setProperty(
"org.apache.commons.logging.simplelog.defaultlog",
"debug");
}
/**
* Set up instance variables required by this test case.
*/
@Override
public void setUp() throws Exception {
LogFactory.releaseAll();
setProperties();
expected = new ArrayList();
setUpFactory();
setUpLog("DecoratedLogger");
}
/**
* Return the tests included in this test suite.
* <p>
* We need to use a PathableClassLoader here because the SimpleLog class
* is a pile of junk and chock-full of static variables. Any other test
* (like simple.CustomConfigTestCase) that has used the SimpleLog class
* will already have caused it to do once-only initialization that we
* can't reset, even by calling LogFactory.releaseAll, because of those
* ugly statics. The only clean solution is to load a clean copy of
* commons-logging including SimpleLog via a nice clean class loader.
* Or we could fix SimpleLog to be sane...
*/
public static Test suite() throws Exception {
final Class thisClass = CustomConfigTestCase.class;
final PathableClassLoader loader = new PathableClassLoader(null);
loader.useExplicitLoader("junit.", Test.class.getClassLoader());
loader.addLogicalLib("testclasses");
loader.addLogicalLib("commons-logging");
final Class testClass = loader.loadClass(thisClass.getName());
return new PathableTestSuite(testClass, loader);
}
/**
* Tear down instance variables required by this test case.
*/
@Override
public void tearDown() {
super.tearDown();
expected = null;
}
// Test logging message strings with exceptions
public void testExceptionMessages() throws Exception {
((DecoratedSimpleLog) log).clearCache();
logExceptionMessages();
checkExpected();
}
// Test logging plain message strings
public void testPlainMessages() throws Exception {
((DecoratedSimpleLog) log).clearCache();
logPlainMessages();
checkExpected();
}
// Test Serializability of standard instance
@Override
public void testSerializable() throws Exception {
((DecoratedSimpleLog) log).clearCache();
logPlainMessages();
super.testSerializable();
logExceptionMessages();
checkExpected();
}
// Check the decorated log instance
@Override
protected void checkDecorated() {
assertNotNull("Log exists", log);
assertEquals("Log class",
"org.apache.commons.logging.simple.DecoratedSimpleLog",
log.getClass().getName());
// Can we call level checkers with no exceptions?
assertTrue(log.isDebugEnabled());
assertTrue(log.isErrorEnabled());
assertTrue(log.isFatalEnabled());
assertTrue(log.isInfoEnabled());
assertFalse(log.isTraceEnabled());
assertTrue(log.isWarnEnabled());
// Can we retrieve the current log level?
assertEquals(SimpleLog.LOG_LEVEL_DEBUG, ((SimpleLog) log).getLevel());
// Can we validate the extra exposed properties?
checkDecoratedDateTime();
assertEquals("DecoratedLogger",
((DecoratedSimpleLog) log).getLogName());
checkShowDateTime();
assertTrue(((DecoratedSimpleLog) log).getShowShortName());
}
/** Hook for subclassses */
protected void checkShowDateTime() {
assertFalse(((DecoratedSimpleLog) log).getShowDateTime());
}
/** Hook for subclasses */
protected void checkDecoratedDateTime() {
assertEquals("yyyy/MM/dd HH:mm:ss:SSS zzz",
((DecoratedSimpleLog) log).getDateTimeFormat());
}
// Check the actual log records against the expected ones
protected void checkExpected() {
final List acts = ((DecoratedSimpleLog) log).getCache();
final Iterator exps = expected.iterator();
int n = 0;
while (exps.hasNext()) {
final LogRecord exp = (LogRecord) exps.next();
final LogRecord act = (LogRecord) acts.get(n++);
assertEquals("Row " + n + " type", exp.type, act.type);
assertEquals("Row " + n + " message", exp.message, act.message);
assertEquals("Row " + n + " throwable", exp.t, act.t);
}
}
// Check the standard log instance
@Override
protected void checkStandard() {
checkDecorated();
}
// Log the messages with exceptions
protected void logExceptionMessages() {
// Generate log records
final Throwable t = new DummyException();
log.trace("trace", t); // Should not actually get logged
log.debug("debug", t);
log.info("info", t);
log.warn("warn", t);
log.error("error", t);
log.fatal("fatal", t);
// Record the log records we expect
expected.add(new LogRecord(SimpleLog.LOG_LEVEL_DEBUG, "debug", t));
expected.add(new LogRecord(SimpleLog.LOG_LEVEL_INFO, "info", t));
expected.add(new LogRecord(SimpleLog.LOG_LEVEL_WARN, "warn", t));
expected.add(new LogRecord(SimpleLog.LOG_LEVEL_ERROR, "error", t));
expected.add(new LogRecord(SimpleLog.LOG_LEVEL_FATAL, "fatal", t));
}
// Log the plain messages
protected void logPlainMessages() {
// Generate log records
log.trace("trace"); // Should not actually get logged
log.debug("debug");
log.info("info");
log.warn("warn");
log.error("error");
log.fatal("fatal");
// Record the log records we expect
expected.add(new LogRecord(SimpleLog.LOG_LEVEL_DEBUG, "debug", null));
expected.add(new LogRecord(SimpleLog.LOG_LEVEL_INFO, "info", null));
expected.add(new LogRecord(SimpleLog.LOG_LEVEL_WARN, "warn", null));
expected.add(new LogRecord(SimpleLog.LOG_LEVEL_ERROR, "error", null));
expected.add(new LogRecord(SimpleLog.LOG_LEVEL_FATAL, "fatal", null));
}
}

View File

@@ -1,109 +1,109 @@
/*
* 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.commons.logging.simple;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import junit.framework.Test;
import org.apache.commons.logging.PathableClassLoader;
import org.apache.commons.logging.PathableTestSuite;
/**
* Tests custom date time format configuration
*/
public class DateTimeCustomConfigTestCase extends CustomConfigTestCase {
// ----------------------------------------------------------- Constructors
/**
* Return the tests included in this test suite.
* <p>
* We need to use a PathableClassLoader here because the SimpleLog class
* is a pile of junk and chock-full of static variables. Any other test
* (like simple.CustomConfigTestCase) that has used the SimpleLog class
* will already have caused it to do once-only initialization that we
* can't reset, even by calling LogFactory.releaseAll, because of those
* ugly statics. The only clean solution is to load a clean copy of
* commons-logging including SimpleLog via a nice clean class loader.
* Or we could fix SimpleLog to be sane...
*/
public static Test suite() throws Exception {
final Class thisClass = DateTimeCustomConfigTestCase.class;
final PathableClassLoader loader = new PathableClassLoader(null);
loader.useExplicitLoader("junit.", Test.class.getClassLoader());
loader.addLogicalLib("testclasses");
loader.addLogicalLib("commons-logging");
final Class testClass = loader.loadClass(thisClass.getName());
return new PathableTestSuite(testClass, loader);
}
/**
* Set up system properties required by this unit test. Here, we
* set up the props defined in the parent class setProperties method,
* and add a few to configure the SimpleLog class date/time output.
*/
@Override
public void setProperties() {
super.setProperties();
System.setProperty(
"org.apache.commons.logging.simplelog.dateTimeFormat",
"dd.mm.yyyy");
System.setProperty(
"org.apache.commons.logging.simplelog.showdatetime",
"true");
}
/**
* Set up instance variables required by this test case.
*/
@Override
public void setUp() throws Exception {
super.setUp();
}
// ----------------------------------------------------------- Methods
/** Checks that the date time format has been successfully set */
@Override
protected void checkDecoratedDateTime() {
assertEquals("Expected date format to be set", "dd.mm.yyyy",
((DecoratedSimpleLog) log).getDateTimeFormat());
// try the formatter
final Date now = new Date();
final DateFormat formatter = ((DecoratedSimpleLog) log).getDateTimeFormatter();
final SimpleDateFormat sampleFormatter = new SimpleDateFormat("dd.mm.yyyy");
assertEquals("Date should be formatters to pattern dd.mm.yyyy",
sampleFormatter.format(now), formatter.format(now));
}
/** Hook for subclassses */
@Override
protected void checkShowDateTime() {
assertTrue(((DecoratedSimpleLog) log).getShowDateTime());
}
}
/*
* 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.commons.logging.simple;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import junit.framework.Test;
import org.apache.commons.logging.PathableClassLoader;
import org.apache.commons.logging.PathableTestSuite;
/**
* Tests custom date time format configuration
*/
public class DateTimeCustomConfigTestCase extends CustomConfigTestCase {
// ----------------------------------------------------------- Constructors
/**
* Return the tests included in this test suite.
* <p>
* We need to use a PathableClassLoader here because the SimpleLog class
* is a pile of junk and chock-full of static variables. Any other test
* (like simple.CustomConfigTestCase) that has used the SimpleLog class
* will already have caused it to do once-only initialization that we
* can't reset, even by calling LogFactory.releaseAll, because of those
* ugly statics. The only clean solution is to load a clean copy of
* commons-logging including SimpleLog via a nice clean class loader.
* Or we could fix SimpleLog to be sane...
*/
public static Test suite() throws Exception {
final Class thisClass = DateTimeCustomConfigTestCase.class;
final PathableClassLoader loader = new PathableClassLoader(null);
loader.useExplicitLoader("junit.", Test.class.getClassLoader());
loader.addLogicalLib("testclasses");
loader.addLogicalLib("commons-logging");
final Class testClass = loader.loadClass(thisClass.getName());
return new PathableTestSuite(testClass, loader);
}
/**
* Set up system properties required by this unit test. Here, we
* set up the props defined in the parent class setProperties method,
* and add a few to configure the SimpleLog class date/time output.
*/
@Override
public void setProperties() {
super.setProperties();
System.setProperty(
"org.apache.commons.logging.simplelog.dateTimeFormat",
"dd.mm.yyyy");
System.setProperty(
"org.apache.commons.logging.simplelog.showdatetime",
"true");
}
/**
* Set up instance variables required by this test case.
*/
@Override
public void setUp() throws Exception {
super.setUp();
}
// ----------------------------------------------------------- Methods
/** Checks that the date time format has been successfully set */
@Override
protected void checkDecoratedDateTime() {
assertEquals("Expected date format to be set", "dd.mm.yyyy",
((DecoratedSimpleLog) log).getDateTimeFormat());
// try the formatter
final Date now = new Date();
final DateFormat formatter = ((DecoratedSimpleLog) log).getDateTimeFormatter();
final SimpleDateFormat sampleFormatter = new SimpleDateFormat("dd.mm.yyyy");
assertEquals("Date should be formatters to pattern dd.mm.yyyy",
sampleFormatter.format(now), formatter.format(now));
}
/** Hook for subclassses */
@Override
protected void checkShowDateTime() {
assertTrue(((DecoratedSimpleLog) log).getShowDateTime());
}
}

View File

@@ -1,216 +1,216 @@
/*
* 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.commons.logging.simple;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import junit.framework.Test;
import junit.framework.TestCase;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.logging.PathableClassLoader;
import org.apache.commons.logging.PathableTestSuite;
import org.apache.commons.logging.impl.SimpleLog;
/**
* <p>TestCase for simple logging when running with zero configuration
* other than selecting the SimpleLog implementation.</p>
*/
public class DefaultConfigTestCase extends TestCase {
/**
* <p>The {@link LogFactory} implementation we have selected.</p>
*/
protected LogFactory factory;
/**
* <p>The {@link Log} implementation we have selected.</p>
*/
protected Log log;
/**
* Return the tests included in this test suite.
* <p>
* We need to use a PathableClassLoader here because the SimpleLog class
* is a pile of junk and chock-full of static variables. Any other test
* (like simple.CustomConfigTestCase) that has used the SimpleLog class
* will already have caused it to do once-only initialization that we
* can't reset, even by calling LogFactory.releaseAll, because of those
* ugly statics. The only clean solution is to load a clean copy of
* commons-logging including SimpleLog via a nice clean class loader.
* Or we could fix SimpleLog to be sane...
*/
public static Test suite() throws Exception {
final Class thisClass = DefaultConfigTestCase.class;
final PathableClassLoader loader = new PathableClassLoader(null);
loader.useExplicitLoader("junit.", Test.class.getClassLoader());
loader.addLogicalLib("testclasses");
loader.addLogicalLib("commons-logging");
final Class testClass = loader.loadClass(thisClass.getName());
return new PathableTestSuite(testClass, loader);
}
/**
* Set system properties that will control the LogFactory/Log objects
* when they are created. Subclasses can override this method to
* define properties that suit them.
*/
public void setProperties() {
System.setProperty(
"org.apache.commons.logging.Log",
"org.apache.commons.logging.impl.SimpleLog");
}
/**
* Set up instance variables required by this test case.
*/
@Override
public void setUp() throws Exception {
LogFactory.releaseAll();
setProperties();
setUpFactory();
setUpLog("TestLogger");
}
/**
* Tear down instance variables required by this test case.
*/
@Override
public void tearDown() {
log = null;
factory = null;
LogFactory.releaseAll();
}
// Test pristine DecoratedSimpleLog instance
public void testPristineDecorated() {
setUpDecorated("DecoratedLogger");
checkDecorated();
}
// Test pristine Log instance
public void testPristineLog() {
checkStandard();
}
// Test pristine LogFactory instance
public void testPristineFactory() {
assertNotNull("LogFactory exists", factory);
assertEquals("LogFactory class",
"org.apache.commons.logging.impl.LogFactoryImpl",
factory.getClass().getName());
final String[] names = factory.getAttributeNames();
assertNotNull("Names exists", names);
assertEquals("Names empty", 0, names.length);
}
// Test Serializability of standard instance
public void testSerializable() throws Exception {
// Serialize and deserialize the instance
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
final ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(log);
oos.close();
final ByteArrayInputStream bais =
new ByteArrayInputStream(baos.toByteArray());
final ObjectInputStream ois = new ObjectInputStream(bais);
log = (Log) ois.readObject();
ois.close();
// Check the characteristics of the resulting object
checkStandard();
}
// Check the decorated log instance
protected void checkDecorated() {
assertNotNull("Log exists", log);
assertEquals("Log class",
"org.apache.commons.logging.simple.DecoratedSimpleLog",
log.getClass().getName());
// Can we call level checkers with no exceptions?
assertFalse(log.isDebugEnabled());
assertTrue(log.isErrorEnabled());
assertTrue(log.isFatalEnabled());
assertTrue(log.isInfoEnabled());
assertFalse(log.isTraceEnabled());
assertTrue(log.isWarnEnabled());
// Can we retrieve the current log level?
assertEquals(SimpleLog.LOG_LEVEL_INFO, ((SimpleLog) log).getLevel());
// Can we validate the extra exposed properties?
assertEquals("yyyy/MM/dd HH:mm:ss:SSS zzz",
((DecoratedSimpleLog) log).getDateTimeFormat());
assertEquals("DecoratedLogger",
((DecoratedSimpleLog) log).getLogName());
assertFalse(((DecoratedSimpleLog) log).getShowDateTime());
assertTrue(((DecoratedSimpleLog) log).getShowShortName());
}
// Check the standard log instance
protected void checkStandard() {
assertNotNull("Log exists", log);
assertEquals("Log class",
"org.apache.commons.logging.impl.SimpleLog",
log.getClass().getName());
// Can we call level checkers with no exceptions?
assertFalse(log.isDebugEnabled());
assertTrue(log.isErrorEnabled());
assertTrue(log.isFatalEnabled());
assertTrue(log.isInfoEnabled());
assertFalse(log.isTraceEnabled());
assertTrue(log.isWarnEnabled());
// Can we retrieve the current log level?
assertEquals(SimpleLog.LOG_LEVEL_INFO, ((SimpleLog) log).getLevel());
}
// Set up decorated log instance
protected void setUpDecorated(final String name) {
log = new DecoratedSimpleLog(name);
}
// Set up factory instance
protected void setUpFactory() throws Exception {
factory = LogFactory.getFactory();
}
// Set up log instance
protected void setUpLog(final String name) throws Exception {
log = LogFactory.getLog(name);
}
}
/*
* 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.commons.logging.simple;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import junit.framework.Test;
import junit.framework.TestCase;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.logging.PathableClassLoader;
import org.apache.commons.logging.PathableTestSuite;
import org.apache.commons.logging.impl.SimpleLog;
/**
* <p>TestCase for simple logging when running with zero configuration
* other than selecting the SimpleLog implementation.</p>
*/
public class DefaultConfigTestCase extends TestCase {
/**
* <p>The {@link LogFactory} implementation we have selected.</p>
*/
protected LogFactory factory;
/**
* <p>The {@link Log} implementation we have selected.</p>
*/
protected Log log;
/**
* Return the tests included in this test suite.
* <p>
* We need to use a PathableClassLoader here because the SimpleLog class
* is a pile of junk and chock-full of static variables. Any other test
* (like simple.CustomConfigTestCase) that has used the SimpleLog class
* will already have caused it to do once-only initialization that we
* can't reset, even by calling LogFactory.releaseAll, because of those
* ugly statics. The only clean solution is to load a clean copy of
* commons-logging including SimpleLog via a nice clean class loader.
* Or we could fix SimpleLog to be sane...
*/
public static Test suite() throws Exception {
final Class thisClass = DefaultConfigTestCase.class;
final PathableClassLoader loader = new PathableClassLoader(null);
loader.useExplicitLoader("junit.", Test.class.getClassLoader());
loader.addLogicalLib("testclasses");
loader.addLogicalLib("commons-logging");
final Class testClass = loader.loadClass(thisClass.getName());
return new PathableTestSuite(testClass, loader);
}
/**
* Set system properties that will control the LogFactory/Log objects
* when they are created. Subclasses can override this method to
* define properties that suit them.
*/
public void setProperties() {
System.setProperty(
"org.apache.commons.logging.Log",
"org.apache.commons.logging.impl.SimpleLog");
}
/**
* Set up instance variables required by this test case.
*/
@Override
public void setUp() throws Exception {
LogFactory.releaseAll();
setProperties();
setUpFactory();
setUpLog("TestLogger");
}
/**
* Tear down instance variables required by this test case.
*/
@Override
public void tearDown() {
log = null;
factory = null;
LogFactory.releaseAll();
}
// Test pristine DecoratedSimpleLog instance
public void testPristineDecorated() {
setUpDecorated("DecoratedLogger");
checkDecorated();
}
// Test pristine Log instance
public void testPristineLog() {
checkStandard();
}
// Test pristine LogFactory instance
public void testPristineFactory() {
assertNotNull("LogFactory exists", factory);
assertEquals("LogFactory class",
"org.apache.commons.logging.impl.LogFactoryImpl",
factory.getClass().getName());
final String[] names = factory.getAttributeNames();
assertNotNull("Names exists", names);
assertEquals("Names empty", 0, names.length);
}
// Test Serializability of standard instance
public void testSerializable() throws Exception {
// Serialize and deserialize the instance
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
final ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(log);
oos.close();
final ByteArrayInputStream bais =
new ByteArrayInputStream(baos.toByteArray());
final ObjectInputStream ois = new ObjectInputStream(bais);
log = (Log) ois.readObject();
ois.close();
// Check the characteristics of the resulting object
checkStandard();
}
// Check the decorated log instance
protected void checkDecorated() {
assertNotNull("Log exists", log);
assertEquals("Log class",
"org.apache.commons.logging.simple.DecoratedSimpleLog",
log.getClass().getName());
// Can we call level checkers with no exceptions?
assertFalse(log.isDebugEnabled());
assertTrue(log.isErrorEnabled());
assertTrue(log.isFatalEnabled());
assertTrue(log.isInfoEnabled());
assertFalse(log.isTraceEnabled());
assertTrue(log.isWarnEnabled());
// Can we retrieve the current log level?
assertEquals(SimpleLog.LOG_LEVEL_INFO, ((SimpleLog) log).getLevel());
// Can we validate the extra exposed properties?
assertEquals("yyyy/MM/dd HH:mm:ss:SSS zzz",
((DecoratedSimpleLog) log).getDateTimeFormat());
assertEquals("DecoratedLogger",
((DecoratedSimpleLog) log).getLogName());
assertFalse(((DecoratedSimpleLog) log).getShowDateTime());
assertTrue(((DecoratedSimpleLog) log).getShowShortName());
}
// Check the standard log instance
protected void checkStandard() {
assertNotNull("Log exists", log);
assertEquals("Log class",
"org.apache.commons.logging.impl.SimpleLog",
log.getClass().getName());
// Can we call level checkers with no exceptions?
assertFalse(log.isDebugEnabled());
assertTrue(log.isErrorEnabled());
assertTrue(log.isFatalEnabled());
assertTrue(log.isInfoEnabled());
assertFalse(log.isTraceEnabled());
assertTrue(log.isWarnEnabled());
// Can we retrieve the current log level?
assertEquals(SimpleLog.LOG_LEVEL_INFO, ((SimpleLog) log).getLevel());
}
// Set up decorated log instance
protected void setUpDecorated(final String name) {
log = new DecoratedSimpleLog(name);
}
// Set up factory instance
protected void setUpFactory() throws Exception {
factory = LogFactory.getFactory();
}
// Set up log instance
protected void setUpLog(final String name) throws Exception {
log = LogFactory.getLog(name);
}
}