commons-logging-1.1.3-src/build.properties.sample100664 4261 12145235706 20102 0ustartntn 0 0 # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. ###################################################################### # # TO USE: # # Copy this file to build.properties and either # # a) Use 'ant getlibs' to populate the default directory # with dependencies # or b) Change the property values to appropriate values # ######################################################################## # Apache Log4j 1.2.x series log4j12.jar=lib/log4j-1.2.12.jar # Apache Log4j 1.3.x series # Note: Log4j 1.3 support not available in the 1.1 release #log4j13.jar=lib/log4j-1.3.0.jar # logkit.jar - Avalon LogKit classes (see http://jakarta.apache.org/avalon) logkit.jar=lib/logkit-1.0.1.jar # Avalon framework - used for wrapper for avalon framework logger avalon-framework.jar=lib/avalon-framework-4.1.3.jar # ServletApi - used to build ServletContextCleaner class servletapi.jar=lib/servletapi-2.3.jar # # if you want to run the test cases, junit needs to be in the classpath. # the build.xml uses a default value so you might not need to set this property. # Note that version junit 3.8 is required and 3.8.1 recommended. # junit.jar=lib/junit-3.8.1.jar # Maven properties (for web site build) # Those committers using agents may like to use #maven.username=rdonkin #logging.cvs=lserver:rdonkin@cvs.apache.org:/home/cvs # The path to a 1.4 JSDK javac # Optional - used when building with a 1.2 JVM for releases # executable.javac1.4=/opt/java/jdks/j2sdk1.4.2_10/bin/javac commons-logging-1.1.3-src/PROPOSAL.html100664 7274 12145235706 15541 0ustartntn 0 0 Proposal for Logging Library Package

Proposal for Logging Package

(0) Rationale

There is a great need for debugging and logging information inside of Commons components such as HTTPClient and dbcp. However, there are many logging APIs out there and it is difficult to choose among them.

The Logging package will be an ultra-thin bridge between different logging libraries. Commons components may use the Logging JAR to remove compile-time/runtime dependencies on any particular logging package, and contributors may write Log implementations for the library of their choice.

(1) Scope of the Package

The package shall create and maintain a package that provides extremely basic logging functionality and bridges to other, more sophisticated logging implementations.

The package should :

Non-goals:

(1.5) Interaction With Other Packages

Logging relies on:

(2) Required Jakarta-Commons Resources

(4) Initial Committers

The initial committers on the Logging component shall be:

commons-logging-1.1.3-src/pom.xml100664 43661 12145235706 14751 0ustartntn 0 0 org.apache.commons commons-parent 28 4.0.0 commons-logging commons-logging Commons Logging 1.1.3 Commons Logging is a thin adapter allowing configurable bridging to other, well known logging systems. http://commons.apache.org/proper/commons-logging/ JIRA http://issues.apache.org/jira/browse/LOGGING 2001 baliuka Juozas Baliuka baliuka@apache.org Java Developer morgand Morgan Delagrange morgand@apache.org Apache Java Developer donaldp Peter Donald donaldp@apache.org rdonkin Robert Burrell Donkin rdonkin@apache.org The Apache Software Foundation skitching Simon Kitching skitching@apache.org The Apache Software Foundation dennisl Dennis Lundberg dennisl@apache.org The Apache Software Foundation costin Costin Manolache costin@apache.org The Apache Software Foundation craigmcc Craig McClanahan craigmcc@apache.org The Apache Software Foundation tn Thomas Neidhart tn@apache.org The Apache Software Foundation sanders Scott Sanders sanders@apache.org The Apache Software Foundation rsitze Richard Sitze rsitze@apache.org The Apache Software Foundation bstansberry Brian Stansberry rwaldhoff Rodney Waldhoff rwaldhoff@apache.org The Apache Software Foundation Matthew P. Del Buono Provided patch Vince Eagen vince256 at comcast dot net Lumberjack logging abstraction Peter Lawrey Provided patch Berin Loritsch bloritsch at apache dot org Lumberjack logging abstraction JDK 1.4 logging abstraction Philippe Mouawad Provided patch Neeme Praks neeme at apache dot org Avalon logging abstraction scm:svn:http://svn.apache.org/repos/asf/commons/proper/logging/trunk scm:svn:https://svn.apache.org/repos/asf/commons/proper/logging/trunk http://svn.apache.org/repos/asf/commons/proper/logging/trunk org.apache.maven.plugins maven-jar-plugin testjar package test-jar commons-logging apijar package jar ${project.artifactId}-api-${project.version} org/apache/commons/logging/*.class org/apache/commons/logging/impl/LogFactoryImpl*.class org/apache/commons/logging/impl/WeakHashtable*.class org/apache/commons/logging/impl/SimpleLog*.class org/apache/commons/logging/impl/NoOpLog*.class org/apache/commons/logging/impl/Jdk14Logger.class META-INF/LICENSE.txt META-INF/NOTICE.txt **/package.html adaptersjar package jar ${project.artifactId}-adapters-${project.version} org/apache/commons/logging/impl/**.class META-INF/LICENSE.txt META-INF/NOTICE.txt org/apache/commons/logging/impl/WeakHashtable*.class org/apache/commons/logging/impl/LogFactoryImpl*.class fulljar package jar ${project.artifactId}-${project.version} org.apache.maven.plugins maven-antrun-plugin site.resources site run org.codehaus.mojo build-helper-maven-plugin 1.0 attach-artifacts package attach-artifact ${project.build.directory}/${project.artifactId}-adapters-${project.version}.jar jar adapters ${project.build.directory}/${project.artifactId}-api-${project.version}.jar jar api org.apache.maven.plugins maven-surefire-plugin true org.codehaus.mojo cobertura-maven-plugin ${commons.cobertura.version} true org.apache.maven.plugins maven-failsafe-plugin ${commons.surefire.version} integration-test integration-test verify **/*TestCase.java ${log4j:log4j:jar} ${logkit:logkit:jar} ${javax.servlet:servlet-api:jar} target/${project.build.finalName}.jar target/${project.artifactId}-api-${project.version}.jar target/${project.artifactId}-adapters-${project.version}.jar target/commons-logging-tests.jar org.apache.maven.plugins maven-assembly-plugin 2.3 src/main/assembly/bin.xml src/main/assembly/src.xml gnu org.apache.maven.plugins maven-dependency-plugin 2.4 properties org.apache.maven.plugins maven-scm-publish-plugin javadocs commons-logging-** junit junit 3.8.1 test log4j log4j 1.2.17 true logkit logkit 1.0.1 true avalon-framework avalon-framework 4.1.5 true javax.servlet servlet-api 2.3 provided true org.apache.maven.plugins maven-checkstyle-plugin 2.7 ${basedir}/checkstyle.xml false ${basedir}/license-header.txt org.codehaus.mojo clirr-maven-plugin 2.2.2 org.codehaus.mojo jdepend-maven-plugin 2.0-beta-1 apache.website ${commons.deployment.protocol}://people.apache.org/www/commons.apache.org/logging/ 1.2 1.1 logging 1.1.3 LOGGING 12310484 RC2 2.12 true javax.servlet;version="[2.1.0, 3.0.0)";resolution:=optional, org.apache.avalon.framework.logger;version="[4.1.3, 4.1.5]";resolution:=optional, org.apache.log;version="[1.0.1, 1.0.1]";resolution:=optional, org.apache.log4j;version="[1.2.15, 2.0.0)";resolution:=optional commons-logging-1.1.3-src/build.xml100664 72160 12145235706 15251 0ustartntn 0 0 Log4j12: ${log4j12.jar} LogKit: ${logkit.jar} Avalon-Framework: ${avalon-framework.jar} *** WARNING *** Log4j 1.2 not found: Cannot Build Log4JLogger *** WARNING *** LogKit not found: Cannot Build LogKitLogger *** WARNING *** Avalon-Framework not found: Cannot Build AvalonLogger *** WARNING *** JDK 1.4 not present: Cannot Build Jdk14Logger *** WARNING *** Log4J 1.2.x Jar not found: Cannot execute 1.2.x tests *** WARNING *** Maven generated documentation not found: Documentation distribution will be empty One or more unit tests failed. commons-logging-1.1.3-src/build-testing.xml100664 33377 12145235706 16733 0ustartntn 0 0 Log4j12: ${log4j12.jar} LogKit: ${logkit.jar} Avalon-Framework: ${avalon-framework.jar} *** WARNING *** Log4J 1.2.x Jar not found: Cannot execute 1.2.x tests One or more unit tests failed. commons-logging-1.1.3-src/NOTICE.txt100664 261 12145235706 15103 0ustartntn 0 0 Apache Commons Logging Copyright 2003-2013 The Apache Software Foundation This product includes software developed at The Apache Software Foundation (http://www.apache.org/). commons-logging-1.1.3-src/license-header.txt100664 1443 12145235706 17015 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ commons-logging-1.1.3-src/checkstyle.xml100664 5074 12145235706 16270 0ustartntn 0 0 commons-logging-1.1.3-src/RELEASE-NOTES.txt100664 1474 12145235706 16117 0ustartntn 0 0 Apache Commons Logging Version 1.1.3 RELEASE NOTES The Commons Logging team is pleased to announce the release of Apache Commons Logging 1.1.3 Commons Logging is a thin adapter allowing configurable bridging to other, well known logging systems. This is a maintenance release containing bug fixes. Changes in this version include: Fixed Bugs: o LOGGING-151: Use "org.apache.commons.logging" as bundle symbolic name. Thanks to Krzysztof Daniel. Historical list of changes: http://commons.apache.org/proper/commons-logging/changes-report.html For complete information on Commons Logging, including instructions on how to submit bug reports, patches, or suggestions for improvement, see the Apache Commons Logging website: http://commons.apache.org/proper/commons-logging/commons-logging-1.1.3-src/LICENSE.txt100664 26136 12145235706 15255 0ustartntn 0 0 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. commons-logging-1.1.3-src/src/ 40755 0 0 0 12145235706 13226 5ustar 0 0 commons-logging-1.1.3-src/src/site/ 40775 0 12145235706 15040 5ustartntn 0 0 commons-logging-1.1.3-src/src/site/resources/ 40775 0 12145235706 17052 5ustartntn 0 0 commons-logging-1.1.3-src/src/site/resources/images/ 40775 0 12145235706 20317 5ustartntn 0 0 commons-logging-1.1.3-src/src/site/xdoc/ 40775 0 12145235706 15775 5ustartntn 0 0 commons-logging-1.1.3-src/src/media/ 40775 0 12145235705 15152 5ustartntn 0 0 commons-logging-1.1.3-src/src/test/ 40775 0 12145235705 15052 5ustartntn 0 0 commons-logging-1.1.3-src/src/test/resources/ 40775 0 12145235705 17064 5ustartntn 0 0 commons-logging-1.1.3-src/src/test/resources/org/ 40775 0 12145235705 17653 5ustartntn 0 0 commons-logging-1.1.3-src/src/test/resources/org/apache/ 40775 0 12145235705 21074 5ustartntn 0 0 commons-logging-1.1.3-src/src/test/resources/org/apache/commons/ 40775 0 12145235705 22547 5ustartntn 0 0 commons-logging-1.1.3-src/src/test/resources/org/apache/commons/logging/ 40775 0 12145235705 24175 5ustartntn 0 0 commons-logging-1.1.3-src/src/test/resources/org/apache/commons/logging/tccl/ 40775 0 12145235705 25122 5ustartntn 0 0 commons-logging-1.1.3-src/src/test/resources/org/apache/commons/logging/tccl/log/ 40775 0 12145235705 25703 5ustartntn 0 0 ././@LongLink100644 0 0 145 12145235757 10266 Lustar 0 0 commons-logging-1.1.3-src/src/test/resources/org/apache/commons/logging/tccl/log/props_disable_tccl/commons-logging-1.1.3-src/src/test/resources/org/apache/commons/logging/tccl/log/props_disable_tccl/ 40775 0 12145235705 31536 5ustartntn 0 0 commons-logging-1.1.3-src/src/test/resources/org/apache/commons/logging/tccl/log/props_enable_tccl/ 40775 0 12145235705 31361 5ustartntn 0 0 commons-logging-1.1.3-src/src/test/resources/org/apache/commons/logging/tccl/logfactory/ 40775 0 12145235705 27273 5ustartntn 0 0 ././@LongLink100644 0 0 154 12145235757 10266 Lustar 0 0 commons-logging-1.1.3-src/src/test/resources/org/apache/commons/logging/tccl/logfactory/props_disable_tccl/commons-logging-1.1.3-src/src/test/resources/org/apache/commons/logging/tccl/logfactory/props_disabl 40775 0 12145235705 31675 5ustartntn 0 0 ././@LongLink100644 0 0 153 12145235757 10265 Lustar 0 0 commons-logging-1.1.3-src/src/test/resources/org/apache/commons/logging/tccl/logfactory/props_enable_tccl/commons-logging-1.1.3-src/src/test/resources/org/apache/commons/logging/tccl/logfactory/props_enable 40775 0 12145235705 31665 5ustartntn 0 0 commons-logging-1.1.3-src/src/test/resources/org/apache/commons/logging/jdk14/ 40775 0 12145235705 25112 5ustartntn 0 0 commons-logging-1.1.3-src/src/test/resources/org/apache/commons/logging/config/ 40775 0 12145235705 25442 5ustartntn 0 0 commons-logging-1.1.3-src/src/test/resources/org/apache/commons/logging/config/priority10/ 40775 0 12145235705 27464 5ustartntn 0 0 commons-logging-1.1.3-src/src/test/resources/org/apache/commons/logging/config/nopriority/ 40775 0 12145235705 27660 5ustartntn 0 0 commons-logging-1.1.3-src/src/test/resources/org/apache/commons/logging/config/priority20a/ 40775 0 12145235705 27626 5ustartntn 0 0 commons-logging-1.1.3-src/src/test/resources/org/apache/commons/logging/config/priority20/ 40775 0 12145235705 27465 5ustartntn 0 0 commons-logging-1.1.3-src/src/test/java/ 40775 0 12145235705 15773 5ustartntn 0 0 commons-logging-1.1.3-src/src/test/java/org/ 40775 0 12145235705 16562 5ustartntn 0 0 commons-logging-1.1.3-src/src/test/java/org/apache/ 40775 0 12145235705 20003 5ustartntn 0 0 commons-logging-1.1.3-src/src/test/java/org/apache/commons/ 40775 0 12145235705 21456 5ustartntn 0 0 commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/ 40775 0 12145235705 23104 5ustartntn 0 0 commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/impl/ 40775 0 12145235705 24045 5ustartntn 0 0 commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/simple/ 40775 0 12145235705 24375 5ustartntn 0 0 commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/avalon/ 40775 0 12145235705 24364 5ustartntn 0 0 commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/pathable/ 40775 0 12145235705 24664 5ustartntn 0 0 commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/security/ 40775 0 12145235705 24753 5ustartntn 0 0 commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/logkit/ 40775 0 12145235705 24375 5ustartntn 0 0 commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/tccl/ 40775 0 12145235705 24031 5ustartntn 0 0 commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/tccl/custom/ 40775 0 12145235705 25343 5ustartntn 0 0 commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/tccl/log/ 40775 0 12145235705 24612 5ustartntn 0 0 commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/tccl/logfactory/ 40775 0 12145235705 26202 5ustartntn 0 0 commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/servlet/ 40775 0 12145235705 24570 5ustartntn 0 0 commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/noop/ 40775 0 12145235705 24057 5ustartntn 0 0 commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/jdk14/ 40775 0 12145235705 24021 5ustartntn 0 0 commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/config/ 40775 0 12145235705 24351 5ustartntn 0 0 commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/log4j/ 40775 0 12145235705 24123 5ustartntn 0 0 commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/log4j/log4j12/ 40775 0 12145235705 25305 5ustartntn 0 0 commons-logging-1.1.3-src/src/main/ 40775 0 12145235705 15017 5ustartntn 0 0 commons-logging-1.1.3-src/src/main/assembly/ 40775 0 12145235705 16636 5ustartntn 0 0 commons-logging-1.1.3-src/src/main/java/ 40775 0 12145235706 15741 5ustartntn 0 0 commons-logging-1.1.3-src/src/main/java/org/ 40775 0 12145235705 16527 5ustartntn 0 0 commons-logging-1.1.3-src/src/main/java/org/apache/ 40775 0 12145235705 17750 5ustartntn 0 0 commons-logging-1.1.3-src/src/main/java/org/apache/commons/ 40775 0 12145235705 21423 5ustartntn 0 0 commons-logging-1.1.3-src/src/main/java/org/apache/commons/logging/ 40775 0 12145235706 23052 5ustartntn 0 0 commons-logging-1.1.3-src/src/main/java/org/apache/commons/logging/impl/ 40775 0 12145235705 24012 5ustartntn 0 0 commons-logging-1.1.3-src/src/conf/ 40775 0 12145235706 15021 5ustartntn 0 0 commons-logging-1.1.3-src/src/changes/ 40775 0 12145235706 15504 5ustartntn 0 0 commons-logging-1.1.3-src/src/site/resources/images/logo.png100664 27742 12145235706 22116 0ustartntn 0 0 ‰PNG  IHDR,d³cš—bKGDÿÿÿ ½§“ pHYs  ÒÝ~ütIMEÔ )("q¤â IDATxœí]y|UòÝ3ÉLB…È$p]?œ¹&!†]W Gˆ’ˆ¬( Ê}©ë‚ xp r¸¬„S$ Q`¹WrbÝUDÈLŽ  $™\“L÷ïúMmåõd2 r$ö÷>a¦¦ºº^Õ;êÕ«'ȲÌT¨Pqë ÞjT¨ø½CuB*n1T'T¡âCuB*n1T'T¡âCuB*n1T'T¡âCuB*n1T'T¡âCuB*n1T'T¡âCuB*n1T'T¡âC{ý,¸s‚ üV¬®“[£h”y“ˆo„ 7N·¿­b¯_Q7HÕ-BóŽ2¥§§Ÿ>žãÜ([ø¹ÉdBhBsçÎ]²d‰ûMß²!7Ë–- hˆÛèÑ£úé§šššÚÚZ»Ý.I’$I ±Zºt© Vþþþ3f̸pá‚Íf«««sÍmÇŽ ðÃíÛ·Ûl¶ÚÚÚººº'N„‡‡+™ÆóçÏ×ÔÔsàÜÝ…!†„„”––Z­ÖêêêãÇ»èc~~~HLÅHKK›={¶Òâ­V«Õjýá‡жœbáÂ…eeeðvÜà©ÄäÉ“‘ìRÙF&“ … Û¶m[ee¥Õj-++Û¸qcHHe8jÔ(h&®sIJJJHHP*dË–-åååGŽa¹!lܸ±¼¼¼ªªÊf³9m}0 à›o¾©ªª‚¦/++;tèPhh(ò)//·Z­®ß·uÀ]'LJJ¦=þ¼Õj½víÚÕ«W/_¾\RRb±X‚ƒƒiK|òÉ'×®]«¨¨PjpÙ²eH¶uëÖòòrŽUqqqLL åZJ¹I’4{öì„„˜q>}ú4œ¿¿ÿôéÓ·lÙ²qãÆÉ“'s”óçÏ/))Ù´iü7..nÛ¶m›7oNLL|á… ƒ’¸´´´²²ý0<<õÔS>>>Œ1I’€­Ýnïׯ_rr2¾WNNÎ?þ¸zõê±cÇb·‚Ä=zôøæ›oŠ‹‹¸¨¨èñÇG]¡bc½{÷6™L@–œœìéé ³Y–A@ÅŠ¢xï½÷–••}ûí·@\^^žŸŸ½U,C_Êjµ~ðÁS¦Lñññ̓’$õèÑ#99)ívûàÁƒ±é5 °]¾|9øahhèðáÃABx­V  †ï¿ÿþ‡~˜6m†V«Åo[e„¦ñ}ÂG}þ˜6mZÇŽ«ªªPwÆÓÓS§Óétº»ï¾›[rüéOª¬¬ÄK–å9sæà·“&Mªªª‚•ƒ$IÐ ÀMï7wzë­·*++ébƒ9ÛÕèÛ·ïÂ… !Œ«0D­VëááÁMtûöíûÞ{ïœhµ( ]¢0ÆL&Suu5Šás°HJ9sæÌAƒÁr _Øzxx€Å#æÌ™ó—¿ü¥ªª èÁòP·AAAHY\\ €¨ÀV–åeË–¡ÆÆÆvèК ˜*V§Ó½ýöÛt¹wïÞ'NÀOjkkaÀQê^ ´Š½°F£ñðð ¥³†ÜÜ\|:‚¡™™™ø­,ËÀ„ôôô„É9íã”nMhÄ iëFGGcó³úºÛ¼y3Nèß{n;ÒèVZZ <¸ªª š\E]}èõúˆˆj+ÅÅÅëÖ­ƒÖE[Q†Â;uêTç€$I0xzzêõzooŽØf³Á{Q“õòòRÿüóG}â‰'8²ÂÂÂ×_ý§Ÿ~‚­K˜¶Öævå„ÜVÒ§Ÿ~Šñw’ `€FÀÅWÎ;G£ ¬áþ›ÚJß¾}YSÖo¿¸PlCIENqÓt+FÑÛ´iÓ£Gyóæ:tèᇦdEEE}ô—BÐ*ýЕvíÚ•þ7///77ÖczNrrò£>JûTÎ¥óòò•ks¡ ‘ÈÊïܹY†Åb±X,AC?¤Šíׯ_çÎo´Ž3fùòåÀŸ ¤ßsÏ=«V­úàƒ(ýÞ½{1Q±ÏK]9¡ÑhäzÙW^y¥  €f9;ýazzú£>úÙgŸQSàœðìÙ³è‡.:9nìá‡Hð½uG®ÝDhh(×L y×±+V_·QQQœbonÓÓÓQ$:/õññiÛ¶íèÑ£Ÿzê)$...†cšÔÚúÃFÖ„ÜÖªÅbyÿý÷óóó1RÙÆàááá!!!4Á*44”Ûl8|ø0ÄЉÓt§Ÿ~1àNºê„Œ1A¦NJ?9rädÕ¸ØÈ1›Í¸ÁØ¥K—qãÆ $[ÀéæûõC–åääd:™‚=-ðC_xáúšƒÚ‘´t¸rBAf̘Á%7:tè±ÇKOO§~ˆ]Ô²eËÂÃÃM&Ó¶mÛ`ç—&oÙ²…²Ú¾}{QQf:íç0ãÔ`0@$ Ó¦`ûQõCh&z„Åb±lݺ•ÛMmH±Œ18µHë4­ç·ÂòåË1ÝBvdMa†}Ïž=‘²OŸ>4µUƒÌ…ârkñâÅÜWÅÅÅqqqýû÷饗vìØ±cÇŽ¤¤¤Ù³gwëÖ +mÛ¶­sçÎô…쨕˜˜HY½üòË8Z*û9<Ãáçç—ššŠ‰˜5þ›tØ-º]áõEQܼy3=q²bÅŠ‚‚ì¹Á*ƒÀßü1„d`Pú­2T\8̪U«.]ºD7lVOOÏ«W¯"%L’¹^ëC##¡(Šñññ6lP~[XX¸víÚ'Ÿ|òñÇ;vìŠ+Àa6oÞ§Îp¿¦:ñññP"——7kÖ,š ŠÝvRR¸´¿¿ÿž={:uê$Ë2žŸ‚4è­¹u#séWôÀÐèO‹ÅõU£àˆQw`±X¸O@·ÝºuÛ¿?õÃ'Ÿ|Òd2ÑÉÀd2á­ÄÄÄaÆaR>è’éA(((p_0šäÈ+))Á¿9‡4›Í¯¾ú*ä©Ò>†b¨uÀ>|øøñã]'Tµ42å€.*..Ž;_ë~~~Ÿ|òÉ!CðÈŸ\?Í ´¿{÷n<zðàÁÈÈÈÕ«Wc oRRRDDĘ1ccF£qÿþý;w–È©ÆØ¡C‡À”»d²,sÄ‹åðáÃø-‡åË—Sâ¼¼<%gøƒcûé§Ÿ"ON%ñáÇÁ½¹y£¬8+ÈÛ€¬þN)4S·nÝöìÙ3lØ0|µ|ðÍ7ßLKKƒ>îäÉ“sæÌéÚµ«Édò÷÷ß´iÓðáÃÁ?qBˆ½› ~ø¡›/ŧ9Y}÷£~¸{÷î#FÀ¢†žNž;w.<466vÍš5˜,Þº×ÿÔ•'說ªÎŸ??iÒ$¬ ÁáÙgŸ0aT”`õœÑôQäVQQ±víÚ7bíPiÀ€xàl°étº/¾ø¢°°0%%…«ÃóõõíÓ§OLLÌ<ЫW/N—žžî”˜1öðÃ1¢Gƒ Òëõ.ˆ}}}rÏ=÷ôìÙ3'''+++%%…3AÆXŸ>}ú÷ïo4ÇŒãíííáá‘ššš‘‘¡´W`Ù³gOOOOÄ}úô2dH·nÝ"##{õê'îdY®«««®®®¬¬t¬8‚‰¢¨Óé@«p¢M»Ý¯ƒÊ¤Ñ æÈÎÇØ©F£A[j­gš¿‹Bp]‡cæ¢ãÌ;| ŽÄ\œ‚Ro¡Š£ÜðWtº^ºÕ; ŠÂÓ1ì‰1†ƒ#G`RD ½ºpÃ1pFby Â2GWâQ߈¢HYà¹@Œ}<°eޏ-5ä .J÷‡ +àŒg‚P±´-DG3,P‚2C§rÒGƒœ  ´pi ö`KËaS2Æ`Æ·F9±)Er´·/ ݺ†zfÁsgÛqŸ+_4´'iÀÛ¢ ÉSÜÛPK`̬\&åÕè ÌHœz° ‘+ÒSbOOOÊ™Û åa4ä8ýLv %1Z'÷‚¨%Ž30ç8sŠõððàr›h°Q©XÊòáäÄ—âäDï‚Þ ~Ný4Z­¥âÔ¬ÄúuZß,Ñ„ a°w¤i.4¾Lݯ¡® ƒ{ȇ†Ñ©r`Ž6£?‘è 48ÃD 1•Ÿi•ÄȇDF¦Ù8&0âÜ R¶”e@wA¬©j¦8“—Hz *–ê–óeCsi7ÊG³ú«\ZEb:€S{øŸ]mpíÞúд[™p ;âéIEÇCr­5™„Ú±IÐVXý1“Z å€Í))òB¨ÁQ £ôõtá ë¯`•Ä‚c‹å”냓Ù‡M˜ÚkCÄœ1ÒÇqºeЉþŠê¨ôå£9z§ZåæDÈP®¿ÿåÄk­îhÎÕhT_JÓtÇý”ܘ³‹F*%QÊÃêŸ"w‡ÿuj(Jb勸~…ßP`×*jè·Ü#Òm“š6ŸSE5d”3v.^ªõ¡™÷œúÌõ@)Œ›<} §Þò›»‰¦òäœ`6›ÍfsXX5V憖œ>Ñݺ¯«&iµÑqÄP??,,lÖ¬Yœ‡·/•UÜöHKKƒÌxÆX||<]ªÑõ^k½³qÖ¬YôîÇÖñú×5ª¸¡€îŸKFûÛäú±«Ö½jâ^ ïÒÁp”Ó€y B« û¶øûû'$$pw÷J’Tí½£w¦´>ªŸŸæ-àí`-ýõÝÚ'TqK Ër\\œ$I˜Æ]WWgµZ%Gl` Î.äh5X²d dó3ÆÞ|óÍŠŠ »Ý™429!ÐrCÕ okȲ,I=°[WWWVV&Ë2¤Ú1GªM‹¶B׈¿páÂñãÇûôéÓ®];tBÉ‘‘×Ò·òU'l s-»Ý#!¤ÑAöÒÿ–ø­ÎáÝ Cll,Ün¹xIc¯_s¬…¾¾ê„- ’$UUUI’•­¸ò @þ;¤±(e8ª…z S°E€Ûc”9îuäÜ[(ÞMæ¾Aj8LAñ’…=eªÞæH~»»·NÀ›Œ<¡šXhnµ˜Í‡ê„·5`2Æ9áHè¹ÍPÑÐ: Ž„*n,”ݼûzzºÉdG Çê•îç» a@–倀å…jîBÍã#8Òå=<<²³³ƒƒƒåúµ‹8…`rŸÓG'$$°úQœFå5ÒŸ»#vð›åÞ¨¸1$iÇŽØ^QQQÇŽ;xðàÑ£G³³³ÏŸ?ùòåÊÊJZ :--Mi+€™3g?~Ë~Úë—å`2™€Oxx8$Íâãã—,Y|¸:§Ü®ŸÏŽ;°Ú?Ö à*P˲œ””‚ä>»Ý~ñâÅY³fQ ,Y²~ÛhîÛìÙ³è]aaa3gÎܾ}»›¯ß(T'làœð›o¾9tèS'4™L`åK—.ýù矡êĶmÛŒF#2™>}:Ô¡Á¤¥é$%%Ÿ'N@Mššî.Џ¸8´iÎ1šÇçÒ¥KÔ÷PDä·Ùl/^\ºt)×éÄÅÅÕÔÔ;vŒ» ±xñb«ÕŠLhˆ `2™ SgéÒ¥(ö¶mÛ›1æfצ„:m=0›Í`=ÇŽƒJY6›M’¤èèèáÇ?õÔS_|ñclåÊ•;wîûì³ñãLJ††Nž<ÙÏϯ°°põêÕXñõ•W^:th@@Öda䀨Ùl8p ôhÓ§OÇ“Ê1117n¤·e„„„ Ð}}Áq|ÔɪšÀÝ””„y[QQQóæÍ«©©Ñh4mÛ¶mß¾}»víÚ´ic±X ÆúÍ7ßÓCñØ+?÷ÜsPk1´gÏ®‰ ˜® e¸°Úš$I……… @ÙÒÓÓ =>)ŠŠŠºwï~=| wÈÊÊ4hRH¤-ì— ‚ðâ‹/brŸŸŸ_AAÁo¼1qâD,€ Ërttô©S§€æ™gž™7o%£8p T»Ü¾}{ll,-¿L²³³É¼yóàbýbN+†4„–VR;v,x`XXX`` T4à=›uuu«W¯Æ²Ë§NzõÕW±ê&CӒǵµµÕÕÕÈÇf³uêÔ)(( Nœ8QZZZZZZVV|82ÉÌ̤bcE¼&máªNØ™™‰W,M™2<ê)ÂCtóÏ>û,þpÆ çÏŸëACÄk*üýý‘¸˜itt4rØ»wo¹V«,–…è„ÍãƒÅ¹íŽ’v«ÕŠ~…oÇ•ÕˆŠŠŠˆˆ£.Mï!=sæŒÕjEÏ©$IÂ×gŒùúú*59bÄ$Ø¿¿ÕjÅq·¸¹Ù|ª¶@^À€Ðn þ'sÜS¯ØØXúÛÝ»w£!b X€Ùl¦¬à+FCÇY–!RBíOªqe³ù8µcQ•Q%¤ä>ZÙôÀM±T, ÏP‚‹/"\ë Šb@@½óJ³âߌ£Uª¶|þùçøwÇŽÑnÀò°3/¿ûî»é<077*öÂÀÂ!F‹GÔjµt›9*ÓÝ¢(Ò KóøÐ@Jfw”V–ÉDY–ëêßÌ'8ªŒ+ŸXSSƒShI’èM!6› û\ˆzxxS&ð,¬aÝÔC-ª¶x`@ײ,〠 Ü=z”öåtŠÈËÈÈÀ*éè<Køúúb&s$yj4­ÃEcIDATn¢y|h¡D ÙYÑD Ê SÞt:··7%EüÞKC%ÏÎÎF±%r3ö pk-}jÀýŠª¶xp˜Áê v&„ú×9b8~ôèÑô'pN¨èµ°ûöíCeÄȯ!Á!ÖM¥®Þ<>´´)Âé #Š’ŒäÜ äæCè€8VÌQ]×–J±±&?sô(€RlZ¢ÚÍÁPuÂÖ¼ÌÖbAC¡?‘eF˜•=ÿüóøÕÁƒé¾cL„¬¬,øÖ`0 0mŽÛ%›1cÆõð¡2SiÝœéqN( WŒ†VzE|qqqnn.WјJ>lØ0ºA¡:áïß~û-]q!нAèÂfâĉ<ò|e±XæÏŸÏ™)ÆÖ®]«¬.80cÆŒQ£F5›O“LÙiz-"[å¯hò cÌ`0Ð{Ýß|óÍ’’‰àóÏ?‡MÿI“&^ØÕ [!ÐÿRú>}úõ‹óK’ôÉ'ŸLš4 ¾þúë·Þz+//¯®®Îl6?þóÏ?÷÷÷OLL ÈexJ[ß²e Ž«Må#6P~Ûé‡NA]Q$Y,SnŽ‹‹Û°al¨–””LŸ>ýÈ‘#0’¯Y³n­›:uê‚ ¨Ÿ7c" PÓÖZ?Œô‚ûq·¸»ÿtÕ [¦L™B÷å>ÿüóQ£FIŽ+¥èx(8”200°oß¾eee 'Š¢h±X^}õUF³sçNÈ8ñõõÕh4^^^555Ìq±™ä¸„œ.úÅà¡ EEE³gÏE±Ù|áf§7ÃC׬Y³råÊ]»vùøøX­Ö‡zdƒ,mØ\Á¬¼–“Žáî?QuÂÖ¸eý055uäÈ‘Üj’$A0Ðl6cŽÛ¼yóàKE1**Êl6Ÿ={V§ÓÁ¾‚à¸" n…Ñö!a烻è!§ü»ï¾ÓëõÍãs³Uɘ /½ôÒŠ+/^ܽ{w«Õ }`Z©ÌQô@Eè/hßÑÔ\ Ì´x€Å/^¼‡—/_NMM•Èuóvr÷ãœ9s€lÆ ýúõcŽÙ.ÆæÏŸC¥Åbñ°ÆôñW`|^^^p!6LÌ;rÊ‹‹‹1k§|n²>322 뵨¨HKnž¦W‚&aH±!‰ëƒÜ„:¶‚àïï¿oß¾¡C‡1ÆÖ¯_ïëë;tèPLÝ’$IÅ””HL{÷ÝwGŒu„EÇíËà!kÖ¬¶=ôc,::š†[áÌ‘(ŠÁÁÁþþþŽó`‚˜ ý׿þõzøàäùúÁ%68æ¯\¹råÊ•AAA;wÆDVƒÁb †œŽ6{ôVðv‡,ËôLÐ&MštÇw0Å•šÝºuÛ½{÷믿¾ÿ~ÆØ;ï¼óÃ?DGG?ðÀ6›íÛo¿]½zõÎ;Þ}÷ݘ˜˜ŠŠ ‰\ëóÀÐÐÐÌÌL|âž={¨<À’˜˜ØµkWº‚Ågxx8ž j6V?ŒÄûì³Ïbbb˜âFÄ?üiΜ9ã42ì«°°°;w" ž?Dlܸÿöóó{ûí·GÝÔu …z¨÷öErrrzzzrr2=WÎëܹó}÷Ý÷àƒ†„„üñ¼ãŽ;¼½½5Ýn¯ªª*//?qâDbbâÑ£G9†þþþÓ§OŸ6mšÝn‡|Q8<­½½½}||Ú´isùòåU«VÑ“âÀaaaÜ>¡Ùl^¾|9íAšÄ'55µ°°0--óÆØ Aƒî¿ÿþÀÀÀˆˆˆªªªsçέY³&##ƒÓÒ Aƒ|ðÁÐÐÐöíÛýõ×{öìIMMU²úóŸÿ‚S¶pGtäbÈäìÙ³gΜٺukqqqJJJhh(-QXXØl>Å>Œ±ºººšš«Õ gØ«««c^^^wÜqT÷Ðét¢(Â\Àjµ^»vÍjµÖÖÖŠ¢Ø¦MÔ/­©©©¨¨VUUU”8áO<‘™™ùå—_¶mÛh @Šclä”””äååmݺ577÷é§Ÿ~óÍ71M{"wüP]Þî?ÄÀ€ `—¢ãfÆ@|(Š"\€`:šnàÖ2ðððHMM;v¬¿¿ÿ¢E‹˜cA[ްÏ|@’=zôìÙsРA<òÈ… î¿ÿ~< ˜šš:nܸfóÑëõÎ… xMÁq¢1† fW£–ÀÉ¡Ñ8 ÌÐÓOÀ BAÌ‘'À+((6l˜ÙlÞ´iS—.]ÊËËYý´ØY±Û¶m9qâD³Ù\^^®×ë15=°Q?Tð¶Í#H)x»Ý;T´þ4Œ*à‡@LSˆõ½áêEã8é£Õj³³³ÇŽË›>}ºÁ`°Z­8j)í »óÎ;c0ÇãÎÉÉ7nclêÔ©]ºt©¨¨h€F£‘Ç…aÃÞ…ÆQ©káÎ| ãç H?GM:´  Àh4Ž9²ªªJp¤†‚Ò½[’¤N:I’é‚âHa£­¬:a ¶+Ü‚Y&0Ž¡õ`² vðD°Â°èÅ`#ÊÖÐëSu);¦˜L*59vìXºMÏ{â‰'úöí|Ï=÷`j(ä覦¦Â®cbbbLL ŠÍƒ…+Í¿sÝζ С±ý•ÜðmD²,'%%=öØcîK5mÚ´E‹a’*:á¾}ûðLpóøà<ÓM2e§/î´Ói”&???22Òý=z£Ñ¸yóæ.]ºÐ×g'ÉavÍGMànÀÙ£ÜØÐo•óO%e\\ÜÑ£GCBB•gêÔ©ßÿýÛo¿MsÄ™cq»wï^îÈ“ø‚ L½‹BE“1IÈ øúë¯wíÚ•““sîÜ9$:t¨F£‰‰‰yä‘Gp à6è` g³ÙNœ8ñÅ_4. alt<¹þׇ†êêêÿþ÷¿;wî„póP«Õ‚ØxÕ™@²ÒpÚL‹Äáž¾ûb«N¨â 7Œ¤ªêõzzù®èLé6è„×Éç¦y jº üªì 22`¢ät ÚŒŽC ̨àJ{}àî6Æ÷išÒþ~+>·êõ9É©RÉQx.Èä>T'Tá4§CðÊTåÜ âsóÁÉŒkBøåë_Oß<ÉU'TÑ hš_œj27Œï·âsóÒº›5}ô£PP…[PÚIóÌî·âs“áÔM~+Éÿ§oöýIIEND®B`‚commons-logging-1.1.3-src/src/site/xdoc/issue-tracking.xml100664 13257 12145235706 21574 0ustartntn 0 0 Commons Logging Issue tracking Commons Documentation Team

Commons Logging uses ASF JIRA for tracking issues. See the Commons Logging JIRA project page.

To use JIRA you may need to create an account (if you have previously created/updated Commons issues using Bugzilla an account will have been automatically created and you can use the Forgot Password page to get a new password).

If you would like to report a bug, or raise an enhancement request with Commons Logging please do the following:

  1. Search existing open bugs. If you find your issue listed then please add a comment with your details.
  2. Search the mailing list archive(s). You may find your issue or idea has already been discussed.
  3. Decide if your issue is a bug or an enhancement.
  4. Submit either a bug report or enhancement request.

Please also remember these points:

  • the more information you provide, the better we can help you
  • test cases are vital, particularly for any proposed enhancements
  • the developers of Commons Logging are all unpaid volunteers

For more information on subversion and creating patches see the Apache Contributors Guide.

You may also find these links useful:

commons-logging-1.1.3-src/src/site/xdoc/guide.xml100664 114232 12145235706 17754 0ustartntn 0 0 User Guide Commons Documentation Team

  1. Introduction
  2. Quick Start
    1. Configuration
    2. Configuring The Underlying Logging System
    3. Configuring Log4J
  3. Developing With JCL
    1. Obtaining a Log Object
    2. Logging a Message
    3. Serialization Issues
  4. Jars Included in the Standard Distribution
    1. commons-logging.jar
    2. commons-logging-api.jar
    3. commons-logging-adapters.jar
  5. JCL Best Practices
  6. Best Practices (General)
    1. Code Guards
    2. Message Priorities/Levels
    3. Default Message Priority/Level
  7. Best Practices (Enterprise)
    1. Logging Exceptions
    2. When Info Level Instead of Debug?
    3. More Control of Enterprise Exception Logging
    4. National Language Support And Internationalization
    5. Classloader and Memory Management
  8. Extending Commons Logging
    1. Contract
    2. Creating a Log Implementation
    3. Creating A LogFactory Implementation
  9. A Quick Guide To Simple Log
  10. Frequently Asked Questions

The Apache Commons Logging (JCL) provides a Log interface that is intended to be both light-weight and an independent abstraction of other logging toolkits. It provides the middleware/tooling developer with a simple logging abstraction, that allows the user (application developer) to plug in a specific logging implementation.

JCL provides thin-wrapper Log implementations for other logging tools, including Log4J, Avalon LogKit (the Avalon Framework's logging infrastructure), JDK 1.4, and an implementation of JDK 1.4 logging APIs (JSR-47) for pre-1.4 systems. The interface maps closely to Log4J and LogKit.

Familiarity with high-level details of the relevant Logging implementations is presumed.

As far as possible, JCL tries to be as unobtrusive as possible. In most cases, including the (full) commons-logging.jar in the classpath should result in JCL configuring itself in a reasonable manner. There's a good chance that it'll guess (discover) your preferred logging system and you won't need to do any configuration of JCL at all!

Note, however, that if you have a particular preference then providing a simple commons-logging.properties file which specifies the concrete logging library to be used is recommended, since (in this case) JCL will log only to that system and will report any configuration problems that prevent that system being used.

When no particular logging library is specified then JCL will silently ignore any logging library that it finds but cannot initialise and continue to look for other alternatives. This is a deliberate design decision; no application should fail to run because a "guessed" logging library cannot be used. To ensure an exception is reported when a particular logging library cannot be used, use one of the available JCL configuration mechanisms to force that library to be selected (ie disable JCL's discovery process).

There are two base abstractions used by JCL: Log (the basic logger) and LogFactory (which knows how to create Log instances). Specifying a particular Log implementation is very useful (whether that is one provided by commons-logging or a user-defined one). Specifying a LogFactory implementation other than the default is a subject for advanced users only, so will not be addressed here.

The default LogFactory implementation uses the following discovery process to determine what type of Log implementation it should use (the process terminates when the first positive match - in order - is found):

  1. Look for a configuration attribute of this factory named org.apache.commons.logging.Log (for backwards compatibility to pre-1.0 versions of this API, an attribute org.apache.commons.logging.log is also consulted).

    Configuration attributes can be set explicitly by java code, but they are more commonly set by placing a file named commons-logging.properties in the classpath. When such a file exists, every entry in the properties file becomes an "attribute" of the LogFactory. When there is more than one such file in the classpath, releases of commons-logging prior to 1.1 simply use the first one found. From release 1.1, each file may define a priority key, and the file with the highest priority is used (no priority definition implies priority of zero). When multiple files have the same priority, the first one found is used.

    Defining this property in a commons-logging.properties file is the recommended way of explicitly selecting a Log implementation.

  2. Look for a system property named org.apache.commons.logging.Log (for backwards compatibility to pre-1.0 versions of this API, a system property org.apache.commons.logging.log is also consulted).
  3. If the Log4J logging system is available in the application class path, use the corresponding wrapper class (Log4JLogger).
  4. If the application is executing on a JDK 1.4 system, use the corresponding wrapper class (Jdk14Logger).
  5. Fall back to the default simple logging wrapper (SimpleLog).

Consult the JCL javadocs for details of the various Log implementations that ship with the component. (The discovery process is also covered in more detail there.)

The JCL SPI can be configured to use different logging toolkits (see above). JCL provides only a bridge for writing log messages. It does not (and will not) support any sort of configuration API for the underlying logging system.

Configuration of the behavior of the JCL ultimately depends upon the logging toolkit being used. Please consult the documentation for the chosen logging system.

JCL is NOT responsible for initialisation, configuration or shutdown of the underlying logging library. In many cases logging libraries will automatically initialise/configure themselves when first used, and need no explicit shutdown process. In these situations an application can simply use JCL and not depend directly on the API of the underlying logging system in any way. However if the logging library being used requires special initialisation, configuration or shutdown then some logging-library-specific code will be required in the application. JCL simply forwards logging method calls to the correct underlying implementation. When writing library code this issue is of course not relevant as the calling application is responsible for handling such issues.

Log4J is a very commonly used logging implementation (as well as being the JCL primary default), so a few details are presented herein to get the developer/integrator going. Please see the Log4J Home for more details on Log4J and it's configuration.

Configure Log4J using system properties and/or a properties file:

  • log4j.configuration=log4j.properties Use this system property to specify the name of a Log4J configuration file. If not specified, the default configuration file is log4j.properties.
  • log4j.rootCategory=priority [, appender]*
  • Set the default (root) logger priority.
  • log4j.logger.logger.name=priority Set the priority for the named logger and all loggers hierarchically lower than, or below, the named logger. logger.name corresponds to the parameter of LogFactory.getLog(logger.name), used to create the logger instance. Priorities are: DEBUG, INFO, WARN, ERROR, or FATAL.
    Log4J understands hierarchical names, enabling control by package or high-level qualifiers: log4j.logger.org.apache.component=DEBUG will enable debug messages for all classes in both org.apache.component and org.apache.component.sub. Likewise, setting log4j.logger.org.apache.component=DEBUG will enable debug message for all 'component' classes, but not for other Apache projects.
  • log4j.appender.appender.Threshold=priority
  • Log4J appenders correspond to different output devices: console, files, sockets, and others. If appender's threshold is less than or equal to the message priority then the message is written by that appender. This allows different levels of detail to be appear at different log destinations. For example: one can capture DEBUG (and higher) level information in a logfile, while limiting console output to INFO (and higher).

To use the JCL SPI from a Java class, include the following import statements:

    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;

Note that some components using JCL may either extend Log, or provide a component-specific LogFactory implementation. Review the component documentation for guidelines on how commons-logging should be used in such components.

For each class definition, declare and initialize a log attribute as follows:

    public class CLASS { private Log log = LogFactory.getLog(CLASS.class); ... ;

Note that for application code, declaring the log member as "static" is more efficient as one Log object is created per class, and is recommended. However this is not safe to do for a class which may be deployed via a "shared" classloader in a servlet or j2ee container or similar environment. If the class may end up invoked with different thread-context-classloader values set then the member must not be declared static. The use of "static" should therefore be avoided in code within any "library" type project.

Messages are logged to a logger, such as log by invoking a method corresponding to priority. The org.apache.commons.logging.Log interface defines the following methods for use in writing log/trace messages to the log:

    log.fatal(Object message); log.fatal(Object message, Throwable t); log.error(Object message); log.error(Object message, Throwable t); log.warn(Object message); log.warn(Object message, Throwable t); log.info(Object message); log.info(Object message, Throwable t); log.debug(Object message); log.debug(Object message, Throwable t); log.trace(Object message); log.trace(Object message, Throwable t);

Semantics for these methods are such that it is expected that the severity, from highest to lowest, of messages is ordered as above.

In addition to the logging methods, the following are provided for code guards:

    log.isFatalEnabled(); log.isErrorEnabled(); log.isWarnEnabled(); log.isInfoEnabled(); log.isDebugEnabled(); log.isTraceEnabled();

Prior to release 1.0.4, none of the standard Log implementations were Serializable. If you are using such a release and have a Serializable class with a member that is of type Log then it is necessary to declare that member to be transient and to ensure that the value is restored on deserialization. The recommended approach is to define a custom readObject method on the class which reinitializes that member.

In release 1.0.4, all standard Log implementations are Serializable. This means that class members of type Log do not need to be declared transient; on deserialization the Log object will "rebind" to the same category for the same logging library. Note that the same underlying logging library will be used on deserialization as was used in the original object, even if the application the object was deserialized into is using a different logging library. There is one exception; LogKitLogger (adapter for the Avalon LogKit library) is not Serializable for technical reasons.

Custom Log implementations not distributed with commons-logging may or may not be Serializable. If you wish your code to be compatible with any arbitrary log adapter then you should follow the advice given above for pre-1.0.4 releases.

The commons-logging.jar file includes the JCL API, the default LogFactory implementation and thin-wrapper Log implementations for Log4J, Avalon LogKit, the Avalon Framework's logging infrastructure, JDK 1.4, as well as an implementation of JDK 1.4 logging APIs (JSR-47) for pre-1.4 systems.

In most cases, including commons-logging.jar and your preferred logging implementation in the classpath should be all that is required to use JCL.

The commons-logging-api.jar file includes the JCL API and the default LogFactory implementation as well as the built-in Log implementations SimpleLog and NoOpLog. However it does not include the wrapper Log implementations that require additional libraries such as Log4j, Avalon and Lumberjack.

This jar is intended for use by projects that recompile the commons-logging source using alternate java environments, and cannot compile against all of the optional libraries that the Apache release of commons-logging supports. Because of the reduced dependencies of this jarfile, such projects should be able to create an equivalent of this library with fewer difficulties.

This jar is also useful for build environments that automatically track dependencies, and thus have difficulty with the concept that the main commons-logging.jar has "optional" dependencies on various logging implementations that can safely go unsatisfied at runtime.

The commons-logging-adapters.jar file includes only adapters to third-party logging implementations, and none of the core commons-logging framework. As such, it cannot be used alone; either commons-logging.jar or commons-logging-api.jar must also be present in the classpath.

This library will not often be used; it is only intended for situations where a container has deployed commons-logging-api.jar in a shared classpath but a webapp wants to bind logging to one of the external logging implementations that the api jar does not include. In this situation, deploying the commons-logging.jar file within the webapp can cause problems as this leads to duplicates of the core commons-logging classes (Log, LogFactory, etc) in the classpath which in turn can cause unpleasant ClassCastException exceptions to occur. Deploying only the adapters avoids this problem.

Best practices for JCL are presented in two categories: General and Enterprise. The general principles are fairly clear.Enterprise practices are a bit more involved and it is not always as clear as to why they are important.

Enterprise best-practice principles apply to middleware components and tooling that is expected to execute in an "Enterprise" level environment. These issues relate to Logging as Internationalization, and fault detection. Enterprise requires more effort and planning, but are strongly encouraged (if not required) in production level systems. Different corporate enterprises/environments have different requirements, so being flexible always helps.

Code guards are typically used to guard code that only needs to execute in support of logging, that otherwise introduces undesirable runtime overhead in the general case (logging disabled). Examples are multiple parameters, or expressions (e.g. string + " more") for parameters. Use the guard methods of the form log.is<Priority>() to verify that logging should be performed, before incurring the overhead of the logging method call. Yes, the logging methods will perform the same check, but only after resolving parameters.

It is important to ensure that log message are appropriate in content and severity. The following guidelines are suggested:

  • fatal - Severe errors that cause premature termination. Expect these to be immediately visible on a status console. See also Internationalization.
  • error - Other runtime errors or unexpected conditions. Expect these to be immediately visible on a status console. See also Internationalization.
  • warn - Use of deprecated APIs, poor use of API, 'almost' errors, other runtime situations that are undesirable or unexpected, but not necessarily "wrong". Expect these to be immediately visible on a status console. See also Internationalization.
  • info - Interesting runtime events (startup/shutdown). Expect these to be immediately visible on a console, so be conservative and keep to a minimum. See also Internationalization.
  • debug - detailed information on the flow through the system. Expect these to be written to logs only.
  • trace - more detailed information. Expect these to be written to logs only.

By default the message priority should be no lower than info. That is, by default debug message should not be seen in the logs.

The general rule in dealing with exceptions is to assume that the user (developer using a tooling/middleware API) isn't going to follow the rules. Since any problems that result are going to be assigned to you, it's in your best interest to be prepared with the proactive tools necessary to demonstrate that your component works correctly, or at worst that the problem can be analyzed from your logs. For this discussion, we must make a distinction between different types of exceptions based on what kind of boundaries they cross:

  • External Boundaries - Expected Exceptions. This classification includes exceptions such as FileNotFoundException that cross API/SPI boundaries, and are exposed to the user of a component/toolkit. These are listed in the 'throws' clause of a method signature.
    Appropriate handling of these exceptions depends upon the type of code you are developing. API's for utility functions and tools should log these at the debug level, if they are caught at all by internal code.
    For higher level frameworks and middleware components, these exceptions should be caught immediately prior to crossing the API/SPI interface back to user code-space, logged with full stack trace at info level, and rethrown. The assures that the log contains a record of the root cause for future analysis in the event that the exception is not caught and resolved as expected by the user's code.
  • External Boundaries - Unexpected Exceptions. This classification includes exceptions such as NullPointerException that cross API/SPI boundaries, and are exposed to the user of a component/toolkit. These are runtime exceptions/error that are NOT listed in the 'throws' clause of a method signature.
    Appropriate handling of these exceptions depends upon the type of code you are developing. APIs for utility functions and tools should log these at the debug level, if they are caught at all.
    For higher level frameworks and middleware components, these exceptions should be caught immediately prior to crossing the API/SPI interface back to user code-space, logged with full stack trace at info level, and rethrown/wrapped as ComponentInternalError. This ensures that the log contains a record of the root cause for future analysis in the event that the exception is not caught and logged/reported as expected by the user's code.
  • Internal Boundaries. Exceptions that occur internally and are resolved internally. These should be logged when caught as debug or info messages, at the programmer's discretion.
  • Significant Internal Boundaries. This typically only applies to middleware components that span networks or runtime processes. Exceptions that cross over significant internal component boundaries such as networks should be logged when caught as info messages. Do not assume that such a (process/network) boundary will deliver exceptions to the 'other side'.

You want to have exception/problem information available for first-pass problem determination in a production level enterprise application without turning on debug as a default log level. There is simply too much information in debug to be appropriate for day-to-day operations.

If more control is desired for the level of detail of these 'enterprise' exceptions, then consider creating a special logger just for these exceptions:

    Log log = LogFactory.getLog("org.apache.component.enterprise");

This allows the 'enterprise' level information to be turned on/off explicitly by most logger implementations.

NLS internationalization involves looking up messages from a message file by a message key, and using that message for logging. There are various tools in Java, and provided by other components, for working with NLS messages.

NLS enabled components are particularly appreciated (that's an open-source-correct term for 'required by corporate end-users' :-) for tooling and middleware components.

NLS internationalization SHOULD be strongly considered for used for fatal, error, warn, and info messages. It is generally considered optional for debug and trace messages.

Perhaps more direct support for internationalizing log messages can be introduced in a future or alternate version of the Log interface.

The LogFactory discovery process (see Configuration above) is a fairly expensive operation, so JCL certainly should not perform it each time user code invokes:

LogFactory.getLog()

Instead JCL caches the LogFactory implementation created as a result of the discovery process and uses the cached factory to return Log objects. Since in J2EE and similar multi-classloader environments, the result of the discovery process can vary depending on the thread context classloader (e.g. one webapp in a web container may be configured to use Log4j and another to use JDK 1.4 logging), JCL internally caches the LogFactory instances in a static hashtable, keyed by classloader.

While this approach is efficient, it can lead to memory leaks if container implementors are not careful to call

LogFactory.release()

whenever a classloader that has utilized JCL is undeployed. If release() is not called, a reference to the undeployed classloader (and thus to all the classes loaded by it) will be held in LogFactory's static hashtable.

Beginning with JCL 1.1, LogFactory caches factory implementations in a "WeakHashtable". This class is similar to java.util.WeakHashMap in that it holds a WeakReference to each key (but a strong reference to each value), thus allowing classloaders to be GC'd even if LogFactory.release() is never invoked.

Because WeakHashtable depends on JDK 1.3+ features, it is dynamically loaded depending on the JVM version; when commons-logging is run on java versions prior to 1.3 the code defaults to a standard Hashtable instead.

If a custom LogFactory implementation is used, however, then a WeakHashtable alone can be insufficient to allow garbage collection of a classloader without a call to release. If the abstract class LogFactory is loaded by a parent classloader and a concrete subclass implementation of LogFactory is loaded by a child classloader, the WeakHashtable's key is a weak reference to the TCCL (child classloader), but the value is a strong reference to the LogFactory instance, which in turn contains a strong reference to its class and thus loading classloader - the child classloader. This chain of strong references prevents the child loader from being garbage collected.

If use of a custom LogFactory subclass is desired, ensuring that the custom subclass is loaded by the same classloader as LogFactory will prevent problems. In normal deployments, the standard implementations of LogFactory found in package org.apache.commons.logging.impl will be loaded by the same classloader that loads LogFactory itself, so use of the standard LogFactory implementation should not pose problems. Alternatively, use the provided ServletContextCleaner to ensure this reference is explicitly released on webapp unload.

JCL is designed to encourage extensions to be created that add functionality. Typically, extensions to JCL fall into two categories:

  • new Log implementations that provide new bridges to logging systems
  • new LogFactory implementations that provide alternative discovery strategies

When creating new implementations for Log and LogFactory, it is important to understand the implied contract between the factory and the log implementations:

  • Life cycle
    The JCL LogFactory implementation must assume responsibility for either connecting/disconnecting to a logging toolkit, or instantiating/initializing/destroying a logging toolkit.
  • Exception handling
    The JCL Log interface doesn't specify any exceptions to be handled, the implementation must catch any exceptions.
  • Multiple threads
    The JCL Log and LogFactory implementations must ensure that any synchronization required by the logging toolkit is met.

The minimum requirement to integrate with another logger is to provide an implementation of the org.apache.commons.logging.Log interface. In addition, an implementation of the org.apache.commons.logging.LogFactory interface can be provided to meet specific requirements for connecting to, or instantiating, a logger.

The default LogFactory provided by JCL can be configured to instantiate a specific implementation of the org.apache.commons.logging.Log interface by setting the property of the same name (org.apache.commons.logging.Log). This property can be specified as a system property, or in the commons-logging.properties file, which must exist in the CLASSPATH.

If desired, the default implementation of the org.apache.commons.logging.LogFactory interface can be overridden, allowing the JDK 1.3 Service Provider discovery process to locate and create a LogFactory specific to the needs of the application. Review the Javadoc for the LogFactoryImpl.java for details.

JCL is distributed with a very simple Log implementation named org.apache.commons.logging.impl.SimpleLog. This is intended to be a minimal implementation and those requiring a fully functional open source logging system are directed to Log4J.

SimpleLog sends all (enabled) log messages, for all defined loggers, to System.err. The following system properties are supported to configure the behavior of this logger:

  • org.apache.commons.logging.simplelog.defaultlog - Default logging detail level for all instances of SimpleLog. Must be one of:
    • trace
    • debug
    • info
    • warn
    • error
    • fatal
    If not specified, defaults to info.
  • org.apache.commons.logging.simplelog.log.xxxxx - Logging detail level for a SimpleLog instance named "xxxxx". Must be one of:
    • trace
    • debug
    • info
    • warn
    • error
    • fatal
    If not specified, the default logging detail level is used.
  • org.apache.commons.logging.simplelog.showlogname - Set to true if you want the Log instance name to be included in output messages. Defaults to false.
  • org.apache.commons.logging.simplelog.showShortLogname - Set to true if you want the last component of the name to be included in output messages. Defaults to true.
  • org.apache.commons.logging.simplelog.showdatetime - Set to true if you want the current date and time to be included in output messages. Default is false.
  • org.apache.commons.logging.simplelog.dateTimeFormat - The date and time format to be used in the output messages. The pattern describing the date and time format is the same that is used in java.text.SimpleDateFormat. If the format is not specified or is invalid, the default format is used. The default format is yyyy/MM/dd HH:mm:ss:SSS zzz.

In addition to looking for system properties with the names specified above, this implementation also checks for a class loader resource named "simplelog.properties", and includes any matching definitions from this resource (if it exists).

See the FAQ document on the commons-logging wiki site

commons-logging-1.1.3-src/src/site/xdoc/mail-lists.xml100664 22270 12145235706 20715 0ustartntn 0 0 Commons Logging Mailing Lists Commons Documentation Team

Commons Logging shares mailing lists with all the other Commons Components. To make it easier for people to only read messages related to components they are interested in, the convention in Commons is to prefix the subject line of messages with the component's name, for example:

  • [logging] Problem with the ...

Questions related to the usage of Commons Logging should be posted to the User List.
The Developer List is for questions and discussion related to the development of Commons Logging.
Please do not cross-post; developers are also subscribed to the user list.

Note: please don't send patches or attachments to any of the mailing lists. Patches are best handled via the Issue Tracking system. Otherwise, please upload the file to a public server and include the URL in the mail.

Please prefix the subject line of any messages for Commons Logging with [logging] - thanks!

Name Subscribe Unsubscribe Post Archive Other Archives
Commons User List

Questions on using Commons Logging.

Subscribe Unsubscribe Post mail-archives.apache.org markmail.org
www.mail-archive.com
news.gmane.org
Commons Developer List

Discussion of development of Commons Logging.

Subscribe Unsubscribe Post mail-archives.apache.org markmail.org
www.mail-archive.com
news.gmane.org
Commons Issues List

Only for e-mails automatically generated by the issue tracking system.

Subscribe Unsubscribe read only mail-archives.apache.org markmail.org
www.mail-archive.com
Commons Commits List

Only for e-mails automatically generated by the source control sytem.

Subscribe Unsubscribe read only mail-archives.apache.org markmail.org
www.mail-archive.com

Other mailing lists which you may find useful include:

Name Subscribe Unsubscribe Post Archive Other Archives
Apache Announce List

General announcements of Apache project releases.

Subscribe Unsubscribe read only mail-archives.apache.org markmail.org
old.nabble.com
www.mail-archive.com
news.gmane.org
commons-logging-1.1.3-src/src/site/xdoc/junit-report.xml100664 3135 12145235706 21260 0ustartntn 0 0 JUnit Test Results Commons Documentation Team

The Apache Commons Logging test cases make extensive use of sophisticated classloader configurations in order to simulate the behaviour of various containers. It is difficult to run these tests under Maven in the default "test" phase. As a consequence the tests are executed via the failsafe-plugin as part of the "integration-test" phase. The reports are available here.

commons-logging-1.1.3-src/src/site/xdoc/download_logging.xml100664 15466 12145235706 22165 0ustartntn 0 0 Download Commons Logging Commons Documentation Team

We recommend you use a mirror to download our release builds, but you must verify the integrity of the downloaded files using signatures downloaded from our main distribution directories. Recent releases (48 hours) may not yet be available from the mirrors.

You are currently using [preferred]. If you encounter a problem with this mirror, please select another mirror. If all mirrors are failing, there are backup mirrors (at the end of the mirrors list) that should be available.

[if-any logo][end]

Other mirrors:

The KEYS link links to the code signing keys used to sign the product. The PGP link downloads the OpenPGP compatible signature from our main site. The MD5 link downloads the checksum from the main site.

commons-logging-1.1.3-bin.tar.gz md5 pgp
commons-logging-1.1.3-bin.zip md5 pgp
commons-logging-1.1.3-src.tar.gz md5 pgp
commons-logging-1.1.3-src.zip md5 pgp

Older releases can be obtained from the archives.

commons-logging-1.1.3-src/src/site/xdoc/proposal.xml100664 7472 12145235706 20465 0ustartntn 0 0 Proposal for Logging Library Package

There is a great need for debugging and logging information inside of Commons components such as HTTPClient and dbcp. However, there are many logging APIs out there and it is difficult to choose among them.

The Logging package will be an ultra-thin bridge between different logging libraries. Commons components may use the Logging JAR to remove compile-time/runtime dependencies on any particular logging package, and contributors may write Log implementations for the library of their choice.

The package shall create and maintain a package that provides extremely basic logging functionality and bridges to other, more sophisticated logging implementations.

The package should :

  • Have an API which should be as simple to use as possible
  • Provide support for log4j
  • Provide pluggable support for other logging APIs

Non-goals:

  • This package will not perform logging itself, except at the most basic level.
  • We do not seek to become a "standard" API.

Logging relies on:

  • Java Development Kit (Version 1.1 or later)
  • Avalon Framework (compile-time dependency only unless this Log implementation is selected at runtime)
  • Avalon LogKit (compile-time dependency only unless this Log implementation is selected at runtime)
  • JDK 1.4 (compile-time dependency only unless this log implementation is selected at runtime).
  • Log4J (compile-time dependency only unless this Log implementation is selected at runtime)
  • Lumberjack (compile-time dependency only unless this Log implementation is selected at runtime)
  • CVS Repository - New directory logging in the jakarta-commons CVS repository.
  • Initial Committers - The list is provided below.
  • Mailing List - Discussions will take place on the general dev@commons.apache.org mailing list. To help list subscribers identify messages of interest, it is suggested that the message subject of messages about this component be prefixed with [Logging].
  • Bugzilla - New component "Logging" under the "Commons" product category, with appropriate version identifiers as needed.
  • Jyve FAQ - New category "commons-logging" (when available).

The initial committers on the Logging component shall be:

  • Morgan Delagrange
  • Rodney Waldhoff
  • Craig McClanahan
commons-logging-1.1.3-src/src/site/xdoc/troubleshooting.xml100664 46031 12145235706 22067 0ustartntn 0 0 Troubleshooting Guide Commons Documentation Team

Diagnostics is a feature introduced in JCL 1.1 as an aid to debugging problems with JCL configurations. When diagnostics are switched on, messages are logged to a stream (specified by the user) by the two main classes involved in discovery in JCL (LogFactory and LogFactoryImpl).

Diagnostics are intended to be used in conjunction with the source. The source contains numerous and lengthy comments. Often these are intended to help explain the meaning of the messages.

Diagnostic logging is intended only to be used when debugging a problematic configuration. It should be switched off for production.

Diagnostic logging is controlled through the system property org.apache.commons.logging.diagnostics.dest. Setting the property value to the special strings STDOUT or STDERR (case-sensitive) will output messages to System.out and System.err respectively. Setting the property value to a valid file name will result in the messages being logged to that file.

Diagnostics uses the concept of an Object ID (OID). This allows the identity of objects to be tracked without relying on useful toString implementations. These are of the form:

classname@system identity hash code

The system identity hash code is found by calling System.identityHashCode() which should uniquely identify a particular instance. The classname is usually the fully qualified class name though in a few cases, org.apache.commons.logging.impl.LogFactoryImpl may be shortened to LogFactoryImpl to increase ease of reading. For example:

sun.misc.Launcher$AppClassLoader@20120943
LogFactoryImpl@1671711

OIDs are intended to be used to cross-reference. They allow particular instances of classloaders and JCL classes to be tracked in different contexts. This plays a vital role in building up the understanding of the classloader environment required to diagnose JCL problems.

Each diagnostic message is prefixed with details of the relevant class in a standard format. This takes the form:

[class-identifier from ClassLoader OID]

ClassLoader OID is the OID of a classloader which loaded the class issuing the message. class-identifier identifies the object issuing the message.

In the case of LogFactory, this is just LogFactory. For example (line split):

[LogFactory 
   from sun.misc.Launcher$AppClassLoader@20120943] BOOTSTRAP COMPLETED

In the case of LogFactoryImpl, the prefix is the instance OID. This can be cross referenced to discover the details of the TCCL used to manage this instance. For example (line split):

[LogFactoryImpl@1671711 
   from sun.misc.Launcher$AppClassLoader@20120943] Instance created.

Understanding the relationships between classloaders is vital when debugging JCL. At various points, JCL will print to the diagnostic log the hierarchy for important classloaders. This is obtained by walking the tree using getParent. Each classloader is represented (visually) by an OID (to allow cross referencing) and the relationship indicated in child --> parent fashion. For example (line split for easy reading):

ClassLoader tree:java.net.URLClassLoader@3526198  
      --> sun.misc.Launcher$AppClassLoader@20120943 (SYSTEM) 
      --> sun.misc.Launcher$ExtClassLoader@11126876 
      --> BOOT

Represents a hierarchy with four elements ending in the boot classloader.

Whenever the LogFactory class is initialized, diagnostic messages about the classloader environment are logged. The content of each of these messages is prefixed by [ENV] to help distinguish them. The extension directories, application classpath, details of the classloader (including the OID and toString value) used to load LogFactory and the classloader tree for that classloader are logged.

Many Sun classloaders have confusing toString values. For example, the OID may be

sun.misc.Launcher$AppClassLoader@20120943

with a toString value of

sun.misc.Launcher$AppClassLoader@133056f

Other classloader implementations may give very useful information (such as the local classpath).

Finally, once initialization is complete a BOOTSTRAP COMPLETED message is issued.

LogFactoryImpl is the standard and default LogFactory implementation. This section obviously only applies to configurations using this implementation.

Before assigning a Log instance, LogFactory loads a LogFactory implementation. The content is prefixed by [LOOKUP] for each diagnostic message logged by this process.

The implementation used can vary per Thread context classloader (TCCL). If this is the first time that a Log has been requested for a particular TCCL a new instance will be created.

Information of particular interest is logged at this stage. Details of the TCCL are logged allowing the OID later to be cross-referenced to the toString value and the classloader tree. For example, the following log snippet details the TCCL (lines split):

[LogFactory from sun.misc.Launcher$AppClassLoader@20120943] 
    [LOOKUP] LogFactory implementation requested for the first time for context 
        classloader java.net.URLClassLoader@3526198
[LogFactory from sun.misc.Launcher$AppClassLoader@20120943] 
    [LOOKUP] java.net.URLClassLoader@3526198 == 'java.net.URLClassLoader@35ce36'
[LogFactory from sun.misc.Launcher$AppClassLoader@20120943] 
    [LOOKUP] ClassLoader tree:java.net.URLClassLoader@3526198 
        --> sun.misc.Launcher$AppClassLoader@20120943 (SYSTEM)  
          --> sun.misc.Launcher$ExtClassLoader@11126876 
            --> BOOT

The standard LogFactoryImpl issues many diagnostic messages when discovering the Log implementation to be used.

During discovery, environment variables are loaded and values set. This content is prefixed by [ENV] to make it easier to distinguish this material.

The possible messages issued during discovery are numerous. To understand them, the source should be consulted. Attention should be paid to the classloader hierarchy trees for the classloader used to load LogFactory and to the TCCL.

Some containers use a custom LogFactory implementation to adapt JCL to their particular logging system. This has some important consequences for the deployment of applications using JCL within these containers.

Containers known to use this mechanism:

Containers suspected to use this mechanism:

  • WebSphere Application Server (other versions).

The Apache Commons team would be grateful if reports were posted to the development list of other containers using a custom implementation.

An exception is thrown by JCL with a message similar to:

  The chosen LogFactory implementation does not extend LogFactory. Please check your configuration. 
  (Caused by java.lang.ClassCastException: The application has specified that a custom LogFactory 
  implementation should be used but Class 'com.ibm.ws.commons.logging.TrLogFactory' cannot be converted 
  to 'org.apache.commons.logging.LogFactory'. The conflict is caused by the presence of multiple 
  LogFactory classes in incompatible classloaders. Background can be found in 
  http://commons.apache.org/logging/tech.html. If you have not explicitly specified a custom
  LogFactory then it is likely that the container has set one without your knowledge. 
  In this case, consider using the commons-logging-adapters.jar file or specifying the standard 
  LogFactory from the command line. Help can be found @http://commons.apache.org/logging.
  

This is a WebSphere example so the name of the custom LogFactory is com.ibm.ws.commons.logging.TrLogFactory. For other containers, this class name will differ.

A custom LogFactory implementation can only be used if the implementation class loaded dynamically at runtime can be cast to the LogFactory class that loaded it. There are several ways in which this cast can fail. The most obvious is that the source code may not actually extend LogFactory. The source may be compatible but if the LogFactory class against which the source is compiled is not binary compatible then the cast will also fail.

There is also another more unusual way in which this cast can fail: even when the binary is compatible, the implementation class loaded at runtime may be linked to a different instance of the LogFactory class. For more information, see the tech guide.

This situation may be encountered in containers which use a custom LogFactory implementation. The implementation will typically be provided in a shared, high level classloader together with JCL. When an application classloader contains LogFactory, the implementation will be loaded from that higher level classloader. The implementation class will be linked to the LogFactory class loaded by the higher level classloader. Even if the LogFactory implementations are binary compatible, since they are loaded by different classloaders the two LogFactory Class instances are not equal and so the cast must fail.

The policy adopted by JCL in this situation is to re-throw this exception. Additional information is included in the message to help diagnosis. The reasoning behind this choice is that a particular LogFactory implementation has been actively specified and this choice should not be ignored. This policy has unfortunate consequences when running in containers which have custom implementations: the above runtime exception may be thrown under certain classloading policies without the user knowingly specifying a custom implementation.

There are various ways to fix this problem. Which fix is right depends on the circumstances.

If you are happy using another classloading policy for the application, select a classloading policy which ensures that LogFactory will be loaded from the shared classloader containing the custom implementation.

If you want to bypass the container adaption mechanism then set the appropriate system property to the default value when the container is started:

 -Dorg.apache.commons.logging.LogFactory=org.apache.commons.logging.impl.LogFactoryImpl
 

If you want to continue to use the default container mechanism then:

  • Find and replace the commons-logging implementation used by the container with the most modern release
  • Replace the commons-logging jar in the application with the commons-logging-adapters jar. This will ensure that application classloader will delegate to it's parent when loading LogFactory.

If you encounter difficulties when applying the fixes recommended, please turn on diagnostics and consult the logs.

Because commons-logging is such a fundamental library, some containers modify the way in which classloading behaves for commons-logging classes.

At the current date, Tomcat 5.5.16 is the current release. All releases from version 4.1.x through 5.5.16 have a startup process that places jarfile ${tomcat.home}/bin/commons-logging-api.jar in the system classpath and then prevents any webapp from overriding the classes in that jarfile. Effectively, all webapps behave as if "parent-first" classloading were enabled for those classes.

This has some benefits; in particular it means that there are no problems in these Tomcat versions with having multiple copies of the commons-logging Log interface in the classpath (which avoids the "Log does not implement Log" problem described elsewhere).

However it also means that no webapp can override the core commons-logging classes by including an updated commons-logging jarfile in WEB-INF/lib; any class already loaded via the container takes priority. In particular, as Tomcat bundles logging 1.0.4 only, the new diagnostics and memory-leak-prevention features of the 1.1 release will not be available unless the container's library version is updated.

Because the commons-logging-api.jar in the container does not contain any log-library-adapter classes, updated behaviour for these will be seen when logging 1.1 is bundled in WEB-INF/lib. In particular, the support for log4j's TRACE level will take effect without having to update the container.

If you do wish to update Tomcat's version of commons-logging, then you must use the commons-logging-1.1-api jar only, not the full jar. Classes in the webapp cannot override classes loaded from the system classpath set up during Tomcat's startup process, and logging adapters can only see their matching concrete logging library if that library is available in the same classpath. Bundling the full commons-logging jarfile (with adapters) into the system classpath therefore means that logging libraries (eg log4j) within WEB-INF/lib are not accessible.

Note that the behaviour described here only applies if the standard Tomcat startup process is run. When Tomcat is embedded in a larger framework (eg run embedded within an IDE) this may not apply.

The JBoss Application Server can be configured to prevent deployed code from overriding classes higher in the hierarchy, effectively forcing "parent-first" behaviour for selected classes. By default, commons-logging is in this list (at least for some JBoss versions starting with 4.0.2), and therefore including an updated version of commons-logging in WEB-INF/lib or similar will have no effect. See the JBoss classloading documentation for more details.

As more information becomes available on this topic, it may be added to the commons-logging wiki site.

commons-logging-1.1.3-src/src/site/xdoc/tech.xml100664 65122 12145235706 17565 0ustartntn 0 0 Technology Guide Commons Documentation Team

This guide is aimed at describing the technologies that JCL developers and expert users (and users who need to become experts) should be familiar with. The aim is to give an understanding whilst being precise but brief. Details which are not relevant for JCL have been suppressed. References have been included.

These topics are a little difficult and it's easy for even experienced developers to make mistakes. We need you to help us get it right! Please submit corrections, comments, additional references and requests for clarification by either:

TIA

This is intended to present a guide to the process by which Java bytecode uses bytecode in other classes from the perspective of the language and virtual machine specifications. The focus will be on deciding which bytecode will be used (rather than the mechanics of the usage). It focuses on facts and terminology.

The process is recursive: it is therefore difficult to pick a starting point. Sun's documentation starts from the perspective of the startup of a new application. This guide starts from the perspective of an executing application.

During this discussion, please assume that each time that class is mentioned, the comments applied equally well to interfaces.

This document is targeted at Java 1.2 and above.

(LangSpec 12.3.3) The bytecode representation of a class contains symbolic names for other classes referenced.

In practical development terms: If a class is imported (either explicitly in the list of imports at the top of the source file or implicitly through a fully qualified name in the source code) it is referenced symbolically.

(VMSpec 5.4.3) Resolution of a symbolic reference occurs dynamically at runtime and is carried out by the Java Virtual Machine. Resolution of a symbolic reference requires loading and linking of the new class.

Note: references are not statically resolved at compile time.

(VMSpec 2.17.2) Loading is the name given to the process by which a binary form of a class is obtained by the Java Virtual Machine. Java classes are always loaded and linked dynamically by the Java Virtual Machine (rather than statically by the compiler).

In practical development terms: This means that the developer has no certain knowledge about the actual bytecode that will be used to execute any external call (one made outside the class). This is determined only at execution time and is affected by the way that the code is deployed.

(VMSpec 2.17.3) Linking is the name used for combining the binary form of a class into the Java Virtual Machine. This must happen before the class can be used.

(VMSpec 2.17.3) Linking is composed of verification, preparation and resolution (of symbolic references). Flexibility is allowed over the timing of resolution. (Within limit) this may happen at any time after preparation and before that reference is used.

In practical development terms: This means that different JVMs may realize that a reference cannot be resolved at different times during execution. Consequently, the actual behaviour cannot be precisely predicted without intimate knowledge of the JVM (on which the bytecode will be executed). This makes it hard to give universal guidance to users.

(VMSpec 2.17.2) The loading process is performed by a ClassLoader.

(VMSpec 5.3) A classloader may create a class either by delegation or by defining it directly. The classloader that initiates loading of a class is known as the initiating loader. The classloader that defines the class is known as the defining loader.

In practical terms: understanding and appreciating this distinction is crucial when debugging issues concerning classloaders.

(VMSPEC 5.3) The bootstrap is the base ClassLoader supplied by the Java Virtual Machine. All others are user (also known as application) ClassLoader instances.

In practical development terms: The System classloader returned by Classloader.getSystemClassLoader() will be either the bootstrap classloader or a direct descendant of the bootstrap classloader. Only when debugging issues concerning the system classloader should there be any need to consider the detailed differences between the bootstrap classloader and the system classloader.

(VMSpec 5.3) At runtime, a class (or interface) is determined by its fully qualified name and by the classloader that defines it. This is known as the class's runtime package.

(VMSpec 5.4.4) Only classes in the same runtime package are mutually accessible.

In practical development terms: two classes with the same symbolic name can only be used interchangeably if they are defined by the same classloader. A classic symptom indicative of a classloader issue is that two classes with the same fully qualified name are found to be incompatible during a method call. This may happen when a member is expecting an interface which is (seemingly) implemented by a class but the class is in a different runtime package after being defined by a different classloader. This is a fundamental java language security feature.

(VMSpec 5.3) The classloader which defines the class (whose reference is being resolved) is the one used to initiate loading of the class referred to.

In practical development terms: This is very important to bear in mind when trying to solve classloader issues. A classic misunderstanding is this: suppose class A defined by classloader C has a symbolic reference to class B and further that when C initiates loading of B, this is delegated to classloader D which defines B. Class B can now only resolve symbols that can be loaded by D, rather than all those which can be loaded by C. This is a classic recipe for classloader problems.

  • VMSpec The Java Virtual Machine Specification, Second Edition
  • LangSpec The Java Language Specification, Second Edition

When asked to load a class, a class loader may either define the class itself or delegate. The base ClassLoader class insists that every implementation has a parent class loader. This delegation model therefore naturally forms a tree structure rooted in the bootstrap classloader.

Containers (i.e. applications such as servlet engines or application servers that manage and provide support services for a number of "contained" applications that run inside of them) often use complex trees to allow isolation of different applications running within the container. This is particularly true of J2EE containers.

When a classloader is asked to load a class, a question presents itself: should it immediately delegate the loading to its parent (and thus only define those classes not defined by its parent) or should it try to define it first itself (and only delegate to its parent those classes it does not itself define). Classloaders which universally adopt the first approach are termed parent-first and the second child-first.

Note: the term child-first (though commonly used) is misleading. A better term (and one which may be encountered on the mailing list) is parent-last. This more accurately describes the actual process of classloading performed by such a classloader.

Parent-first loading has been the standard mechanism in the JDK class loader, at least since Java 1.2 introduced hierarchical classloaders.

Child-first classloading has the advantage of helping to improve isolation between containers and the applications inside them. If an application uses a library jar that is also used by the container, but the version of the jar used by the two is different, child-first classloading allows the contained application to load its version of the jar without affecting the container.

The ability for a servlet container to offer child-first classloading is made available, as an option, by language in the servlet spec (Section 9.7.2) that allows a container to offer child-first loading with certain restrictions, such as not allowing replacement of java.* or javax.* classes, or the container's implementation classes.

Though child-first and parent-first are not the only strategies possible, they are by far the most common. All other strategies are rare. However, it is not uncommon to be faced with a mixture of parent-first and child-first classloaders within the same hierarchy.

The class loader used to define a class is available programmatically by calling the getClassLoader method on the class in question. This is often known as the class classloader.

Java 1.2 introduces a mechanism which allows code to access classloaders which are not the class classloader or one of its parents. A thread may have a class loader associated with it by its creator for use by code running in the thread when loading resources and classes. This classloader is accessed by the getContextClassLoader method on Thread. It is therefore often known as the context classloader.

Note that the quality and appropriateness of the context classloader depends on the care with which the thread's owner manages it.

The Javadoc for Thread.setContextClassLoader emphasizes the setting of the context classloader as an aspect of thread creation. However, in many applications the context classloader is not fixed at thread creation but rather is changed throughout the life of a thread as thread execution moves from one context to another. This usage of the context classloader is particularly important in container applications.

For example, in a hypothetical servlet container, a pool of threads is created to handle HTTP requests. When created these threads have their context classloader set to a classloader that loads container classes. After the thread is assigned to handle a request, container code parses the request and then determines which of the deployed web applications should handle it. Only when the container is about to call code associated with a particular web application (i.e. is about to cross an "application boundary") is the context classloader set to the classloader used to load the web app's classes. When the web application finishes handling the request and the call returns, the context classloader is set back to the container classloader.

In a properly managed container, changes in the context classloader are made when code execution crosses an application boundary. When contained application A is handling a request, the context classloader should be the one used to load A's resources. When application B is handling a request, the context classloader should be B's.

While a contained application is handling a request, it is not unusual for it to call system or library code loaded by the container. For example, a contained application may wish to call a utility function provided by a shared library. This kind of call is considered to be within the "application boundary", so the context classloader remains the contained application's classloader. If the system or library code needs to load classes or other resources only visible to the contained application's classloader, it can use the context classloader to access these resources.

If the context classloader is properly managed, system and library code that can be accessed by multiple applications can not only use it to load application-specific resources, but also can use it to detect which application is making a call and thereby provided services tailored to the caller.

In practice, context classloaders vary in quality and issues sometimes arise when using them. The owner of the thread is responsible for setting the classloader. If the context classloader is not set then it will default to the system classloader. Any container doing so will cause difficulties for any code using the context classloader.

The owner is also at liberty to set the classloader as they wish. Containers may set the context classloader so that it is neither a child nor a parent of the classloader that defines the class using that loader. Again, this will cause difficulties.

Introduced in Java J2EE 1.3 is a requirement for vendors to appropriately set the context classloader. Section 6.2.4.8 (1.4 text):

This specification requires that J2EE containers provide a per thread context class loader for the use of system or library classes in dynamically loading classes provided by the application. The EJB specification requires that all EJB client containers provide a per thread context class loader for dynamically loading system value classes. The per thread context class loader is accessed using the Thread method getContextClassLoader. The classes used by an application will typically be loaded by a hierarchy of class loaders. There may be a top level application class loader, an extension class loader, and so on, down to a system class loader. The top level application class loader delegates to the lower class loaders as needed. Classes loaded by lower class loaders, such as portable EJB system value classes, need to be able to discover the top level application class loader used to dynamically load application classes. We require that containers provide a per thread context class loader that can be used to load top level application classes as described above.

This specification leaves quite a lot of freedom for vendors. (As well as using unconventional terminology and containing the odd typo.) It is a difficult passage (to say the least).

Reflection cannot bypass restrictions imposed by the java language security model, but, by avoiding symbolic references, reflection can be used to load classes which could not otherwise be loaded. Another ClassLoader can be used to load a class and then reflection used to create an instance.

Recall that the runtime packaging is used to determine accessibility. Reflection cannot be used to avoid basic java security. Therefore, the runtime packaging becomes an issue when attempting to cast classes created by reflection using other class loaders. When using this strategy, various modes of failure are possible when common class references are defined by the different class loaders.

Reflection is often used with the context classloader. In theory, this allows a class defined in a parent classloader to load any class that is loadable by the application. In practice, this only works well when the context classloader is set carefully.

JCL takes the view that different context class loader indicate boundaries between applications running in a container environment. Isolation requires that JCL honours these boundaries and therefore allows different isolated applications to configure their logging systems independently.

Performance dictates that symbolic references to these classes are present in the calling application code (reflection would simply be too slow). Therefore, these classes must be loadable by the classloader that loads the application code.

Performance dictates that symbolic references to the logging systems are present in the implementation classes (again, reflection would simply be too slow). So, for an implementation to be able to function, it is necessary for the logging system to be loadable by the classloader that defines the implementing class.

However, there is actually no reason why LogFactory requires symbolic references to particular Log implementations. Reflection can be used to load these from an appropriate classloader without unacceptable performance degradation. This is the strategy adopted by JCL.

JCL uses the context classloader to load the Log implementation.

commons-logging-1.1.3-src/src/site/xdoc/index.xml100664 14146 12145235706 17751 0ustartntn 0 0 Overview Commons Documentation Team

When writing a library it is very useful to log information. However there are many logging implementations out there, and a library cannot impose the use of a particular one on the overall application that the library is a part of.

The Logging package is an ultra-thin bridge between different logging implementations. A library that uses the commons-logging API can be used with any logging implementation at runtime. Commons-logging comes with support for a number of popular logging implementations, and writing adapters for others is a reasonably simple task.

Applications (rather than libraries) may also choose to use commons-logging. While logging-implementation independence is not as important for applications as it is for libraries, using commons-logging does allow the application to change to a different logging implementation without recompiling code.

Note that commons-logging does not attempt to initialise or terminate the underlying logging implementation that is used at runtime; that is the responsibility of the application. However many popular logging implementations do automatically initialise themselves; in this case an application may be able to avoid containing any code that is specific to the logging implementation used.

The Release Notes document the new features and bug fixes that have been included in the latest release.

The JavaDoc API documents for the latest release are available online. In particular, you should read the package overview of the org.apache.commons.logging package. In addition, there is a (short) User Guide.

The Wiki site has the latest updates, an FAQ and much other useful information.

Users needing to become experts or wanting to help develop JCL should (in addition) consult the Tech Guide. This gives short introductions to topics such as advanced class loading.

Binary and source distributions are available here.

The 1.1.3 release only updates the Bundle-SymbolicName in the manifest to "org.apache.commons.logging".

For a full list of changes since the 1.1.1 release, please refer to the change-report.

The 1.1.2 release is a packaging of bug fixes since release 1.1.1.

For the full details, see the release notes for this version.

This release is a minor update to the 1.1 release that fixes a number of bugs, and resolves packaging issues for maven 1.x and maven 2.x users.

For the full details, see the release notes for this version.

This release makes several changes that are intended to resolve issues that have been encountered when using commons-logging in servlet containers or j2ee containers where complex classpaths are present and multiple copies of commons-logging libraries are present at different levels.

This release also adds support for the TRACE level added to log4j in the 1.2.12 release. In former commons-logging versions, the log.trace method caused log4j to output the message at the DEBUG level (the lowest level supported by log4j at that time).

For the full details, see the release notes for this version.

Note: the 1.0.5 release was abandoned at alpha status.

The next JCL release will be designated 1.1 since we feel this more accurately reflects the improvements made to the codebase.

The 1.0.4 release of commons-logging is a service release containing support for both the 1.2.x and 1.3.x series of Log4J releases.

The 1.0.3 release is primarily a maintenance and code cleanup release with minimal new features.

The 1.0.2 release is a packaging of bug fixes since release 1.0.1.

The 1.0.1 release is a packaging of bug fixes and minor enhancements since release 1.0.

Regular builds of the current SVN HEAD code are made available. See the wiki for details.

commons-logging-1.1.3-src/src/site/xdoc/building.xml100664 5033 12145235706 20412 0ustartntn 0 0 Building Commons Documentation Team

Commons Logging uses Maven 2.0.x as its primary build system. Ant can also be used.

To build the full website, run

mvn site

The result will be in the target/site folder. You must be online and using JDK 1.4 or higher to successfully complete this target.

To build the jar files, run

mvn package

The resulting 4 jar files will be in the target folder. You must use JDK 1.4 or higher to successfully complete this target.

To create a full distribution, run

mvn clean site assembly:assembly

The resulting .zip and .tar.gz files will be in the target folder. You must use JDK 1.4 or higher to successfully complete this target.

Further details can be found in the commons build instructions.

We still use Ant to test the artifacts built my Maven. Please follow the instructions in the file build-testing.xml.

Note: A 1.2 JDK is needed to run the tests.

commons-logging-1.1.3-src/src/site/site.xml100664 4576 12145235706 16637 0ustartntn 0 0 Commons Logging /images/logo.png http://commons.apache.org/logging/ commons-logging-1.1.3-src/src/media/logo.xcf100664 51763 12145235705 16745 0ustartntn 0 0 gimp xcf file,dBB/ gimp-commentCreated with The GIMP¦ K%64aRT, Text Layer#2ÿ     ‰/O,k 3 ?,ƒk ¸   ý89ú8qÆÿª6ýqªÿÿþª6Uþÿÿþª9þÿÿþª9þUÿÿþª9þUÿÿþª9þUÿÿþª9þUÿÿþª9þUÿÿþª9þUÿÿþª9þUÿÿþª þ8UUþUþ8þUÿÿþª ý8ªÿÿý8 úªÿÆÆÿÿüªq8 þUÿÿþªõÆÿâqUÆÿÿþ ûUÿâ8þªÿÿþªþUÿÿþªúâÿâþªÿÿýâûUÿÿqþªÿÿªþqþUÿÿþªúâÿÿ8þªÿÿþÆþÿÿþÿÿþ þUÿÿþªûÆÿÿÆþâÿÿþþÿÿþÆÿÿþU þUÿÿþªþ8ÿÿþUþqÿÿþÿþâþqÿÿþª þUÿÿþªþªÿÿþþÿÿþqÿþ8ÿÿþª þUÿÿþªÿ þÆÿÿþªþUÿÿÿþªþUþUÿÿþªþ8ÿÿ þªÿÿÿþ8ÿþ þUÿÿþªþUÿÿ þUÿÿþâÿÿþÿþ8 þUÿÿþªþUÿÿþ þUÿÿþqÿÿþâû8ÿÿâ þUÿÿþªþUÿÿþU þUÿÿþªÿÿþªûªÿÿ8 þUÿÿþªþÿÿþq þUÿÿþÆþÿÿ÷ª8ªÿâU þUÿÿþªÿþª þUÿÿþþ8ÿÿý þUÿÿþªþªÿÿ þªÿÿþ8øªÆUU8þUÿÿþªþ8ÿÿþqûÆÿÿÆüªªþUÿÿþªþªÿÿþâþÿÿþ8üâÿþUÿÿþªýâÿÿþqûªÿÿUûÿÿ8þUÿÿþªýâÿÿþUûUÿÿqÿªþqUUþ þÆÿÿþýªÿÿö88ªÿâUþÆÿ ÿýÆüUâÿÿûâªUý8ªÿÿýâq ýÿ ÿþ8 Uþþ8UUûªqªªÿþâ,ü⪠ú8qâÿ8*ûUÿâ üÿUþU$û8ÿÿq ýÿUý8ÿ$ûâÿÿU ü8ÿýâÿ#þ8ÿÿþ ýÆü8ÿÿ#þUÿÿþq û8ââüUÿÿ$ÿüâqUøUqÆÿâÿ%þUÿ ÿþýUÿ%ý8Æÿ ÿýþ8'ü8ÆÿÿªþU    üqªq:þÿÿþ9ÿ:þâÿÿþâ9þUÿÿþU:üUiUþ8þ8 ý8UúªÿÆÆÿÿüªq8 ûUªÿÿ÷Uªÿªÿÿýâq ûUÿâ8þªÿÿùªUªÿÿüqªÿÿûª8âÿÿþqùUÿÿqþªÿÿªøqqªªâÿÿü8qªÿÿ÷ªUÿÆqUqâÿÿþüâÿÿþÿÿþþ8ÿÿþÿÿüâÿqþÆÿÿþüÆÿÿÿþÆÿÿþUÿþUÿÿþUþUÿÿþÆþ8ÿÿþâþqÿÿþªÿþUÿÿþªÿþªÿÿþ8ÿÿþªÿþUÿÿþªÿþªÿÿÿþªÿþUÿÿþªÿÿþ8ÿþÿþUÿÿþªÿûªÿÿâÿÿþÿþ8ÿþUÿÿþªÿûÿÿqÿÿþâû8ÿÿâÿþUÿÿþªÿúÿÿªÿÿþªûªÿÿ8ÿþUÿÿþªÿúUÿÿÿ÷ª8ªÿâU ÿþUÿÿþªÿþUþ8ÿÿý ÿþUÿÿþªÿ øªÆUU8 ÿþUÿÿþªÿ üªªÿþUÿÿþªÿúqâÿÿþUÿÿþªÿùÿÿÿ8ÿþUÿÿþªÿþ8ÿÿªþqUUþþÿÿþUÿÿþªþÿÿûªÿÿÆÿ ÿýÆþqÿÿþqþÆÿÿþâþqÿÿþqúqÿÿÿ ÿþ8üUqªÿÿøªq8UÆÿÿøâ8UªÿÿýªUøqâªqªªÿþâ Uü8UUü8UUûq⪠ú8qâÿ8)úªâÿâ üÿU'ùâÿUÿq ýÿU'ùâÿÆÿU ü8ÿ&øÿÿªÿ ýÆ'÷âÿÿâÿÿq û8ââ'ÿþªÿÿüâqUøUqÆÿâ(þªÿÿþ*ýâÿÿþÆÿ ÿý,÷ÿÿ8ÆÿÿªþU1þqÀÀÀ³þ8UU ûââªÿÿüÆUüâÿqþUÿÿþÆþUÿÿþƪªýÿUþÆÿÿþqýÿUþqÿÿþªýÿ8þÿÿýÿUþâÿÿýÿUþªÿÿýÿûªÿÿâýÿâûªÿÿÿþ8ûâÿÿ8ÿýâûUÿÿôâÿÿâUqÿÿýÆÿÿýÆ8ûUâUUUýâ þq þ ÿþƪªþUUþ8 ÿûâUÿ ÿûÆUªªþâÿÿý8úUÆÿ ýƪ ª ýâq ûqâöªÿUÿUUùªÿÿUÿ ÿýÆÿýÆ8þªÿÿûƪqH$ œ8Drop-Shadow#2h     ‡- õœ8 %%*œ8 )Ô ª‰6ô1ñ  /ð %(% .î  -9CFA4$ -î  1DWeh`L4-î '>Xqƒˆ|bB&-î *Cb€—qL+-î %?`ƒž§šzR..ï7Yžªž}T0.ï /Ryš©ž~U0/ð*Lt—§~U0ûû üüð(Iq•¦~U0 ø  ù ù  ÷ ð'Hq”¥~U1 í  ì  Ú&Hp”¥~U1   %(+-.-+& ë "&)+--+(#Ã&Hp”¥~U1  '/48:=@CED@8,  "+157;@EIJGA:2) Ã&Hp”¥~U1  %3>DFEEFJPW\\UH8& +8AEDCFMXcjkf\OA2Ã&Hp”¥~U1  )(%6Uy”™†c?$3T{›§›}W4Ã&Hp”¥~V3 0Pt‘š‹lF' )Hn’©©”pK2,=]ƒ¡Œg@#*Jq’¡—xQ/Ã&Hp”¥~W4"$9\‚¡iB" ]‚Ÿ¦–uN/(Cg…’‡jE&Ã&Hp”¥~W6%*Dk’««’jA!.R| °§ˆ`?08Tx–£š~[<(#.Gfˆ{]< Ã&Hp”¥~W6&+Em”®¯–oE$+Nxœ®¦ˆ_=+/Fg†™™‡jM92:NfxzjN0Ã&Hp”¥~W6%*Dk“®±›uK()Lu™«¢„\9%%7SrŠ“‹v^KCGTdlgU<#Ã&Hp”¥~W5$'?eŽ«³¡}S/ *Mu—¦œ|U3)A^x‡‡zhXPPV\[Q?* Ã&Hp”¥~V4"#8\…¥²¦†^8 -Pv•Ÿ‘qK+!5Phx{tgZRONMF:*Ã&Hp”¥~V40Pxš­©jD& 3Ux‘•ƒc?$ 4K`moh]SLGB<3( Ã(Ir•¦žW4&BfŠ¢§—wS3 !:ZyЇrR3&81)   /Pw˜¨ ƒ]9 %>]zŽ“‡pU=,#"*9Mbnn_G.";Yu…‡tjc^YTOH@7, €²5Uy—¥ž„`>%+C^u‚‚ubN>539DR]`XG1 %Ac”™”‹ƒ~{xtpjbWH7&"9VuŽ™“~_A(,BXhpneXLDACIOQL@0 %Bdƒ—Ÿž™•“’Ž‹†ueQ; #7Ogzƒ~nV>( ):JU[YTMGDCCB>5)  &A`{Ž––”““”€ˆ’Œ…xfN .@P]b_TD3"  !-8@CCA>:74/)  )B\p|~{{|~€‚‚€zmY  +5JPNûúôñ+Jj‡zbF0"÷#,7CIG%æ 1Sw—‹sXA1(#!"$(-5=CE@%æ 2Ty–¡›‰r]MC=:9;=@DFF@7%æ -Mq¡£š‹|oe^ZWVTSPKC8,%æ#>]{‘œž™‘ˆ€ysnib[QF9, %æ ,D^u…Ž‘ˆzri_SF8*&ç,?RbnvyzwrkbWL?2% &ç$1>IQVXVSME<2' 'è !(.2441-(! )ì  ,ù  ù1F_þ9üü4ô 2ò  1ò&151&0ð (]uu]>#/ð"fަ¤Ša: 5ZŸ¦–uN/(Cg…’‡jE& ;cŒ¥¥Œc; 'Hq•¦ž€W2 ;dŒ¥¥‹b; .Pw–£š~[<(#.Gfˆ{]<  ;cŒ¥¥Œc; 'Hq”¦~V1 ;cŒ¥¥‹c; %Cf†™™‡jM92:NfxzjN0  ;cŒ¥¥Œc; 'Hp”¥~U1 ;cŒ¥¥‹c; 3SrŠ“‹v^KCGTdlgU<# ;cŒ¥¥Œc; 'Hp”¥~U1 ;cŒ¥¥‹c;&@^x‡‡zhXPPV\[Q?*  ;cŒ¥¥Œc; 'Hp”¥~U1 ;cŒ¥¥Œc; 5Ohx{tgZRONMF:* ;cŒ¥¥Œc; 'Hp”¥~U1 ;cŒ¥¥Œc; 3K`moh]SLGB<3(  ;cŒ¥¥Œc; 'Hp”¥œ~U1 ;cŒ¥¥Œc; %;Sdkh_TKE?92*!  81)  !?g¨§Žg?! *Lt–§ž€X4!?g¨§Žf>!  :Yu…‡tjc^YTOH@7,  &Dk¨§jC&.Ov—§Ÿ‚[7%Cj§§iB$ %Ac”™”‹ƒ~{xtpjbWH8'-Jn¥¤lH,3Rw•£œ];#+Hl¤¤ŽkG)&&Bdƒ—Ÿž™•“’Ž‹†ueR<) 2Lkˆ™™‡jK1!#6RrŒ—‘z[='/Ii‡˜˜†hH-5!(A`{Ž––”““”€’Œ…xfO8' $2H`u‚‚u_F1#$4Kdx|jR:'!.D]ts\B,@*,C\p|~{{|~€‚‚€znZC/$$-;KYaaYJ9* +:2((3:><5,!%09>>90&F706H[gg]N@85568:=AHQZ\UD0  ""   !  ""D:9F[ovmZC0%!$*2>JPL>+  Û    ?9?Sm‚‡zbF0"ð#,7BHD6% üþýýÞ %86AZy‘˜‹sXA1(#!"$(-5=CD<.Þ(//=Y{–¢›‰r]MC=:9;=@DFF@4% ß($%4Pr¡£š‹|oe^ZWVTSPKC8)ß$'@^{‘œž™‘ˆ€ysnib[QF9+ à ,E^u…Ž‘ˆzri_SF8*  â ,?RbnvyzwrkbWL?2% !ã $1>IQVXVSME<2' #å !(.2441-(! %þì  ,ù  ù1n   rþü ù  öé  €ù !$(*,-,)%   )0469>CHJHC=5,#  %4?DDCDJT_hkh`TF8( &:LVVNFDKYl~‰Š‚r^I4!"9RejbQA;ASm‡›¡™…kP7" /MizzhO9.2Ec„Ÿ«¤mM2!=_}Œ…lL1"$6Uz›«¦iF* (HmŒ˜oK,*Ho’¦¢‰c>"-Ov•¡”sM,#?e‰Ÿ„^9 æ.Px™¥™yR0 :^‚˜–}X4 ç,Mt–¦ž[9!"9[}tP.ç&Dj¡Ÿ‰gF-#)>\y‡hF(ç8Z|•›ŽtV>36G_t{qW9ç +Hh„’~fPDEP_kj\D+ è 7Tpƒˆn]ROTZ]VE1è -F`t|xl^TPONI?0é ,CZiokaVNHD>7,  è 3K^iibXNGA;5-$ ç (A[nupf[RKF@:3+# æ2Ol€‡‚wme_[VQKC:0$¾ 8WwŽ˜–ކ€|yvqld[M=,"9Xy‘Ÿ›—”’‘Œˆ‚xkXC- #9Vs‰”—•““”€“‘‡}lV=%';Tjy|{{}€‚}s`H. !/DXfjf_YWWY[]_aeimk`L3 )>TdhaSE;65679;?EMW\XI35OhuraJ6(! #'/:FOOC0 @`|ˆjO7&!)4@GF;* HlŠ˜‘|`G5*$"!#&+2:BE@3# InŽ ŸycRF>;9:0" æ%=:4," &Å +7BJOTX\_^WI7%   -:CJOSWZ]]ZQE5% #1@LÄ &8HTZ\\]bkw€€u_D*  )bŒeD( ;e‘±¹§Q*=eŠ ƒ]9 &Bh‘³Á¸šoD$*Ky©Ì0V}–”zT0 )Lt”¡”rI'.T€£¯wK'*Mz¦Ãȳ‹\3 >m¡È Bm“£”oD"  3QlxoV7 >j˜µµ˜i<  8d•½ÏÅ¢rC  6f›Ä+S¤ª‘d8 0BJE5"'M~ªÀ·‘_2Ü)Q„³ÏÏ´…R) 3c™Â5b‘¯­\0è  $" /[Ž¸È·ŒX,Ý Cu¨ËÔ¿“^1 2b™Â ?o·¯ŠX,é   6e™Á̸‹V*Ý8ižÇÖÆh8 2b™Á !Gx¦½²ŠW+ê ;l¡ÇѺŒW+Ý1_•ÁÕÊ£n<2b™Á $L­Â¶ŽZ-ï >p¤ÊÔ¾Z-Þ,Y½Óʤp>2b™Á%N‚°Ç¼•a3î >o¤Ë××a2Þ*U‹ºÑÈ¢n<2b™Á %M±Êßl< ì ;k ÉØÉ j:Ý)TЏÎÃh8 2b™Á "I|­Ëʬ}K&ë 6c˜ÄØÎªvD Ü+V‹·Ê¼“_1 2b™Á Bs¦ÉÑ»‘a7 é 0YŒ»ÔÒ´ƒP(Û.[·Ä±†S) 2b™Á8g›ÃÔɨ{O- é !,/*)K|­ÍÓ¾“`3€5c”·¼¢uE! 2b™Á-WŠ·ÑÓ¾špJ. )7@?2" =išÀÐÅ¢rC!  @nš³¯Ž`6 2b™Â !Et¤ÇÖÏ·”pQ;-%#%,7EPQF2-S¬ÆÈ°†X1 *NzªšuJ&3c™Â3[гÎÖÍ·›gVLHJQZabXC+ m ÆÂ*Kr˜·ÊÑÏÆ»°¦ž˜…s[@' -LoŽ¢¤•|aI:35>Ocu|t]@% )Jw¥ÆÃ .Mp‘«½ÅÇĽ´ªw^C*  -Ig€†veWPPV_hleT<% !8X~¤¾× -Gd~“¢ª¬©¡”„oX?)  )?Vjvyume`]]î[SF4!  )A\z•¦é &:Napz~|uiYG4" Þ  1AOY]][WSNH@5( (<82+# +7AIMî !##  í   ö !$&ñ  ð ÷  ÷þþþ?   @þ þð ó Ç      !! €)   ! )&(4>DE@6(  ,8AFFA6) !(*% ,8AFD=2# PI:+%*8HYgqtoaM6#,=N^ksuoaM5  (6EOOE4'%-m¡ÆÑ½“`4  #5Y‡±Ëʰ…W2 3Y‡²ÌÍ´‹]6Ķ–nI, 6V~¤¾ÆºœuO1 6U}£½Ä¶—pL2%$.DeŒ®ÂÁ¬‰b?&&Ad‹®ÃıhEª¡‹mO5!(>Zy”§¬¤sU:&)>Zx”¦ª¡‹nR<0/9Lg„›©¨šcF-.Geƒœ©ªž†iL€zm[F1!'9Nbs~|q_K7&'9Nbs}€zm[I90/7EWiw~vgT?,,@Viw€ykXDNLF<1$)5@HMOMG?4')5@HMNLF=3*%$)1;DJNNJC9-  -:DJNNKE;0&%# !$&&Ã$  !$&&%# #%&&%" "%&&%#  ó  õ  ô  ü þþþþþ>   Aøþüí  ù  ù á  " ì   Ý   "$0;CGE>2# Ä #+17;=><7/&  $+.+"%1$ .Hf…Ÿ¯¯ž„mceo|‹šªµ¶acgn{§ºÀ±Ža6 %A`y„}kTA516CXr¡§„a?$1Mp–¶Êʸ›€nfejt„›²ÁOHEHTl®ÃÁ¤wG"  <`“yZ='&9Uw™°¶¦†^9)Di”»ÓÖã‚fTJHN_z»6)$&1Jp›½Ç³ˆU+ 1Wœ¢ŽjD' 7Z„©¿¾¦~R.4Z‰¶ÒÖÂuR:,'+;Y‚¬ 3ZŠµÈ¼•a3 #Fr™®¦…Y1 !@k˜¼É½šk? (M~¯ÎÒºb<#"@l&L®Èžj:1ZŠ®¸¤yJ$,T…±Ì˰‚Q*"ExªÊͱƒR+  1^‘  FxªÇÅ£p??m¼¾ o? à Bs¥ÈÒ¿•b5 Cu¨ÈÉ«zH" +W‹  Cv¨ÇƦsA &K}­ÇÁi8Ã5c˜ÂÔÉ£p? Cu§ÇȨvD )T‰  Bu§ÇƦtB",U‰·ÎÜf6Ã,WŒºÓέzG$!Cu§ÇǧuB (R‡  Bu§ÇǧtC#0[‘¾ÓÆžg6Ä&Nƒ´Ñв€L'!Cu§ÇǧuB (R‡  Bu§ÇǧtC#2^•ÂÖÊ¢l:Ä "H|¯Îг‚N("Cu§ÇǧuB (R‡  Bu§ÇǧuC#1^”Â×ͨs@ Ä Ex«Ìα€L'!Cu§ÇǧuB (R‡  Bu§ÇǧuC#/Y¾×Ѱ}I" à DwªÉʬzH$!Cu§ÇǧuB (R‡  Bu§ÇǧuC"*R‡·ÔÔ¸ˆS)à FyªÇÄ¢p@ Cu§ÇǧuB (R‡  Bu§ÇǧuC!$Hz¬ÎÖÁ•a3à $K~¬Ã»–c6 Bu§ÇǧuB (R‡  Bu§ÇǧuB 43:H\p|yfJ-  1X‡²Ë˰†X3 "@kš*'@cŠ­ÁÁ­Šb@& &@]x‹‘Š{j[QOS\eki[E- "=b‹®Â­Šc@'/Nuœ3!/Gd‚›¨¨š‚dG. "7Odsywpha^]]\WK:(  (Cc‚œ©©›‚dG/#7Sr0!-@Uhw~~vhU@-+=94.& *7CJNNJC:.!%2>G "%&&%"    á"%&&%"  $ ø ð ù ó  þüþþ?¤¤¤ þ üú  øú í  ù- ë &-13321/,)! ùU>' ÷)8BGHHõJKNNI<) á‚eE( 1FUZWRNMRZeljX< €Ä©Œf?  0LdmgXI@?GVj{~kI'À«„W/&Fh}|hL6)'0B\upN*ɾœm> 4[€„d@%+EaqhK)ÇÈ­~K$ ?k‘žf=  /I[XB%ÁÌ·ŠU* !Etœª™sI( 3CE5 ¼Ì½’\. EtŸ´ªŠc@'".0& á¹ÍÀ–`0 >lš·º¦†eH1!á·ÌÁ—a12\НÀ½ªsXA.!â¶ÌÁ˜b2%Gr›¸Äµ ‡lS=+ á¶ÌÁ˜b2 0S{ž¸ÅÈÀ°šfL5" €̶ÌÁ˜b2 5Ux˜±ÂÊȽ«“x[?' ¶ÌÁ™b24PnŒ¦ºÆÊŸ¢†eD(¶ÌÁ™b2 .D^z•¬½ÈÉÀ¬Œf@"¶ÌÁ™b2 %7Mg›²ÃÊĬ‡[3¶ÌÁ™b2 )-$$,=Xuˆ‡pM+ºÆ¾¤}U4$@b|„yeQB;;BPbquiP3 ¤¬§”xX;$3Mcli_TLHINV^`YH2|}sbL5""3AHIGDCCEHJJD9*âMOMH@4&"&()+-/121.' &æ$!   è  þ)p8 ,d Backgroundÿ     S,dS#SÏSÛSç,dSWScSoS{S‡S“SŸS«S·SÃÿÿÿÿÿÿÿÿÿÿÿÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ0ÿ0ÿ0ÿ–2K% commons-logging-1.1.3-src/src/media/logo.png100664 27742 12145235705 16751 0ustartntn 0 0 ‰PNG  IHDR,d³cš—bKGDÿÿÿ ½§“ pHYs  ÒÝ~ütIMEÔ )("q¤â IDATxœí]y|UòÝ3ÉLB…È$p]?œ¹&!†]W Gˆ’ˆ¬( Ê}©ë‚ xp r¸¬„S$ Q`¹WrbÝUDÈLŽ  $™\“L÷ïúMmåõd2 r$ö÷>a¦¦ºº^Õ;êÕ«'ȲÌT¨Pqë ÞjT¨ø½CuB*n1T'T¡âCuB*n1T'T¡âCuB*n1T'T¡âCuB*n1T'T¡âCuB*n1T'T¡âCuB*n1T'T¡âC{ý,¸s‚ üV¬®“[£h”y“ˆo„ 7N·¿­b¯_Q7HÕ-BóŽ2¥§§Ÿ>žãÜ([ø¹ÉdBhBsçÎ]²d‰ûMß²!7Ë–- hˆÛèÑ£úé§šššÚÚZ»Ý.I’$I ±Zºt© Vþþþ3f̸pá‚Íf«««sÍmÇŽ ðÃíÛ·Ûl¶ÚÚÚººº'N„‡‡+™ÆóçÏ×ÔÔsàÜÝ…!†„„”––Z­ÖêêêãÇ»èc~~~HLÅHKK›={¶Òâ­V«Õjýá‡жœbáÂ…eeeðvÜà©ÄäÉ“‘ìRÙF&“ … Û¶m[ee¥Õj-++Û¸qcHHe8jÔ(h&®sIJJJHHP*dË–-åååGŽa¹!lܸ±¼¼¼ªªÊf³9m}0 à›o¾©ªª‚¦/++;tèPhh(ò)//·Z­®ß·uÀ]'LJJ¦=þ¼Õj½víÚÕ«W/_¾\RRb±X‚ƒƒiK|òÉ'×®]«¨¨PjpÙ²eH¶uëÖòòrŽUqqqLL åZJ¹I’4{öì„„˜q>}ú4œ¿¿ÿôéÓ·lÙ²qãÆÉ“'s”óçÏ/))Ù´iü7..nÛ¶m›7oNLL|á… ƒ’¸´´´²²ý0<<õÔS>>>Œ1I’€­Ýnïׯ_rr2¾WNNÎ?þ¸zõê±cÇb·‚Ä=zôøæ›oŠ‹‹¸¨¨èñÇG]¡bc½{÷6™L@–œœìéé ³Y–A@ÅŠ¢xï½÷–••}ûí·@\^^žŸŸ½U,C_Êjµ~ðÁS¦Lñññ̓’$õèÑ#99)ívûàÁƒ±é5 °]¾|9øahhèðáÃABx­V  †ï¿ÿþ‡~˜6m†V«Åo[e„¦ñ}ÂG}þ˜6mZÇŽ«ªªPwÆÓÓS§Óétº»ï¾›[rüéOª¬¬ÄK–å9sæà·“&Mªªª‚•ƒ$IÐ ÀMï7wzë­·*++ébƒ9ÛÕèÛ·ïÂ… !Œ«0D­VëááÁMtûöíûÞ{ïœhµ( ]¢0ÆL&Suu5Šás°HJ9sæÌAƒÁr _Øzxx€Å#æÌ™ó—¿ü¥ªª èÁòP·AAAHY\\ €¨ÀV–åeË–¡ÆÆÆvèК ˜*V§Ó½ýöÛt¹wïÞ'NÀOjkkaÀQê^ ´Š½°F£ñðð ¥³†ÜÜ\|:‚¡™™™ø­,ËÀ„ôôô„É9íã”nMhÄ iëFGGcó³úºÛ¼y3Nèß{n;ÒèVZZ <¸ªª š\E]}èõúˆˆj+ÅÅÅëÖ­ƒÖE[Q†Â;uêTç€$I0xzzêõzooŽØf³Á{Q“õòòRÿüóG}â‰'8²ÂÂÂ×_ý§Ÿ~‚­K˜¶Öævå„ÜVÒ§Ÿ~Šñw’ `€FÀÅWÎ;G£ ¬áþ›ÚJß¾}YSÖo¿¸PlCIENqÓt+FÑÛ´iÓ£Gyóæ:tèᇦdEEE}ô—BÐ*ýЕvíÚ•þ7///77ÖczNrrò£>JûTÎ¥óòò•ks¡ ‘ÈÊïܹY†Åb±X,AC?¤Šíׯ_çÎo´Ž3fùòåÀŸ ¤ßsÏ=«V­úàƒ(ýÞ½{1Q±ÏK]9¡ÑhäzÙW^y¥  €f9;ýazzú£>úÙgŸQSàœðìÙ³è‡.:9nìá‡Hð½uG®ÝDhh(×L y×±+V_·QQQœbonÓÓÓQ$:/õññiÛ¶íèÑ£Ÿzê)$...†cšÔÚúÃFÖ„ÜÖªÅbyÿý÷óóó1RÙÆàááá!!!4Á*44”Ûl8|ø0ÄЉÓt§Ÿ~1àNºê„Œ1A¦NJ?9rädÕ¸ØÈ1›Í¸ÁØ¥K—qãÆ $[ÀéæûõC–åääd:™‚=-ðC_xáúšƒÚ‘´t¸rBAf̘Á%7:tè±ÇKOO§~ˆ]Ô²eËÂÃÃM&Ó¶mÛ`ç—&oÙ²…²Ú¾}{QQf:íç0ãÔ`0@$ Ó¦`ûQõCh&z„Åb±lݺ•ÛMmH±Œ18µHë4­ç·ÂòåË1ÝBvdMa†}Ïž=‘²OŸ>4µUƒÌ…ârkñâÅÜWÅÅÅqqqýû÷饗vìØ±cÇŽ¤¤¤Ù³gwëÖ +mÛ¶­sçÎô…쨕˜˜HY½üòË8Z*û9<Ãáçç—ššŠ‰˜5þ›tØ-º]áõEQܼy3=q²bÅŠ‚‚ì¹Á*ƒÀßü1„d`Pú­2T\8̪U«.]ºD7lVOOÏ«W¯"%L’¹^ëC##¡(Šñññ6lP~[XX¸víÚ'Ÿ|òñÇ;vìŠ+Àa6oÞ§Îp¿¦:ñññP"——7kÖ,š ŠÝvRR¸´¿¿ÿž={:uê$Ë2žŸ‚4è­¹u#séWôÀÐèO‹ÅõU£àˆQw`±X¸O@·ÝºuÛ¿?õÃ'Ÿ|Òd2ÑÉÀd2á­ÄÄÄaÆaR>è’éA(((p_0šäÈ+))Á¿9‡4›Í¯¾ú*ä©Ò>†b¨uÀ>|øøñã]'Tµ42å€.*..Ž;_ë~~~Ÿ|òÉ!CðÈŸ\?Í ´¿{÷n<zðàÁÈÈÈÕ«Wc oRRRDDĘ1ccF£qÿþý;w–È©ÆØ¡C‡À”»d²,sÄ‹åðáÃø-‡åË—Sâ¼¼<%gøƒcûé§Ÿ"ON%ñáÇÁ½¹y£¬8+ÈÛ€¬þN)4S·nÝöìÙ3lØ0|µ|ðÍ7ßLKKƒ>îäÉ“sæÌéÚµ«Édò÷÷ß´iÓðáÃÁ?qBˆ½› ~ø¡›/ŧ9Y}÷£~¸{÷î#FÀ¢†žNž;w.<466vÍš5˜,Þº×ÿÔ•'說ªÎŸ??iÒ$¬ ÁáÙgŸ0aT”`õœÑôQäVQQ±víÚ7bíPiÀ€xàl°étº/¾ø¢°°0%%…«ÃóõõíÓ§OLLÌ<ЫW/N—žžî”˜1öðÃ1¢Gƒ Òëõ.ˆ}}}rÏ=÷ôìÙ3'''+++%%…3AÆXŸ>}ú÷ïo4ÇŒãíííáá‘ššš‘‘¡´W`Ù³gOOOOÄ}úô2dH·nÝ"##{õê'îdY®«««®®®¬¬t¬8‚‰¢¨Óé@«p¢M»Ý¯ƒÊ¤Ñ æÈÎÇØ©F£A[j­gš¿‹Bp]‡cæ¢ãÌ;| ŽÄ\œ‚Ro¡Š£ÜðWtº^ºÕ; ŠÂÓ1ì‰1†ƒ#G`RD ½ºpÃ1pFby Â2GWâQ߈¢HYà¹@Œ}<°eޏ-5ä .J÷‡ +àŒg‚P±´-DG3,P‚2C§rÒGƒœ  ´pi ö`KËaS2Æ`Æ·F9±)Er´·/ ݺ†zfÁsgÛqŸ+_4´'iÀÛ¢ ÉSÜÛPK`̬\&åÕè ÌHœz° ‘+ÒSbOOOÊ™Û åa4ä8ýLv %1Z'÷‚¨%Ž30ç8sŠõððàr›h°Q©XÊòáäÄ—âäDï‚Þ ~Ný4Z­¥âÔ¬ÄúuZß,Ñ„ a°w¤i.4¾Lݯ¡® ƒ{ȇ†Ñ©r`Ž6£?‘è 48ÃD 1•Ÿi•ÄȇDF¦Ù8&0âÜ R¶”e@wA¬©j¦8“—Hz *–ê–óeCsi7ÊG³ú«\ZEb:€S{øŸ]mpíÞúд[™p ;âéIEÇCr­5™„Ú±IÐVXý1“Z å€Í))òB¨ÁQ £ôõtá ë¯`•Ä‚c‹å”냓Ù‡M˜ÚkCÄœ1ÒÇqºeЉþŠê¨ôå£9z§ZåæDÈP®¿ÿåÄk­îhÎÕhT_JÓtÇý”ܘ³‹F*%QÊÃêŸ"w‡ÿuj(Jb勸~…ßP`×*jè·Ü#Òm“š6ŸSE5d”3v.^ªõ¡™÷œúÌõ@)Œ›<} §Þò›»‰¦òäœ`6›ÍfsXX5V憖œ>Ñݺ¯«&iµÑqÄP??,,lÖ¬Yœ‡·/•UÜöHKKƒÌxÆX||<]ªÑõ^k½³qÖ¬YôîÇÖñú×5ª¸¡€îŸKFûÛäú±«Ö½jâ^ ïÒÁp”Ó€y B« û¶øûû'$$pw÷J’Tí½£w¦´>ªŸŸæ-àí`-ýõÝÚ'TqK Ër\\œ$I˜Æ]WWgµZ%Gl` Î.äh5X²d dó3ÆÞ|óÍŠŠ »Ý™429!ÐrCÕ okȲ,I=°[WWWVV&Ë2¤Ú1GªM‹¶B׈¿páÂñãÇûôéÓ®];tBÉ‘‘×Ò·òU'l s-»Ý#!¤ÑAöÒÿ–ø­ÎáÝ Cll,Ün¹xIc¯_s¬…¾¾ê„- ’$UUUI’•­¸ò @þ;¤±(e8ª…z S°E€Ûc”9îuäÜ[(ÞMæ¾Aj8LAñ’…=eªÞæH~»»·NÀ›Œ<¡šXhnµ˜Í‡ê„·5`2Æ9áHè¹ÍPÑÐ: Ž„*n,”ݼûzzºÉdG Çê•îç» a@–倀å…jîBÍã#8Òå=<<²³³ƒƒƒåúµ‹8…`rŸÓG'$$°úQœFå5ÒŸ»#vð›åÞ¨¸1$iÇŽØ^QQQÇŽ;xðàÑ£G³³³ÏŸ?ùòåÊÊJZ :--Mi+€™3g?~Ë~Úë—å`2™€Oxx8$Íâãã—,Y|¸:§Ü®ŸÏŽ;°Ú?Ö à*P˲œ””‚ä>»Ý~ñâÅY³fQ ,Y²~ÛhîÛìÙ³è]aaa3gÎܾ}»›¯ß(T'làœð›o¾9tèS'4™L`åK—.ýù矡êĶmÛŒF#2™>}:Ô¡Á¤¥é$%%Ÿ'N@Mššî.Џ¸8´iÎ1šÇçÒ¥KÔ÷PDä·Ùl/^\ºt)×éÄÅÅÕÔÔ;vŒ» ±xñb«ÕŠLhˆ `2™ SgéÒ¥(ö¶mÛ›1æfצ„:m=0›Í`=ÇŽƒJY6›M’¤èèèáÇ?õÔS_|ñclåÊ•;wîûì³ñãLJ††Nž<ÙÏϯ°°põêÕXñõ•W^:th@@Öda䀨Ùl8p ôhÓ§OÇ“Ê1117n¤·e„„„ Ð}}Áq|ÔɪšÀÝ””„y[QQQóæÍ«©©Ñh4mÛ¶mß¾}»víÚ´ic±X ÆúÍ7ßÓCñØ+?÷ÜsPk1´gÏ®‰ ˜® e¸°Úš$I……… @ÙÒÓÓ =>)ŠŠŠºwï~=| wÈÊÊ4hRH¤-ì— ‚ðâ‹/brŸŸŸ_AAÁo¼1qâD,€ Ërttô©S§€æ™gž™7o%£8p T»Ü¾}{ll,-¿L²³³É¼yóàbýbN+†4„–VR;v,x`XXX`` T4à=›uuu«W¯Æ²Ë§NzõÕW±ê&CӒǵµµÕÕÕÈÇf³uêÔ)(( Nœ8QZZZZZZVV|82ÉÌ̤bcE¼&máªNØ™™‰W,M™2<ê)ÂCtóÏ>û,þpÆ çÏŸëACÄk*üýý‘¸˜itt4rØ»wo¹V«,–…è„ÍãƒÅ¹íŽ’v«ÕŠ~…oÇ•ÕˆŠŠŠˆˆ£.Mï!=sæŒÕjEÏ©$IÂ×gŒùúú*59bÄ$Ø¿¿ÕjÅq·¸¹Ù|ª¶@^À€Ðn þ'sÜS¯ØØXúÛÝ»w£!b X€Ùl¦¬à+FCÇY–!RBíOªqe³ù8µcQ•Q%¤ä>ZÙôÀM±T, ÏP‚‹/"\ë Šb@@½óJ³âߌ£Uª¶|þùçøwÇŽÑnÀò°3/¿ûî»é<077*öÂÀÂ!F‹GÔjµt›9*ÓÝ¢(Ò KóøÐ@Jfw”V–ÉDY–ëêßÌ'8ªŒ+ŸXSSƒShI’èM!6› û\ˆzxxS&ð,¬aÝÔC-ª¶x`@ײ,〠 Ü=z”öåtŠÈËÈÈÀ*éè<Køúúb&s$yj4­ÃEcIDATn¢y|h¡D ÙYÑD Ê SÞt:··7%EüÞKC%ÏÎÎF±%r3ö pk-}jÀýŠª¶xp˜Áê v&„ú×9b8~ôèÑô'pN¨èµ°ûöíCeÄȯ!Á!ÖM¥®Þ<>´´)Âé #Š’ŒäÜ äæCè€8VÌQ]×–J±±&?sô(€RlZ¢ÚÍÁPuÂÖ¼ÌÖbAC¡?‘eF˜•=ÿüóøÕÁƒé¾cL„¬¬,øÖ`0 0mŽÛ%›1cÆõð¡2SiÝœéqN( WŒ†VzE|qqqnn.WјJ>lØ0ºA¡:áïß~û-]q!нAèÂfâĉ<ò|e±XæÏŸÏ™)ÆÖ®]«¬.80cÆŒQ£F5›O“LÙiz-"[å¯hò cÌ`0Ð{Ýß|óÍ’’‰àóÏ?‡MÿI“&^ØÕ [!ÐÿRú>}úõ‹óK’ôÉ'ŸLš4 ¾þúë·Þz+//¯®®Îl6?þóÏ?÷÷÷OLL ÈexJ[ß²e Ž«Må#6P~Ûé‡NA]Q$Y,SnŽ‹‹Û°al¨–””LŸ>ýÈ‘#0’¯Y³n­›:uê‚ ¨Ÿ7c" PÓÖZ?Œô‚ûq·¸»ÿtÕ [¦L™B÷å>ÿüóQ£FIŽ+¥èx(8”200°oß¾eee 'Š¢h±X^}õUF³sçNÈ8ñõõÕh4^^^555Ìq±™ä¸„œ.úÅà¡ EEE³gÏE±Ù|áf§7ÃC׬Y³råÊ]»vùøøX­Ö‡zdƒ,mØ\Á¬¼–“Žáî?QuÂÖ¸eý055uäÈ‘Üj’$A0Ðl6cŽÛ¼yóàKE1**Êl6Ÿ={V§ÓÁ¾‚à¸" n…Ñö!a烻è!§ü»ï¾ÓëõÍãs³Uɘ /½ôÒŠ+/^ܽ{w«Õ }`Z©ÌQô@Eè/hßÑÔ\ Ì´x€Å/^¼‡—/_NMM•Èuóvr÷ãœ9s€lÆ ýúõcŽÙ.ÆæÏŸC¥Åbñ°ÆôñW`|^^^p!6LÌ;rÊ‹‹‹1k§|n²>322 뵨¨HKnž¦W‚&aH±!‰ëƒÜ„:¶‚àïï¿oß¾¡C‡1ÆÖ¯_ïëë;tèPLÝ’$IÅ””HL{÷ÝwGŒu„EÇíËà!kÖ¬¶=ôc,::š†[áÌ‘(ŠÁÁÁþþþŽó`‚˜ ý׿þõzøàäùúÁ%68æ¯\¹råÊ•AAA;wÆDVƒÁb †œŽ6{ôVðv‡,ËôLÐ&MštÇw0Å•šÝºuÛ½{÷믿¾ÿ~ÆØ;ï¼óÃ?DGG?ðÀ6›íÛo¿]½zõÎ;Þ}÷ݘ˜˜ŠŠ ‰\ëóÀÐÐÐÌÌL|âž={¨<À’˜˜ØµkWº‚Ågxx8ž j6V?ŒÄûì³Ïbbb˜âFÄ?üiΜ9ã42ì«°°°;w" ž?Dlܸÿöóó{ûí·GÝÔu …z¨÷öErrrzzzrr2=WÎëܹó}÷Ý÷àƒ†„„üñ¼ãŽ;¼½½5Ýn¯ªª*//?qâDbbâÑ£G9†þþþÓ§OŸ6mšÝn‡|Q8<­½½½}||Ú´isùòåU«VÑ“âÀaaaÜ>¡Ùl^¾|9íAšÄ'55µ°°0--óÆØ Aƒî¿ÿþÀÀÀˆˆˆªªªsçέY³&##ƒÓÒ Aƒ|ðÁÐÐÐöíÛýõ×{öìIMMU²úóŸÿ‚S¶pGtäbÈäìÙ³gΜٺukqqqJJJhh(-QXXØl>Å>Œ±ºººšš«Õ gØ«««c^^^wÜqT÷Ðét¢(Â\Àjµ^»vÍjµÖÖÖŠ¢Ø¦MÔ/­©©©¨¨VUUU”8áO<‘™™ùå—_¶mÛh @Šclä”””äååmݺ577÷é§Ÿ~óÍ71M{"wüP]Þî?ÄÀ€ `—¢ãfÆ@|(Š"\€`:šnàÖ2ðððHMM;v¬¿¿ÿ¢E‹˜cA[ްÏ|@’=zôìÙsРA<òÈ… î¿ÿ~< ˜šš:nܸfóÑëõÎ… xMÁq¢1† fW£–ÀÉ¡Ñ8 ÌÐÓOÀ BAÌ‘'À+((6l˜ÙlÞ´iS—.]ÊËËYý´ØY±Û¶m9qâD³Ù\^^®×ë15=°Q?Tð¶Í#H)x»Ý;T´þ4Œ*à‡@LSˆõ½áêEã8é£Õj³³³ÇŽË›>}ºÁ`°Z­8j)í »óÎ;c0ÇãÎÉÉ7nclêÔ©]ºt©¨¨h€F£‘Ç…aÃÞ…ÆQ©káÎ| ãç H?GM:´  Àh4Ž9²ªªJp¤†‚Ò½[’¤N:I’é‚âHa£­¬:a ¶+Ü‚Y&0Ž¡õ`² vðD°Â°èÅ`#ÊÖÐëSu);¦˜L*59vìXºMÏ{â‰'úöí|Ï=÷`j(ä覦¦Â®cbbbLL ŠÍƒ…+Í¿sÝζ С±ý•ÜðmD²,'%%=öØcîK5mÚ´E‹a’*:á¾}ûðLpóøà<ÓM2e§/î´Ói”&???22Òý=z£Ñ¸yóæ.]ºÐ×g'ÉavÍGMànÀÙ£ÜØÐo•óO%e\\ÜÑ£GCBB•gêÔ©ßÿýÛo¿MsÄ™cq»wï^îÈ“ø‚ L½‹BE“1IÈ øúë¯wíÚ•““sîÜ9$:t¨F£‰‰‰yä‘Gp à6è` g³ÙNœ8ñÅ_4. alt<¹þׇ†êêêÿþ÷¿;wî„póP«Õ‚ØxÕ™@²ÒpÚL‹Äáž¾ûb«N¨â 7Œ¤ªêõzzù®èLé6è„×Éç¦y jº üªì 22`¢ät ÚŒŽC ̨àJ{}àî6Æ÷išÒþ~+>·êõ9É©RÉQx.Èä>T'Tá4§CðÊTåÜ âsóÁÉŒkBøåë_Oß<ÉU'TÑ hš_œj27Œï·âsóÒº›5}ô£PP…[PÚIóÌî·âs“áÔM~+Éÿ§oöýIIEND®B`‚././@LongLink100644 0 0 177 12145235757 10273 Lustar 0 0 commons-logging-1.1.3-src/src/test/resources/org/apache/commons/logging/tccl/log/props_disable_tccl/commons-logging.propertiescommons-logging-1.1.3-src/src/test/resources/org/apache/commons/logging/tccl/log/props_disable_tccl/100664 1637 12145235705 31644 0ustartntn 0 0 # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. use_tccl=false org.apache.commons.logging.Log=org.apache.commons.logging.tccl.custom.MyLog org.apache.commons.logging.diagnostics.dest=STDERR././@LongLink100644 0 0 176 12145235757 10272 Lustar 0 0 commons-logging-1.1.3-src/src/test/resources/org/apache/commons/logging/tccl/log/props_enable_tccl/commons-logging.propertiescommons-logging-1.1.3-src/src/test/resources/org/apache/commons/logging/tccl/log/props_enable_tccl/c100664 1620 12145235705 31622 0ustartntn 0 0 # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. org.apache.commons.logging.Log=org.apache.commons.logging.tccl.custom.MyLog org.apache.commons.logging.diagnostics.dest=STDERR././@LongLink100644 0 0 206 12145235757 10264 Lustar 0 0 commons-logging-1.1.3-src/src/test/resources/org/apache/commons/logging/tccl/logfactory/props_disable_tccl/commons-logging.propertiescommons-logging-1.1.3-src/src/test/resources/org/apache/commons/logging/tccl/logfactory/props_disabl100664 1577 12145235705 32006 0ustartntn 0 0 # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. use_tccl=false org.apache.commons.logging.LogFactory=org.apache.commons.logging.tccl.custom.MyLogFactoryImpl ././@LongLink100644 0 0 205 12145235757 10263 Lustar 0 0 commons-logging-1.1.3-src/src/test/resources/org/apache/commons/logging/tccl/logfactory/props_enable_tccl/commons-logging.propertiescommons-logging-1.1.3-src/src/test/resources/org/apache/commons/logging/tccl/logfactory/props_enable100664 1560 12145235705 31766 0ustartntn 0 0 # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. org.apache.commons.logging.LogFactory=org.apache.commons.logging.tccl.custom.MyLogFactoryImpl ././@LongLink100644 0 0 146 12145235757 10267 Lustar 0 0 commons-logging-1.1.3-src/src/test/resources/org/apache/commons/logging/jdk14/CustomConfig.propertiescommons-logging-1.1.3-src/src/test/resources/org/apache/commons/logging/jdk14/CustomConfig.propertie100664 2142 12145235705 31541 0ustartntn 0 0 # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # This is the custom configuration properties for the JDK 1.4 logger tests # in CustomConfigTestCase. # Configure the Handler so we can examine the logged messages handlers = org.apache.commons.logging.jdk14.TestHandler # Configre the default logging level to be FINE so we should get # everything except trace messages .level = FINE ././@LongLink100644 0 0 165 12145235757 10270 Lustar 0 0 commons-logging-1.1.3-src/src/test/resources/org/apache/commons/logging/config/priority10/commons-logging.propertiescommons-logging-1.1.3-src/src/test/resources/org/apache/commons/logging/config/priority10/commons-lo100664 1464 12145235705 31574 0ustartntn 0 0 # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. priority=10.5 configId=priority10 ././@LongLink100644 0 0 165 12145235757 10270 Lustar 0 0 commons-logging-1.1.3-src/src/test/resources/org/apache/commons/logging/config/nopriority/commons-logging.propertiescommons-logging-1.1.3-src/src/test/resources/org/apache/commons/logging/config/nopriority/commons-lo100664 1446 12145235705 31770 0ustartntn 0 0 # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. configId=nopriority ././@LongLink100644 0 0 166 12145235757 10271 Lustar 0 0 commons-logging-1.1.3-src/src/test/resources/org/apache/commons/logging/config/priority20a/commons-logging.propertiescommons-logging-1.1.3-src/src/test/resources/org/apache/commons/logging/config/priority20a/commons-l100664 1465 12145235705 31560 0ustartntn 0 0 # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. priority=20.6 configId=priority20a ././@LongLink100644 0 0 165 12145235757 10270 Lustar 0 0 commons-logging-1.1.3-src/src/test/resources/org/apache/commons/logging/config/priority20/commons-logging.propertiescommons-logging-1.1.3-src/src/test/resources/org/apache/commons/logging/config/priority20/commons-lo100664 1464 12145235705 31575 0ustartntn 0 0 # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. priority=20.6 configId=priority20 commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/impl/WeakHashtableTestCase.java100664 25732 12145235705 31175 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.logging.impl; import java.lang.ref.ReferenceQueue; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Collection; import java.util.Enumeration; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; import junit.framework.TestCase; public class WeakHashtableTestCase extends TestCase { private static final int WAIT_FOR_THREAD_COMPLETION = 5000; // 5 seconds private static final int RUN_LOOPS = 3000; private static final int OUTER_LOOP = 400; private static final int THREAD_COUNT = 10; private static WeakHashtable hashtable; /** Maximum number of iterations before our test fails */ private static final int MAX_GC_ITERATIONS = 50; private WeakHashtable weakHashtable; private Long keyOne; private Long keyTwo; private Long keyThree; private Long valueOne; private Long valueTwo; private Long valueThree; public WeakHashtableTestCase(String testName) { super(testName); } protected void setUp() throws Exception { super.setUp(); weakHashtable = new WeakHashtable(); keyOne = new Long(1); keyTwo = new Long(2); keyThree = new Long(3); valueOne = new Long(100); valueTwo = new Long(200); valueThree = new Long(300); weakHashtable.put(keyOne, valueOne); weakHashtable.put(keyTwo, valueTwo); weakHashtable.put(keyThree, valueThree); } /** Tests public boolean contains(Object value) */ public void testContains() throws Exception { assertFalse(weakHashtable.contains(new Long(1))); assertFalse(weakHashtable.contains(new Long(2))); assertFalse(weakHashtable.contains(new Long(3))); assertTrue(weakHashtable.contains(new Long(100))); assertTrue(weakHashtable.contains(new Long(200))); assertTrue(weakHashtable.contains(new Long(300))); assertFalse(weakHashtable.contains(new Long(400))); } /** Tests public boolean containsKey(Object key) */ public void testContainsKey() throws Exception { assertTrue(weakHashtable.containsKey(new Long(1))); assertTrue(weakHashtable.containsKey(new Long(2))); assertTrue(weakHashtable.containsKey(new Long(3))); assertFalse(weakHashtable.containsKey(new Long(100))); assertFalse(weakHashtable.containsKey(new Long(200))); assertFalse(weakHashtable.containsKey(new Long(300))); assertFalse(weakHashtable.containsKey(new Long(400))); } /** Tests public boolean containsValue(Object value) */ public void testContainsValue() throws Exception { assertFalse(weakHashtable.containsValue(new Long(1))); assertFalse(weakHashtable.containsValue(new Long(2))); assertFalse(weakHashtable.containsValue(new Long(3))); assertTrue(weakHashtable.containsValue(new Long(100))); assertTrue(weakHashtable.containsValue(new Long(200))); assertTrue(weakHashtable.containsValue(new Long(300))); assertFalse(weakHashtable.containsValue(new Long(400))); } /** Tests public Enumeration elements() */ public void testElements() throws Exception { ArrayList elements = new ArrayList(); for (Enumeration e = weakHashtable.elements(); e.hasMoreElements();) { elements.add(e.nextElement()); } assertEquals(3, elements.size()); assertTrue(elements.contains(valueOne)); assertTrue(elements.contains(valueTwo)); assertTrue(elements.contains(valueThree)); } /** Tests public Set entrySet() */ public void testEntrySet() throws Exception { Set entrySet = weakHashtable.entrySet(); for (Iterator it = entrySet.iterator(); it.hasNext();) { Map.Entry entry = (Map.Entry) it.next(); Object key = entry.getKey(); if (keyOne.equals(key)) { assertEquals(valueOne, entry.getValue()); } else if (keyTwo.equals(key)) { assertEquals(valueTwo, entry.getValue()); } else if (keyThree.equals(key)) { assertEquals(valueThree, entry.getValue()); } else { fail("Unexpected key"); } } } /** Tests public Object get(Object key) */ public void testGet() throws Exception { assertEquals(valueOne, weakHashtable.get(keyOne)); assertEquals(valueTwo, weakHashtable.get(keyTwo)); assertEquals(valueThree, weakHashtable.get(keyThree)); assertNull(weakHashtable.get(new Long(50))); } /** Tests public Enumeration keys() */ public void testKeys() throws Exception { ArrayList keys = new ArrayList(); for (Enumeration e = weakHashtable.keys(); e.hasMoreElements();) { keys.add(e.nextElement()); } assertEquals(3, keys.size()); assertTrue(keys.contains(keyOne)); assertTrue(keys.contains(keyTwo)); assertTrue(keys.contains(keyThree)); } /** Tests public Set keySet() */ public void testKeySet() throws Exception { Set keySet = weakHashtable.keySet(); assertEquals(3, keySet.size()); assertTrue(keySet.contains(keyOne)); assertTrue(keySet.contains(keyTwo)); assertTrue(keySet.contains(keyThree)); } /** Tests public Object put(Object key, Object value) */ public void testPut() throws Exception { Long anotherKey = new Long(2004); weakHashtable.put(anotherKey, new Long(1066)); assertEquals(new Long(1066), weakHashtable.get(anotherKey)); // Test compliance with the hashtable API re nulls Exception caught = null; try { weakHashtable.put(null, new Object()); } catch (Exception e) { caught = e; } assertNotNull("did not throw an exception adding a null key", caught); caught = null; try { weakHashtable.put(new Object(), null); } catch (Exception e) { caught = e; } assertNotNull("did not throw an exception adding a null value", caught); } /** Tests public void putAll(Map t) */ public void testPutAll() throws Exception { Map newValues = new HashMap(); Long newKey = new Long(1066); Long newValue = new Long(1415); newValues.put(newKey, newValue); Long anotherNewKey = new Long(1645); Long anotherNewValue = new Long(1815); newValues.put(anotherNewKey, anotherNewValue); weakHashtable.putAll(newValues); assertEquals(5, weakHashtable.size()); assertEquals(newValue, weakHashtable.get(newKey)); assertEquals(anotherNewValue, weakHashtable.get(anotherNewKey)); } /** Tests public Object remove(Object key) */ public void testRemove() throws Exception { weakHashtable.remove(keyOne); assertEquals(2, weakHashtable.size()); assertNull(weakHashtable.get(keyOne)); } /** Tests public Collection values() */ public void testValues() throws Exception { Collection values = weakHashtable.values(); assertEquals(3, values.size()); assertTrue(values.contains(valueOne)); assertTrue(values.contains(valueTwo)); assertTrue(values.contains(valueThree)); } /** * Disabled this test as it makes wrong assumptions wrt the GC. * This test especially fails with: * * Java(TM) SE Runtime Environment (build pxi3260sr12-20121025_01(SR12)) * IBM J9 VM (build 2.4, JRE 1.6.0 IBM J9 2.4 Linux x86-32 jvmxi3260sr12-20121024_1 */ public void xxxIgnoretestRelease() throws Exception { assertNotNull(weakHashtable.get(new Long(1))); ReferenceQueue testQueue = new ReferenceQueue(); WeakReference weakKeyOne = new WeakReference(keyOne, testQueue); // lose our references keyOne = null; keyTwo = null; keyThree = null; valueOne = null; valueTwo = null; valueThree = null; int iterations = 0; int bytz = 2; while(true) { System.gc(); if(iterations++ > MAX_GC_ITERATIONS){ fail("Max iterations reached before resource released."); } if(weakHashtable.get(new Long(1)) == null) { break; } else { // create garbage: byte[] b = new byte[bytz]; bytz = bytz * 2; } } // some JVMs seem to take a little time to put references on // the reference queue once the reference has been collected // need to think about whether this is enough to justify // stepping through the collection each time... while(testQueue.poll() == null) {} // Test that the released objects are not taking space in the table assertEquals("underlying table not emptied", 0, weakHashtable.size()); } public static class StupidThread extends Thread { public StupidThread(String name) { super(name); } public void run() { for (int i = 0; i < RUN_LOOPS; i++) { hashtable.put("key" + ":" + i%10, Boolean.TRUE); if(i%50 == 0) { yield(); } } } } public void testLOGGING_119() throws Exception { Thread [] t = new Thread[THREAD_COUNT]; for (int j=1; j <= OUTER_LOOP; j++) { hashtable = new WeakHashtable(); for (int i = 0; i < t.length; i++) { t[i] = new StupidThread("Thread:" + i); t[i].setDaemon(true); // Otherwise we cannot exit t[i].start(); } for (int i = 0; i < t.length; i++) { t[i].join(WAIT_FOR_THREAD_COMPLETION); if (t[i].isAlive()) { break; // at least one thread is stuck } } int active=0; for (int i = 0; i < t.length; i++) { if (t[i].isAlive()) { active++; } } if (active > 0) { fail("Attempt: " + j + " Stuck threads: " + active); } } } } commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/AltHashtable.java100664 2356 12145235705 26406 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.logging; import java.util.Hashtable; public class AltHashtable extends Hashtable { /** * Generated serial version ID. */ private static final long serialVersionUID = 8927996458633688095L; public static Object lastKey; public static Object lastValue; public Object put(Object key, Object value) { lastKey = key; lastValue = value; return super.put(key, value); } } commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/simple/CustomConfigTestCase.java100664 21043 12145235705 31411 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.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; /** *

TestCase for simple logging when running with custom configuration * properties.

* * @author Craig R. McClanahan * @version $Revision: 1432587 $ $Date: 2013-01-13 12:11:32 +0100 (Sun, 13 Jan 2013) $ */ public class CustomConfigTestCase extends DefaultConfigTestCase { // ----------------------------------------------------- Instance Variables /** *

The expected log records.

*/ protected List expected; /** *

The message levels that should have been logged.

*/ /* protected Level testLevels[] = { Level.FINE, Level.INFO, Level.WARNING, Level.SEVERE, Level.SEVERE }; */ /** *

The message strings that should have been logged.

*/ protected String testMessages[] = { "debug", "info", "warn", "error", "fatal" }; // ------------------------------------------- JUnit Infrastructure Methods /** * 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.simple.DecoratedSimpleLog"); System.setProperty( "org.apache.commons.logging.simplelog.defaultlog", "debug"); } /** * Set up instance variables required by this test case. */ public void setUp() throws Exception { LogFactory.releaseAll(); setProperties(); expected = new ArrayList(); setUpFactory(); setUpLog("DecoratedLogger"); } /** * Return the tests included in this test suite. *

* 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 initialisation 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 classloader. * Or we could fix SimpleLog to be sane... */ public static Test suite() throws Exception { Class thisClass = CustomConfigTestCase.class; PathableClassLoader loader = new PathableClassLoader(null); loader.useExplicitLoader("junit.", Test.class.getClassLoader()); loader.addLogicalLib("testclasses"); loader.addLogicalLib("commons-logging"); Class testClass = loader.loadClass(thisClass.getName()); return new PathableTestSuite(testClass, loader); } /** * Tear down instance variables required by this test case. */ public void tearDown() { super.tearDown(); expected = null; } // ----------------------------------------------------------- Test Methods // 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 public void testSerializable() throws Exception { ((DecoratedSimpleLog) log).clearCache(); logPlainMessages(); super.testSerializable(); logExceptionMessages(); checkExpected(); } // -------------------------------------------------------- Support Methods // 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? assertTrue(log.isDebugEnabled()); assertTrue(log.isErrorEnabled()); assertTrue(log.isFatalEnabled()); assertTrue(log.isInfoEnabled()); assertTrue(!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() { assertTrue(!((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() { List acts = ((DecoratedSimpleLog) log).getCache(); Iterator exps = expected.iterator(); int n = 0; while (exps.hasNext()) { LogRecord exp = (LogRecord) exps.next(); 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 protected void checkStandard() { checkDecorated(); } // Log the messages with exceptions protected void logExceptionMessages() { // Generate log records 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)); } } ././@LongLink100644 0 0 145 12145235757 10266 Lustar 0 0 commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/simple/DefaultConfigTestCase.javacommons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/simple/DefaultConfigTestCase.java100664 17141 12145235705 31527 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.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; /** *

TestCase for simple logging when running with zero configuration * other than selecting the SimpleLog implementation.

* * @author Craig R. McClanahan * @version $Revision: 1432587 $ $Date: 2013-01-13 12:11:32 +0100 (Sun, 13 Jan 2013) $ */ public class DefaultConfigTestCase extends TestCase { // ----------------------------------------------------- Instance Variables /** *

The {@link LogFactory} implementation we have selected.

*/ protected LogFactory factory = null; /** *

The {@link Log} implementation we have selected.

*/ protected Log log = null; // ------------------------------------------- JUnit Infrastructure Methods /** * Return the tests included in this test suite. *

* 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 initialisation 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 classloader. * Or we could fix SimpleLog to be sane... */ public static Test suite() throws Exception { Class thisClass = DefaultConfigTestCase.class; PathableClassLoader loader = new PathableClassLoader(null); loader.useExplicitLoader("junit.", Test.class.getClassLoader()); loader.addLogicalLib("testclasses"); loader.addLogicalLib("commons-logging"); 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. */ public void setUp() throws Exception { LogFactory.releaseAll(); setProperties(); setUpFactory(); setUpLog("TestLogger"); } /** * Tear down instance variables required by this test case. */ public void tearDown() { log = null; factory = null; LogFactory.releaseAll(); } // ----------------------------------------------------------- Test Methods // 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()); 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 ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos); oos.writeObject(log); oos.close(); ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bais); log = (Log) ois.readObject(); ois.close(); // Check the characteristics of the resulting object checkStandard(); } // -------------------------------------------------------- Support Methods // 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? assertTrue(!log.isDebugEnabled()); assertTrue(log.isErrorEnabled()); assertTrue(log.isFatalEnabled()); assertTrue(log.isInfoEnabled()); assertTrue(!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()); assertTrue(!((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? assertTrue(!log.isDebugEnabled()); assertTrue(log.isErrorEnabled()); assertTrue(log.isFatalEnabled()); assertTrue(log.isInfoEnabled()); assertTrue(!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(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(String name) throws Exception { log = LogFactory.getLog(name); } } ././@LongLink100644 0 0 154 12145235757 10266 Lustar 0 0 commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/simple/DateTimeCustomConfigTestCase.javacommons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/simple/DateTimeCustomConfigTestCa100664 7570 12145235705 31547 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.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. *

* 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 initialisation 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 classloader. * Or we could fix SimpleLog to be sane... */ public static Test suite() throws Exception { Class thisClass = DateTimeCustomConfigTestCase.class; PathableClassLoader loader = new PathableClassLoader(null); loader.useExplicitLoader("junit.", Test.class.getClassLoader()); loader.addLogicalLib("testclasses"); loader.addLogicalLib("commons-logging"); 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. */ 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. */ public void setUp() throws Exception { super.setUp(); } // ----------------------------------------------------------- Methods /** Checks that the date time format has been successfully set */ protected void checkDecoratedDateTime() { assertEquals("Expected date format to be set", "dd.mm.yyyy", ((DecoratedSimpleLog) log).getDateTimeFormat()); // try the formatter Date now = new Date(); DateFormat formatter = ((DecoratedSimpleLog) log).getDateTimeFormatter(); 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 */ protected void checkShowDateTime() { assertTrue(((DecoratedSimpleLog) log).getShowDateTime()); } } commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/simple/LogRecord.java100664 2403 12145235705 27214 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.logging.simple; import java.io.Serializable; public class LogRecord implements Serializable { /** * Generated serial version ID. */ private static final long serialVersionUID = -5254831759209770665L; public LogRecord(int type, Object message, Throwable t) { this.type = type; this.message = message; this.t = t; } public int type; public Object message; public Throwable t; } commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/simple/DecoratedSimpleLog.java100664 4675 12145235705 31057 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.logging.simple; import java.util.ArrayList; import java.util.List; import java.text.DateFormat; import org.apache.commons.logging.impl.SimpleLog; /** *

Decorated instance of SimpleLog to expose internal state and * support buffered output.

*/ public class DecoratedSimpleLog extends SimpleLog { // ------------------------------------------------------------ Constructor /** * Generated serial version ID. */ private static final long serialVersionUID = 196544280770017153L; public DecoratedSimpleLog(String name) { super(name); } // ------------------------------------------------------------- Properties public DateFormat getDateTimeFormatter() { return dateFormatter; } public String getDateTimeFormat() { return dateTimeFormat; } public String getLogName() { return logName; } public boolean getShowDateTime() { return showDateTime; } public boolean getShowShortName() { return showShortName; } // ------------------------------------------------------- Protected Methods // Cache logged messages protected void log(int type, Object message, Throwable t) { super.log(type, message, t); cache.add(new LogRecord(type, message, t)); } // ---------------------------------------------------------- Public Methods // Cache of logged records protected ArrayList cache = new ArrayList(); // Clear cache public void clearCache() { cache.clear(); } // Return cache public List getCache() { return this.cache; } } commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/avalon/AvalonLoggerTestCase.java100664 3202 12145235705 31335 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.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; /** * @author Neeme Praks * @version $Revision: 1432587 $ $Date: 2013-01-13 12:11:32 +0100 (Sun, 13 Jan 2013) $ */ public class AvalonLoggerTestCase extends AbstractLogTest { public static Test suite() { TestSuite suite = new TestSuite(); suite.addTestSuite(AvalonLoggerTestCase.class); return suite; } public Log getLogObject() { // Output does not seem to be used, so don't display it. Log log = new AvalonLogger(new NullLogger()); return log; } } commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/LoadTestCase.java100664 20761 12145235705 26405 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.logging; import junit.framework.TestCase; /** * testcase to emulate container and application isolated from container * @author baliuka * @version $Id: LoadTestCase.java 1432587 2013-01-13 11:11:32Z tn $ */ 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. *

* 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(ClassLoader parent){ super(parent); } private Class def(String name)throws ClassNotFoundException{ Class result = (Class)classes.get(name); if(result != null){ return result; } try{ ClassLoader cl = this.getClass().getClassLoader(); String classFileName = name.replace('.','/') + ".class"; java.io.InputStream is = cl.getResourceAsStream(classFileName); java.io.ByteArrayOutputStream out = new java.io.ByteArrayOutputStream(); while(is.available() > 0){ out.write(is.read()); } byte data [] = out.toByteArray(); result = super.defineClass(name, data, 0, data.length ); classes.put(name,result); return result; }catch(java.io.IOException ioe){ throw new ClassNotFoundException( name + " caused by " + ioe.getMessage() ); } } // not very trivial to emulate we must implement "findClass", // but it will delegete to junit class loder first public Class loadClass(String name)throws ClassNotFoundException{ //isolates all logging classes, application in the same classloader too. //filters exeptions to simlify handling in test for(int i = 0; i < LOG_PCKG.length; i++ ){ if( name.startsWith( LOG_PCKG[i] ) && 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(Class c, String state) throws Exception { Class[] params = {String.class}; java.lang.reflect.Method m = c.getDeclaredMethod("setAllowFlawedContext", params); m.invoke(null, new Object[] {state}); } /** * Test what happens when we play various classloader tricks like those * that happen in web and j2ee containers. *

* 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(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(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; AppClassLoader appLoader = new AppClassLoader( this.getClass().getClassLoader()); try{ testObjCls = appLoader.loadClass(UserClass.class.getName()); }catch(ClassNotFoundException cnfe){ throw cnfe; }catch(Throwable t){ t.printStackTrace(); fail("AppClassLoader failed "); } assertTrue( "app isolated" ,testObjCls.getClassLoader() == appLoader ); return testObjCls; } private void execute(Class cls)throws Exception{ cls.newInstance(); } public void setUp() { // save state before test starts so we can restore it when test ends origContextClassLoader = Thread.currentThread().getContextClassLoader(); } public void tearDown() { // restore original state so a test can't stuff up later tests. Thread.currentThread().setContextClassLoader(origContextClassLoader); } private ClassLoader origContextClassLoader; } ././@LongLink100644 0 0 145 12145235757 10266 Lustar 0 0 commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/pathable/ParentFirstTestCase.javacommons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/pathable/ParentFirstTestCase.java100664 33173 12145235705 31550 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.logging.pathable; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.Enumeration; import java.util.HashSet; import java.util.Set; import junit.framework.Test; import junit.framework.TestCase; import org.apache.commons.logging.PathableClassLoader; import org.apache.commons.logging.PathableTestSuite; /** * Tests for the PathableTestSuite and PathableClassLoader functionality, * where lookup order for the PathableClassLoader is parent-first. *

* These tests assume: *

    *
  • junit is in system classpath *
  • nothing else is in system classpath *
*/ public class ParentFirstTestCase extends TestCase { /** * Set up a custom classloader hierarchy for this test case. * The hierarchy is: *
    *
  • contextloader: parent-first. *
  • childloader: parent-first, used to load test case. *
  • parentloader: parent-first, parent is the bootclassloader. *
*/ public static Test suite() throws Exception { Class thisClass = ParentFirstTestCase.class; ClassLoader thisClassLoader = thisClass.getClassLoader(); // Make the parent a direct child of the bootloader to hide all // other classes in the system classpath PathableClassLoader parent = new PathableClassLoader(null); // Make the junit classes visible as a special case, as junit // won't be able to call this class at all without this. The // junit classes must be visible from the classloader that loaded // this class, so use that as the source for future access to classes // from the junit package. parent.useExplicitLoader("junit.", thisClassLoader); // make the commons-logging.jar classes visible via the parent parent.addLogicalLib("commons-logging"); // create a child classloader to load the test case through PathableClassLoader child = new PathableClassLoader(parent); // obviously, the child classloader needs to have the test classes // in its path! child.addLogicalLib("testclasses"); child.addLogicalLib("commons-logging-adapters"); // create a third classloader to be the context classloader. PathableClassLoader context = new PathableClassLoader(child); // reload this class via the child classloader Class testClass = child.loadClass(thisClass.getName()); // and return our custom TestSuite class return new PathableTestSuite(testClass, context); } /** * Utility method to return the set of all classloaders in the * parent chain starting from the one that loaded the class for * this object instance. */ private Set getAncestorCLs() { Set s = new HashSet(); ClassLoader cl = this.getClass().getClassLoader(); while (cl != null) { s.add(cl); cl = cl.getParent(); } return s; } /** * Test that the classloader hierarchy is as expected, and that * calling loadClass() on various classloaders works as expected. * Note that for this test case, parent-first classloading is * in effect. */ public void testPaths() throws Exception { // the context classloader is not expected to be null ClassLoader contextLoader = Thread.currentThread().getContextClassLoader(); assertNotNull("Context classloader is null", contextLoader); assertEquals("Context classloader has unexpected type", PathableClassLoader.class.getName(), contextLoader.getClass().getName()); // the classloader that loaded this class is obviously not null ClassLoader thisLoader = this.getClass().getClassLoader(); assertNotNull("thisLoader is null", thisLoader); assertEquals("thisLoader has unexpected type", PathableClassLoader.class.getName(), thisLoader.getClass().getName()); // the suite method specified that the context classloader's parent // is the loader that loaded this test case. assertSame("Context classloader is not child of thisLoader", thisLoader, contextLoader.getParent()); // thisLoader's parent should be available ClassLoader parentLoader = thisLoader.getParent(); assertNotNull("Parent classloader is null", parentLoader); assertEquals("Parent classloader has unexpected type", PathableClassLoader.class.getName(), parentLoader.getClass().getName()); // parent should have a parent of null assertNull("Parent classloader has non-null parent", parentLoader.getParent()); // getSystemClassloader is not a PathableClassLoader; it's of a // built-in type. This also verifies that system classloader is none of // (context, child, parent). ClassLoader systemLoader = ClassLoader.getSystemClassLoader(); assertNotNull("System classloader is null", systemLoader); assertFalse("System classloader has unexpected type", PathableClassLoader.class.getName().equals( systemLoader.getClass().getName())); // junit classes should be visible; their classloader is not // in the hierarchy of parent classloaders for this class, // though it is accessable due to trickery in the PathableClassLoader. Class junitTest = contextLoader.loadClass("junit.framework.Test"); Set ancestorCLs = getAncestorCLs(); assertFalse("Junit not loaded by ancestor classloader", ancestorCLs.contains(junitTest.getClassLoader())); // jcl api classes should be visible only via the parent Class logClass = contextLoader.loadClass("org.apache.commons.logging.Log"); assertSame("Log class not loaded via parent", logClass.getClassLoader(), parentLoader); // jcl adapter classes should be visible via both parent and child. However // as the classloaders are parent-first we should see the parent one. Class log4jClass = contextLoader.loadClass("org.apache.commons.logging.impl.Log4JLogger"); assertSame("Log4JLogger not loaded via parent", log4jClass.getClassLoader(), parentLoader); // test classes should be visible via the child only Class testClass = contextLoader.loadClass("org.apache.commons.logging.PathableTestSuite"); assertSame("PathableTestSuite not loaded via child", testClass.getClassLoader(), thisLoader); // test loading of class that is not available try { Class noSuchClass = contextLoader.loadClass("no.such.class"); fail("Class no.such.class is unexpectedly available"); assertNotNull(noSuchClass); // silence warning about unused var } catch(ClassNotFoundException ex) { // ok } // String class classloader is null Class stringClass = contextLoader.loadClass("java.lang.String"); assertNull("String class classloader is not null!", stringClass.getClassLoader()); } /** * Test that the various flavours of ClassLoader.getResource work as expected. */ public void testResource() { URL resource; ClassLoader contextLoader = Thread.currentThread().getContextClassLoader(); ClassLoader childLoader = contextLoader.getParent(); // getResource where it doesn't exist resource = childLoader.getResource("nosuchfile"); assertNull("Non-null URL returned for invalid resource name", resource); // getResource where it is accessable only to parent classloader resource = childLoader.getResource("org/apache/commons/logging/Log.class"); assertNotNull("Unable to locate Log.class resource", resource); // getResource where it is accessable only to child classloader resource = childLoader.getResource("org/apache/commons/logging/PathableTestSuite.class"); assertNotNull("Unable to locate PathableTestSuite.class resource", resource); // getResource where it is accessable to both classloaders. The one visible // to the parent should be returned. The URL returned will be of form // jar:file:/x/y.jar!path/to/resource. The filename part should include the jarname // of form commons-logging-nnnn.jar, not commons-logging-adapters-nnnn.jar resource = childLoader.getResource("org/apache/commons/logging/impl/Log4JLogger.class"); assertNotNull("Unable to locate Log4JLogger.class resource", resource); assertTrue("Incorrect source for Log4JLogger class", resource.toString().indexOf("/commons-logging-1.") > 0); } /** * Test that the various flavours of ClassLoader.getResources work as expected. */ public void testResources() throws Exception { Enumeration resources; URL[] urls; // verify the classloader hierarchy ClassLoader contextLoader = Thread.currentThread().getContextClassLoader(); ClassLoader childLoader = contextLoader.getParent(); ClassLoader parentLoader = childLoader.getParent(); ClassLoader bootLoader = parentLoader.getParent(); assertNull("Unexpected classloader hierarchy", bootLoader); // getResources where no instances exist resources = childLoader.getResources("nosuchfile"); urls = toURLArray(resources); assertEquals("Non-null URL returned for invalid resource name", 0, urls.length); // getResources where the resource only exists in the parent resources = childLoader.getResources("org/apache/commons/logging/Log.class"); urls = toURLArray(resources); assertEquals("Unexpected number of Log.class resources found", 1, urls.length); // getResources where the resource only exists in the child resources = childLoader.getResources("org/apache/commons/logging/PathableTestSuite.class"); urls = toURLArray(resources); assertEquals("Unexpected number of PathableTestSuite.class resources found", 1, urls.length); // getResources where the resource exists in both. // resources should be returned in order (parent-resource, child-resource) resources = childLoader.getResources("org/apache/commons/logging/impl/Log4JLogger.class"); urls = toURLArray(resources); assertEquals("Unexpected number of Log4JLogger.class resources found", 2, urls.length); // There is no gaurantee about the ordering of results returned from getResources // To make this test portable across JVMs, sort the string to give them a known order String[] urlsToStrings = new String[2]; urlsToStrings[0] = urls[0].toString(); urlsToStrings[1] = urls[1].toString(); Arrays.sort(urlsToStrings); assertTrue("Incorrect source for Log4JLogger class", urlsToStrings[0].indexOf("/commons-logging-1.") > 0); assertTrue("Incorrect source for Log4JLogger class", urlsToStrings[1].indexOf("/commons-logging-adapters-1.") > 0); } /** * Utility method to convert an enumeration-of-URLs into an array of URLs. */ private static URL[] toURLArray(Enumeration e) { ArrayList l = new ArrayList(); while (e.hasMoreElements()) { URL u = (URL) e.nextElement(); l.add(u); } URL[] tmp = new URL[l.size()]; return (URL[]) l.toArray(tmp); } /** * Test that getResourceAsStream works. */ public void testResourceAsStream() throws Exception { java.io.InputStream is; // verify the classloader hierarchy ClassLoader contextLoader = Thread.currentThread().getContextClassLoader(); ClassLoader childLoader = contextLoader.getParent(); ClassLoader parentLoader = childLoader.getParent(); ClassLoader bootLoader = parentLoader.getParent(); assertNull("Unexpected classloader hierarchy", bootLoader); // getResourceAsStream where no instances exist is = childLoader.getResourceAsStream("nosuchfile"); assertNull("Invalid resource returned non-null stream", is); // getResourceAsStream where resource does exist is = childLoader.getResourceAsStream("org/apache/commons/logging/Log.class"); assertNotNull("Null returned for valid resource", is); is.close(); // It would be nice to test parent-first ordering here, but that would require // having a resource with the same name in both the parent and child loaders, // but with different contents. That's a little tricky to set up so we'll // skip that for now. } } commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/pathable/ChildFirstTestCase.java100664 33670 12145235705 31344 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.logging.pathable; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.Enumeration; import java.util.HashSet; import java.util.Set; import junit.framework.Test; import junit.framework.TestCase; import org.apache.commons.logging.PathableClassLoader; import org.apache.commons.logging.PathableTestSuite; /** * Tests for the PathableTestSuite and PathableClassLoader functionality, * where lookup order for the PathableClassLoader is child-first. *

* These tests assume: *

    *
  • junit is in system classpath *
  • nothing else is in system classpath *
*/ public class ChildFirstTestCase extends TestCase { /** * Set up a custom classloader hierarchy for this test case. * The hierarchy is: *
    *
  • contextloader: child-first. *
  • childloader: child-first, used to load test case. *
  • parentloader: child-first, parent is the bootclassloader. *
*/ public static Test suite() throws Exception { Class thisClass = ChildFirstTestCase.class; ClassLoader thisClassLoader = thisClass.getClassLoader(); // Make the parent a direct child of the bootloader to hide all // other classes in the system classpath PathableClassLoader parent = new PathableClassLoader(null); parent.setParentFirst(false); // Make the junit classes visible as a special case, as junit // won't be able to call this class at all without this. The // junit classes must be visible from the classloader that loaded // this class, so use that as the source for future access to classes // from the junit package. parent.useExplicitLoader("junit.", thisClassLoader); // Make the commons-logging.jar classes visible via the parent parent.addLogicalLib("commons-logging"); // Create a child classloader to load the test case through PathableClassLoader child = new PathableClassLoader(parent); child.setParentFirst(false); // Obviously, the child classloader needs to have the test classes // in its path! child.addLogicalLib("testclasses"); child.addLogicalLib("commons-logging-adapters"); // Create a third classloader to be the context classloader. PathableClassLoader context = new PathableClassLoader(child); context.setParentFirst(false); // reload this class via the child classloader Class testClass = child.loadClass(thisClass.getName()); // and return our custom TestSuite class return new PathableTestSuite(testClass, context); } /** * Utility method to return the set of all classloaders in the * parent chain starting from the one that loaded the class for * this object instance. */ private Set getAncestorCLs() { Set s = new HashSet(); ClassLoader cl = this.getClass().getClassLoader(); while (cl != null) { s.add(cl); cl = cl.getParent(); } return s; } /** * Test that the classloader hierarchy is as expected, and that * calling loadClass() on various classloaders works as expected. * Note that for this test case, parent-first classloading is * in effect. */ public void testPaths() throws Exception { // the context classloader is not expected to be null ClassLoader contextLoader = Thread.currentThread().getContextClassLoader(); assertNotNull("Context classloader is null", contextLoader); assertEquals("Context classloader has unexpected type", PathableClassLoader.class.getName(), contextLoader.getClass().getName()); // the classloader that loaded this class is obviously not null ClassLoader thisLoader = this.getClass().getClassLoader(); assertNotNull("thisLoader is null", thisLoader); assertEquals("thisLoader has unexpected type", PathableClassLoader.class.getName(), thisLoader.getClass().getName()); // the suite method specified that the context classloader's parent // is the loader that loaded this test case. assertSame("Context classloader is not child of thisLoader", thisLoader, contextLoader.getParent()); // thisLoader's parent should be available ClassLoader parentLoader = thisLoader.getParent(); assertNotNull("Parent classloader is null", parentLoader); assertEquals("Parent classloader has unexpected type", PathableClassLoader.class.getName(), parentLoader.getClass().getName()); // parent should have a parent of null assertNull("Parent classloader has non-null parent", parentLoader.getParent()); // getSystemClassloader is not a PathableClassLoader; it's of a // built-in type. This also verifies that system classloader is none of // (context, child, parent). ClassLoader systemLoader = ClassLoader.getSystemClassLoader(); assertNotNull("System classloader is null", systemLoader); assertFalse("System classloader has unexpected type", PathableClassLoader.class.getName().equals( systemLoader.getClass().getName())); // junit classes should be visible; their classloader is not // in the hierarchy of parent classloaders for this class, // though it is accessable due to trickery in the PathableClassLoader. Class junitTest = contextLoader.loadClass("junit.framework.Test"); Set ancestorCLs = getAncestorCLs(); assertFalse("Junit not loaded by ancestor classloader", ancestorCLs.contains(junitTest.getClassLoader())); // jcl api classes should be visible only via the parent Class logClass = contextLoader.loadClass("org.apache.commons.logging.Log"); assertSame("Log class not loaded via parent", logClass.getClassLoader(), parentLoader); // jcl adapter classes should be visible via both parent and child. However // as the classloaders are child-first we should see the child one. Class log4jClass = contextLoader.loadClass("org.apache.commons.logging.impl.Log4JLogger"); assertSame("Log4JLogger not loaded via child", log4jClass.getClassLoader(), thisLoader); // test classes should be visible via the child only Class testClass = contextLoader.loadClass("org.apache.commons.logging.PathableTestSuite"); assertSame("PathableTestSuite not loaded via child", testClass.getClassLoader(), thisLoader); // test loading of class that is not available try { Class noSuchClass = contextLoader.loadClass("no.such.class"); fail("Class no.such.class is unexpectedly available"); assertNotNull(noSuchClass); // silence warning about unused var } catch(ClassNotFoundException ex) { // ok } // String class classloader is null Class stringClass = contextLoader.loadClass("java.lang.String"); assertNull("String class classloader is not null!", stringClass.getClassLoader()); } /** * Test that the various flavours of ClassLoader.getResource work as expected. */ public void testResource() { URL resource; ClassLoader contextLoader = Thread.currentThread().getContextClassLoader(); ClassLoader childLoader = contextLoader.getParent(); // getResource where it doesn't exist resource = childLoader.getResource("nosuchfile"); assertNull("Non-null URL returned for invalid resource name", resource); // getResource where it is accessable only to parent classloader resource = childLoader.getResource("org/apache/commons/logging/Log.class"); assertNotNull("Unable to locate Log.class resource", resource); // getResource where it is accessable only to child classloader resource = childLoader.getResource("org/apache/commons/logging/PathableTestSuite.class"); assertNotNull("Unable to locate PathableTestSuite.class resource", resource); // getResource where it is accessable to both classloaders. The one visible // to the child should be returned. The URL returned will be of form // jar:file:/x/y.jar!path/to/resource. The filename part should include the jarname // of form commons-logging-adapters-nnnn.jar, not commons-logging-nnnn.jar resource = childLoader.getResource("org/apache/commons/logging/impl/Log4JLogger.class"); assertNotNull("Unable to locate Log4JLogger.class resource", resource); assertTrue("Incorrect source for Log4JLogger class", resource.toString().indexOf("/commons-logging-adapters-1.") > 0); } /** * Test that the various flavours of ClassLoader.getResources work as expected. */ public void testResources() throws Exception { Enumeration resources; URL[] urls; // verify the classloader hierarchy ClassLoader contextLoader = Thread.currentThread().getContextClassLoader(); ClassLoader childLoader = contextLoader.getParent(); ClassLoader parentLoader = childLoader.getParent(); ClassLoader bootLoader = parentLoader.getParent(); assertNull("Unexpected classloader hierarchy", bootLoader); // getResources where no instances exist resources = childLoader.getResources("nosuchfile"); urls = toURLArray(resources); assertEquals("Non-null URL returned for invalid resource name", 0, urls.length); // getResources where the resource only exists in the parent resources = childLoader.getResources("org/apache/commons/logging/Log.class"); urls = toURLArray(resources); assertEquals("Unexpected number of Log.class resources found", 1, urls.length); // getResources where the resource only exists in the child resources = childLoader.getResources("org/apache/commons/logging/PathableTestSuite.class"); urls = toURLArray(resources); assertEquals("Unexpected number of PathableTestSuite.class resources found", 1, urls.length); // getResources where the resource exists in both. // resources should be returned in order (child-resource, parent-resource). // // IMPORTANT: due to the fact that in java 1.4 and earlier method // ClassLoader.getResources is final it isn't possible for PathableClassLoader // to override this. So even when child-first is enabled the resource order // is still (parent-resources, child-resources). This test verifies the expected // behaviour - even though it's not the desired behaviour. resources = childLoader.getResources("org/apache/commons/logging/impl/Log4JLogger.class"); urls = toURLArray(resources); assertEquals("Unexpected number of Log4JLogger.class resources found", 2, urls.length); // There is no guarantee about the ordering of results returned from getResources // To make this test portable across JVMs, sort the string to give them a known order String[] urlsToStrings = new String[2]; urlsToStrings[0] = urls[0].toString(); urlsToStrings[1] = urls[1].toString(); Arrays.sort(urlsToStrings); assertTrue("Incorrect source for Log4JLogger class", urlsToStrings[0].indexOf("/commons-logging-1.") > 0); assertTrue("Incorrect source for Log4JLogger class", urlsToStrings[1].indexOf("/commons-logging-adapters-1.") > 0); } /** * Utility method to convert an enumeration-of-URLs into an array of URLs. */ private static URL[] toURLArray(Enumeration e) { ArrayList l = new ArrayList(); while (e.hasMoreElements()) { URL u = (URL) e.nextElement(); l.add(u); } URL[] tmp = new URL[l.size()]; return (URL[]) l.toArray(tmp); } /** * Test that getResourceAsStream works. */ public void testResourceAsStream() throws Exception { java.io.InputStream is; // verify the classloader hierarchy ClassLoader contextLoader = Thread.currentThread().getContextClassLoader(); ClassLoader childLoader = contextLoader.getParent(); ClassLoader parentLoader = childLoader.getParent(); ClassLoader bootLoader = parentLoader.getParent(); assertNull("Unexpected classloader hierarchy", bootLoader); // getResourceAsStream where no instances exist is = childLoader.getResourceAsStream("nosuchfile"); assertNull("Invalid resource returned non-null stream", is); // getResourceAsStream where resource does exist is = childLoader.getResourceAsStream("org/apache/commons/logging/Log.class"); assertNotNull("Null returned for valid resource", is); is.close(); // It would be nice to test parent-first ordering here, but that would require // having a resource with the same name in both the parent and child loaders, // but with different contents. That's a little tricky to set up so we'll // skip that for now. } } commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/pathable/GeneralTestCase.java100664 10511 12145235705 30653 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.logging.pathable; import java.net.URL; import java.net.URLClassLoader; import junit.framework.Test; import junit.framework.TestCase; import org.apache.commons.logging.PathableClassLoader; import org.apache.commons.logging.PathableTestSuite; /** * Tests for the PathableTestSuite class. */ public class GeneralTestCase extends TestCase { /** * Set up a custom classloader hierarchy for this test case. */ public static Test suite() throws Exception { Class thisClass = GeneralTestCase.class; ClassLoader thisClassLoader = thisClass.getClassLoader(); PathableClassLoader loader = new PathableClassLoader(null); loader.useExplicitLoader("junit.", thisClassLoader); loader.addLogicalLib("testclasses"); // reload this class via the child classloader Class testClass = loader.loadClass(thisClass.getName()); // and return our custom TestSuite class return new PathableTestSuite(testClass, loader); } /** * Verify that a certain system property is not set, then set it. */ private static void checkAndSetProperties() { String prop = System.getProperty("no.such.property"); assertNull("no.such.property is unexpectedly defined", prop); System.setProperty("no.such.property", "dummy value"); prop = System.getProperty("no.such.property"); assertNotNull("no.such.property is unexpectedly undefined", prop); } /** * Verify that when a test method modifies the system properties they are * reset before the next test is run. *

* This method works in conjunction with testResetProps2. There is no * way of knowing which test method junit will run first, but it doesn't * matter; whichever one of them runs first will modify the system properties. * If the PathableTestSuite isn't resetting the system properties then whichever * of them runs second will fail. Of course if other methods are run in-between * then those methods might also fail... */ public void testResetProps1() { checkAndSetProperties(); } /** * See testResetProps1. */ public void testResetProps2() { checkAndSetProperties(); } /** * Verify that the context classloader is a custom one, then reset it to * a non-custom one. */ private static void checkAndSetContext() { ClassLoader contextLoader = Thread.currentThread().getContextClassLoader(); assertEquals("ContextLoader is of unexpected type", contextLoader.getClass().getName(), PathableClassLoader.class.getName()); URL[] noUrls = new URL[0]; Thread.currentThread().setContextClassLoader(new URLClassLoader(noUrls)); } /** * Verify that when a test method modifies the context classloader it is * reset before the next test is run. *

* This method works in conjunction with testResetContext2. There is no * way of knowing which test method junit will run first, but it doesn't * matter; whichever one of them runs first will modify the contextClassloader. * If the PathableTestSuite isn't resetting the contextClassLoader then whichever * of them runs second will fail. Of course if other methods are run in-between * then those methods might also fail... */ public void testResetContext1() { checkAndSetContext(); } /** * See testResetContext1. */ public void testResetContext2() { checkAndSetContext(); } } commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/NullClassLoaderTestCase.java100664 3365 12145235705 30536 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.logging; import junit.framework.TestCase; /** * Test cases for situations where getClassLoader or getContextClassLoader * return null. This can happen when using JDK 1.1. It can also happen when * JCL is deployed via the bootclassloader - something that could be done when * using java in embedded systems. */ public class NullClassLoaderTestCase extends TestCase { //---------------------- unit tests --------------------------------- /** * This tests that when getContextClassLoader returns null, the * LogFactory.getLog(name) method still correctly returns the same * log object when called multiple times with the same name. */ public void testSameLogObject() throws Exception { // unfortunately, there just isn't any way to emulate JCL being // accessable via the null classloader in "standard" systems, so // we can't include this test in our standard unit tests. } } ././@LongLink100644 0 0 151 12145235757 10263 Lustar 0 0 commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/security/SecurityAllowedTestCase.javacommons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/security/SecurityAllowedTestCase.100664 14010 12145235705 31640 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.logging.security; import java.io.PrintWriter; import java.io.StringWriter; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.security.AllPermission; import java.util.Hashtable; 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; /** * Tests for logging with a security policy that allows JCL access to everything. *

* This class has only one unit test, as we are (in part) checking behaviour in * the static block of the LogFactory class. As that class cannot be unloaded after * being loaded into a classloader, the only workaround is to use the * PathableClassLoader approach to ensure each test is run in its own * classloader, and use a separate testcase class for each test. */ public class SecurityAllowedTestCase extends TestCase { private SecurityManager oldSecMgr; // Dummy special hashtable, so we can tell JCL to use this instead of // the standard one. public static class CustomHashtable extends Hashtable { /** * Generated serial version ID. */ private static final long serialVersionUID = 8941017300059246720L; } /** * Return the tests included in this test suite. */ public static Test suite() throws Exception { PathableClassLoader parent = new PathableClassLoader(null); parent.useExplicitLoader("junit.", Test.class.getClassLoader()); parent.addLogicalLib("commons-logging"); parent.addLogicalLib("testclasses"); Class testClass = parent.loadClass( "org.apache.commons.logging.security.SecurityAllowedTestCase"); return new PathableTestSuite(testClass, parent); } public void setUp() { // save security manager so it can be restored in tearDown oldSecMgr = System.getSecurityManager(); } public void tearDown() { // Restore, so other tests don't get stuffed up if a test // sets a custom security manager. System.setSecurityManager(oldSecMgr); } /** * Test what happens when JCL is run with all permissions enabled. Custom * overrides should take effect. */ public void testAllAllowed() { System.setProperty( LogFactory.HASHTABLE_IMPLEMENTATION_PROPERTY, CustomHashtable.class.getName()); MockSecurityManager mySecurityManager = new MockSecurityManager(); mySecurityManager.addPermission(new AllPermission()); System.setSecurityManager(mySecurityManager); try { // Use reflection so that we can control exactly when the static // initialiser for the LogFactory class is executed. Class c = this.getClass().getClassLoader().loadClass( "org.apache.commons.logging.LogFactory"); Method m = c.getMethod("getLog", new Class[] {Class.class}); Log log = (Log) m.invoke(null, new Object[] {this.getClass()}); // Check whether we had any security exceptions so far (which were // caught by the code). We should not, as every secure operation // should be wrapped in an AccessController. Any security exceptions // indicate a path that is missing an appropriate AccessController. // // We don't wait until after the log.info call to get this count // because java.util.logging tries to load a resource bundle, which // requires permission accessClassInPackage. JCL explicitly does not // wrap calls to log methods in AccessControllers because writes to // a log file *should* only be permitted if the original caller is // trusted to access that file. int untrustedCodeCount = mySecurityManager.getUntrustedCodeCount(); log.info("testing"); // check that the default map implementation was loaded, as JCL was // forbidden from reading the HASHTABLE_IMPLEMENTATION_PROPERTY property. System.setSecurityManager(null); Field factoryField = c.getDeclaredField("factories"); factoryField.setAccessible(true); Object factoryTable = factoryField.get(null); assertNotNull(factoryTable); assertEquals(CustomHashtable.class.getName(), factoryTable.getClass().getName()); // we better compare that we have no security exception during the call to log // IBM JVM tries to load bundles during the invoke call, which increase the count assertEquals(untrustedCodeCount, mySecurityManager.getUntrustedCodeCount()); } catch(Throwable t) { // Restore original security manager so output can be generated; the // PrintWriter constructor tries to read the line.separator // system property. System.setSecurityManager(oldSecMgr); StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); t.printStackTrace(pw); fail("Unexpected exception:" + t.getMessage() + ":" + sw.toString()); } } } ././@LongLink100644 0 0 145 12145235757 10266 Lustar 0 0 commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/security/MockSecurityManager.javacommons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/security/MockSecurityManager.java100664 14476 12145235705 31663 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.logging.security; import java.io.FilePermission; import java.security.Permission; import java.security.Permissions; /** * Custom implementation of a security manager, so we can control the * security environment for tests in this package. */ public class MockSecurityManager extends SecurityManager { private final Permissions permissions = new Permissions(); private static final Permission setSecurityManagerPerm = new RuntimePermission("setSecurityManager"); private int untrustedCodeCount = 0; public MockSecurityManager() { permissions.add(setSecurityManagerPerm); } /** * Define the set of permissions to be granted to classes in the o.a.c.l package, * but NOT to unit-test classes in o.a.c.l.security package. */ public void addPermission(Permission p) { permissions.add(p); } /** * This returns the number of times that a check of a permission failed * due to stack-walking tracing up into untrusted code. Any non-zero * value indicates a bug in JCL, ie a situation where code was not * correctly wrapped in an AccessController block. The result of such a * bug is that signing JCL is not sufficient to allow JCL to perform * the operation; the caller would need to be signed too. */ public int getUntrustedCodeCount() { return untrustedCodeCount; } public void checkPermission(Permission p) throws SecurityException { if (setSecurityManagerPerm.implies(p)) { // ok, allow this; we don't want to block any calls to setSecurityManager // otherwise this custom security manager cannot be reset to the original. // System.out.println("setSecurityManager: granted"); return; } // Allow read-only access to files, as this is needed to load classes! // Ideally, we would limit this to just .class and .jar files. if (p instanceof FilePermission) { FilePermission fp = (FilePermission) p; if (fp.getActions().equals("read")) { // System.out.println("Permit read of files"); return; } } System.out.println("\n\ntesting permission:" + p.getClass() + ":"+ p); Exception e = new Exception(); e.fillInStackTrace(); StackTraceElement[] stack = e.getStackTrace(); // scan the call stack from most recent to oldest. // start at 1 to skip the entry in the stack for this method for(int i=1; i * Performing tests with security permissions disabled is tricky, as building error * messages on failure requires certain security permissions. If the security manager * blocks these, then the test can fail without the error messages being output. *

* This class has only one unit test, as we are (in part) checking behaviour in * the static block of the LogFactory class. As that class cannot be unloaded after * being loaded into a classloader, the only workaround is to use the * PathableClassLoader approach to ensure each test is run in its own * classloader, and use a separate testcase class for each test. */ public class SecurityForbiddenTestCase extends TestCase { private SecurityManager oldSecMgr; // Dummy special hashtable, so we can tell JCL to use this instead of // the standard one. public static class CustomHashtable extends Hashtable { /** * Generated serial version ID. */ private static final long serialVersionUID = 7224652794746236024L; } /** * Return the tests included in this test suite. */ public static Test suite() throws Exception { PathableClassLoader parent = new PathableClassLoader(null); parent.useExplicitLoader("junit.", Test.class.getClassLoader()); parent.addLogicalLib("commons-logging"); parent.addLogicalLib("testclasses"); Class testClass = parent.loadClass( "org.apache.commons.logging.security.SecurityForbiddenTestCase"); return new PathableTestSuite(testClass, parent); } public void setUp() { // save security manager so it can be restored in tearDown oldSecMgr = System.getSecurityManager(); } public void tearDown() { // Restore, so other tests don't get stuffed up if a test // sets a custom security manager. System.setSecurityManager(oldSecMgr); } /** * Test what happens when JCL is run with absolutely no security * privileges at all, including reading system properties. Everything * should fall back to the built-in defaults. */ public void testAllForbidden() { System.setProperty( LogFactory.HASHTABLE_IMPLEMENTATION_PROPERTY, CustomHashtable.class.getName()); MockSecurityManager mySecurityManager = new MockSecurityManager(); System.setSecurityManager(mySecurityManager); try { // Use reflection so that we can control exactly when the static // initialiser for the LogFactory class is executed. Class c = this.getClass().getClassLoader().loadClass( "org.apache.commons.logging.LogFactory"); Method m = c.getMethod("getLog", new Class[] {Class.class}); Log log = (Log) m.invoke(null, new Object[] {this.getClass()}); log.info("testing"); // check that the default map implementation was loaded, as JCL was // forbidden from reading the HASHTABLE_IMPLEMENTATION_PROPERTY property. // // The default is either the java Hashtable class (java < 1.2) or the // JCL WeakHashtable (java >= 1.3). System.setSecurityManager(oldSecMgr); Field factoryField = c.getDeclaredField("factories"); factoryField.setAccessible(true); Object factoryTable = factoryField.get(null); assertNotNull(factoryTable); String ftClassName = factoryTable.getClass().getName(); assertTrue("Custom hashtable unexpectedly used", !CustomHashtable.class.getName().equals(ftClassName)); assertEquals(0, mySecurityManager.getUntrustedCodeCount()); } catch(Throwable t) { // Restore original security manager so output can be generated; the // PrintWriter constructor tries to read the line.separator // system property. System.setSecurityManager(oldSecMgr); StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); t.printStackTrace(pw); fail("Unexpected exception:" + t.getMessage() + ":" + sw.toString()); } } } commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/logkit/StandardTestCase.java100664 12171 12145235705 30553 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.logging.logkit; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import junit.framework.Test; import org.apache.commons.logging.AbstractLogTest; 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.LogKitLogger; /** * Basic tests for Avalon LogKit logger adapter. */ public class StandardTestCase extends AbstractLogTest { // ----------------------------------------------------- Instance Variables /** *

The {@link LogFactory} implementation we have selected.

*/ protected LogFactory factory = null; /** *

The {@link Log} implementation we have selected.

*/ protected Log log = null; // ------------------------------------------- JUnit Infrastructure Methods /** * Return the tests included in this test suite. */ public static Test suite() throws Exception { Class thisClass = StandardTestCase.class; PathableClassLoader loader = new PathableClassLoader(null); loader.useExplicitLoader("junit.", Test.class.getClassLoader()); loader.addLogicalLib("testclasses"); loader.addLogicalLib("commons-logging"); loader.addLogicalLib("logkit"); Class testClass = loader.loadClass(thisClass.getName()); return new PathableTestSuite(testClass, loader); } /** * Set up instance variables required by this test case. */ public void setUp() throws Exception { LogFactory.releaseAll(); System.setProperty( "org.apache.commons.logging.Log", "org.apache.commons.logging.impl.LogKitLogger"); factory = LogFactory.getFactory(); log = LogFactory.getLog("TestLogger"); } /** * Tear down instance variables required by this test case. */ public void tearDown() { log = null; factory = null; LogFactory.releaseAll(); } // ----------------------------------------------------------- Test Methods /** * Override the abstract method from the parent class so that the * inherited tests can access the right Log object type. */ public Log getLogObject() { return new LogKitLogger(this.getClass().getName()); } // Test pristine LogFactory instance public void testPristineFactory() { assertNotNull("LogFactory exists", factory); assertEquals("LogFactory class", "org.apache.commons.logging.impl.LogFactoryImpl", factory.getClass().getName()); String names[] = factory.getAttributeNames(); assertNotNull("Names exists", names); assertEquals("Names empty", 0, names.length); } // Test pristine Log instance public void testPristineLog() { checkStandard(); } // Test Serializability of standard instance public void testSerializable() throws Exception { checkStandard(); // Serialize and deserialize the instance ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos); oos.writeObject(log); oos.close(); ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bais); log = (Log) ois.readObject(); ois.close(); checkStandard(); } // -------------------------------------------------------- Support Methods // Check the standard log instance protected void checkStandard() { assertNotNull("Log exists", log); assertEquals("Log class", "org.apache.commons.logging.impl.LogKitLogger", log.getClass().getName()); // Can we call level checkers with no exceptions? // Note that by default *everything* is enabled for LogKit assertTrue(log.isTraceEnabled()); assertTrue(log.isDebugEnabled()); assertTrue(log.isInfoEnabled()); assertTrue(log.isWarnEnabled()); assertTrue(log.isErrorEnabled()); assertTrue(log.isFatalEnabled()); } } ././@LongLink100644 0 0 145 12145235757 10266 Lustar 0 0 commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/BadHashtablePropertyTestCase.javacommons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/BadHashtablePropertyTestCase.java100664 2342 12145235705 31550 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.logging; import junit.framework.TestCase; import java.util.Hashtable; /** * Tests behaviour when the property is misconfigured. */ public class BadHashtablePropertyTestCase extends TestCase { public void testType() { assertTrue(LogFactory.factories instanceof Hashtable); } public void testPutCalled() throws Exception { LogFactory.getLog(BadHashtablePropertyTestCase.class); } } commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/BasicOperationsTestCase.java100664 7257 12145235705 30600 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.logging; import junit.framework.TestCase; /** * Tests the basic logging operations to ensure that they all function * without exception failure. In other words, that they do no fail by * throwing exceptions. * This is the minimum requirement for any well behaved logger * and so this test should be run for each kind. */ public class BasicOperationsTestCase extends TestCase { public void testIsEnabledClassLog() { Log log = LogFactory.getLog(BasicOperationsTestCase.class); executeIsEnabledTest(log); } public void testIsEnabledNamedLog() { Log log = LogFactory.getLog(BasicOperationsTestCase.class.getName()); executeIsEnabledTest(log); } public void executeIsEnabledTest(Log log) { try { log.isTraceEnabled(); log.isDebugEnabled(); log.isInfoEnabled(); log.isWarnEnabled(); log.isErrorEnabled(); log.isFatalEnabled(); } catch (Throwable t) { t.printStackTrace(); fail("Exception thrown: " + t); } } public void testMessageWithoutExceptionClassLog() { Log log = LogFactory.getLog(BasicOperationsTestCase.class); executeMessageWithoutExceptionTest(log); } public void testMessageWithoutExceptionNamedLog() { Log log = LogFactory.getLog(BasicOperationsTestCase.class.getName()); executeMessageWithoutExceptionTest(log); } public void executeMessageWithoutExceptionTest(Log log) { try { log.trace("Hello, Mum"); log.debug("Hello, Mum"); log.info("Hello, Mum"); log.warn("Hello, Mum"); log.error("Hello, Mum"); log.fatal("Hello, Mum"); } catch (Throwable t) { t.printStackTrace(); fail("Exception thrown: " + t); } } public void testMessageWithExceptionClassLog() { Log log = LogFactory.getLog(BasicOperationsTestCase.class); executeMessageWithExceptionTest(log); } public void testMessageWithExceptionNamedLog() { Log log = LogFactory.getLog(BasicOperationsTestCase.class.getName()); executeMessageWithExceptionTest(log); } public void executeMessageWithExceptionTest(Log log) { try { log.trace("Hello, Mum", new ArithmeticException()); log.debug("Hello, Mum", new ArithmeticException()); log.info("Hello, Mum", new ArithmeticException()); log.warn("Hello, Mum", new ArithmeticException()); log.error("Hello, Mum", new ArithmeticException()); log.fatal("Hello, Mum", new ArithmeticException()); } catch (Throwable t) { t.printStackTrace(); fail("Exception thrown: " + t); } } } commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/PathableClassLoader.java100664 41177 12145235705 27733 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.logging; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; import java.util.HashMap; import java.util.Iterator; import java.util.Map; /** * A ClassLoader which sees only specified classes, and which can be * set to do parent-first or child-first path lookup. *

* Note that this classloader is not "industrial strength"; users * looking for such a class may wish to look at the Tomcat sourcecode * instead. In particular, this class may not be threadsafe. *

* Note that the ClassLoader.getResources method isn't overloaded here. * It would be nice to ensure that when child-first lookup is set the * resources from the child are returned earlier in the list than the * resources from the parent. However overriding this method isn't possible * as the java 1.4 version of ClassLoader declares this method final * (though the java 1.5 version has removed the final qualifier). As the * ClassLoader javadoc doesn't specify the order in which resources * are returned, it's valid to return the resources in any order (just * untidy) so the inherited implementation is technically ok. */ public class PathableClassLoader extends URLClassLoader { private static final URL[] NO_URLS = new URL[0]; /** * A map of package-prefix to ClassLoader. Any class which is in * this map is looked up via the specified classloader instead of * the classpath associated with this classloader or its parents. *

* This is necessary in order for the rest of the world to communicate * with classes loaded via a custom classloader. As an example, junit * testcases which are loaded via a custom classloader needs to see * the same junit classes as the code invoking the testcase, otherwise * they can't pass result objects back. *

* Normally, only a classloader created with a null parent needs to * have any lookasides defined. */ private HashMap lookasides = null; /** * See setParentFirst. */ private boolean parentFirst = true; /** * Constructor. *

* Often, null is passed as the parent, ie the parent of the new * instance is the bootloader. This ensures that the classpath is * totally clean; nothing but the standard java library will be * present. *

* When using a null parent classloader with a junit testcase, it *is* * necessary for the junit library to also be visible. In this case, it * is recommended that the following code be used: *

     * pathableLoader.useExplicitLoader(
     *   "junit.",
     *   junit.framework.Test.class.getClassLoader());
     * 
* Note that this works regardless of whether junit is on the system * classpath, or whether it has been loaded by some test framework that * creates its own classloader to run unit tests in (eg maven2's * Surefire plugin). */ public PathableClassLoader(ClassLoader parent) { super(NO_URLS, parent); } /** * Allow caller to explicitly add paths. Generally this not a good idea; * use addLogicalLib instead, then define the location for that logical * library in the build.xml file. */ public void addURL(URL url) { super.addURL(url); } /** * Specify whether this classloader should ask the parent classloader * to resolve a class first, before trying to resolve it via its own * classpath. *

* Checking with the parent first is the normal approach for java, but * components within containers such as servlet engines can use * child-first lookup instead, to allow the components to override libs * which are visible in shared classloaders provided by the container. *

* Note that the method getResources always behaves as if parentFirst=true, * because of limitations in java 1.4; see the javadoc for method * getResourcesInOrder for details. *

* This value defaults to true. */ public void setParentFirst(boolean state) { parentFirst = state; } /** * For classes with the specified prefix, get them from the system * classpath which is active at the point this method is called. *

* This method is just a shortcut for *

     * useExplicitLoader(prefix, ClassLoader.getSystemClassLoader());
     * 
*

* Of course, this assumes that the classes of interest are already * in the classpath of the system classloader. */ public void useSystemLoader(String prefix) { useExplicitLoader(prefix, ClassLoader.getSystemClassLoader()); } /** * Specify a classloader to use for specific java packages. *

* The specified classloader is normally a loader that is NOT * an ancestor of this classloader. In particular, this loader * may have the bootloader as its parent, but be configured to * see specific other classes (eg the junit library loaded * via the system classloader). *

* The differences between using this method, and using * addLogicalLib are: *

    *
  • If code calls getClassLoader on a class loaded via * "lookaside", then traces up its inheritance chain, it * will see the "real" classloaders. When the class is remapped * into this classloader via addLogicalLib, the classloader * chain seen is this object plus ancestors. *
  • If two different jars contain classes in the same * package, then it is not possible to load both jars into * the same "lookaside" classloader (eg the system classloader) * then map one of those subsets from here. Of course they could * be loaded into two different "lookaside" classloaders and * then a prefix used to map from here to one of those classloaders. *
*/ public void useExplicitLoader(String prefix, ClassLoader loader) { if (lookasides == null) { lookasides = new HashMap(); } lookasides.put(prefix, loader); } /** * Specify a collection of logical libraries. See addLogicalLib. */ public void addLogicalLib(String[] logicalLibs) { for(int i=0; i * The specified lib name is used as a key into the system properties; * there is expected to be a system property defined with that name * whose value is a url that indicates where that logical library can * be found. Typically this is the name of a jar file, or a directory * containing class files. *

* If there is no system property, but the classloader that loaded * this class is a URLClassLoader then the set of URLs that the * classloader uses for its classpath is scanned; any jar in the * URL set whose name starts with the specified string is added to * the classpath managed by this instance. *

* Using logical library names allows the calling code to specify its * desired classpath without knowing the exact location of the necessary * classes. */ public void addLogicalLib(String logicalLib) { // first, check the system properties String filename = System.getProperty(logicalLib); if (filename != null) { try { URL libUrl = new File(filename).toURL(); addURL(libUrl); return; } catch(java.net.MalformedURLException e) { throw new UnknownError( "Invalid file [" + filename + "] for logical lib [" + logicalLib + "]"); } } // now check the classpath for a similar-named lib URL libUrl = libFromClasspath(logicalLib); if (libUrl != null) { addURL(libUrl); return; } // lib not found throw new UnknownError( "Logical lib [" + logicalLib + "] is not defined" + " as a System property."); } /** * If the classloader that loaded this class has this logical lib in its * path, then return the matching URL otherwise return null. *

* This only works when the classloader loading this class is an instance * of URLClassLoader and thus has a getURLs method that returns the classpath * it uses when loading classes. However in practice, the vast majority of the * time this type is the classloader used. *

* The classpath of the classloader for this instance is scanned, and any * jarfile in the path whose name starts with the logicalLib string is * considered a match. For example, passing "foo" will match a url * of file:///some/where/foo-2.7.jar. *

* When multiple classpath entries match the specified logicalLib string, * the one with the shortest filename component is returned. This means that * if "foo-1.1.jar" and "foobar-1.1.jar" are in the path, then a logicalLib * name of "foo" will match the first entry above. */ private URL libFromClasspath(String logicalLib) { ClassLoader cl = this.getClass().getClassLoader(); if (cl instanceof URLClassLoader == false) { return null; } URLClassLoader ucl = (URLClassLoader) cl; URL[] path = ucl.getURLs(); URL shortestMatch = null; int shortestMatchLen = Integer.MAX_VALUE; for(int i=0; i= 0) { filename = filename.substring(lastSlash+1); } if (filename.startsWith(logicalLib)) { // ok, this is a candidate if (filename.length() < shortestMatchLen) { shortestMatch = u; shortestMatchLen = filename.length(); } } } return shortestMatch; } /** * Override ClassLoader method. *

* For each explicitly mapped package prefix, if the name matches the * prefix associated with that entry then attempt to load the class via * that entries' classloader. */ protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException { // just for performance, check java and javax if (name.startsWith("java.") || name.startsWith("javax.")) { return super.loadClass(name, resolve); } if (lookasides != null) { for(Iterator i = lookasides.entrySet().iterator(); i.hasNext(); ) { Map.Entry entry = (Map.Entry) i.next(); String prefix = (String) entry.getKey(); if (name.startsWith(prefix) == true) { ClassLoader loader = (ClassLoader) entry.getValue(); Class clazz = Class.forName(name, resolve, loader); return clazz; } } } if (parentFirst) { return super.loadClass(name, resolve); } else { // Implement child-first. // // It appears that the findClass method doesn't check whether the // class has already been loaded. This seems odd to me, but without // first checking via findLoadedClass we can get java.lang.LinkageError // with message "duplicate class definition" which isn't good. try { Class clazz = findLoadedClass(name); if (clazz == null) { clazz = super.findClass(name); } if (resolve) { resolveClass(clazz); } return clazz; } catch(ClassNotFoundException e) { return super.loadClass(name, resolve); } } } /** * Same as parent class method except that when parentFirst is false * the resource is looked for in the local classpath before the parent * loader is consulted. */ public URL getResource(String name) { if (parentFirst) { return super.getResource(name); } else { URL local = super.findResource(name); if (local != null) { return local; } return super.getResource(name); } } /** * Emulate a proper implementation of getResources which respects the * setting for parentFirst. *

* Note that it's not possible to override the inherited getResources, as * it's declared final in java1.4 (thought that's been removed for 1.5). * The inherited implementation always behaves as if parentFirst=true. */ public Enumeration getResourcesInOrder(String name) throws IOException { if (parentFirst) { return super.getResources(name); } else { Enumeration localUrls = super.findResources(name); ClassLoader parent = getParent(); if (parent == null) { // Alas, there is no method to get matching resources // from a null (BOOT) parent classloader. Calling // ClassLoader.getSystemClassLoader isn't right. Maybe // calling Class.class.getResources(name) would do? // // However for the purposes of unit tests, we can // simply assume that no relevant resources are // loadable from the parent; unit tests will never be // putting any of their resources in a "boot" classloader // path! return localUrls; } Enumeration parentUrls = parent.getResources(name); ArrayList localItems = toList(localUrls); ArrayList parentItems = toList(parentUrls); localItems.addAll(parentItems); return Collections.enumeration(localItems); } } /** * * Clean implementation of list function of * {@link java.utils.Collection} added in JDK 1.4 * @param en Enumeration, possibly null * @return ArrayList containing the enumerated * elements in the enumerated order, not null */ private ArrayList toList(Enumeration en) { ArrayList results = new ArrayList(); if (en != null) { while (en.hasMoreElements()){ Object element = en.nextElement(); results.add(element); } } return results; } /** * Same as parent class method except that when parentFirst is false * the resource is looked for in the local classpath before the parent * loader is consulted. */ public InputStream getResourceAsStream(String name) { if (parentFirst) { return super.getResourceAsStream(name); } else { URL local = super.findResource(name); if (local != null) { try { return local.openStream(); } catch(IOException e) { // TODO: check if this is right or whether we should // fall back to trying parent. The javadoc doesn't say... return null; } } return super.getResourceAsStream(name); } } } commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/tccl/BadTCCLTestCase.java100664 3455 12145235705 27570 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.logging.tccl; 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 junit.framework.Test; import junit.framework.TestCase; /** * Simulates the case when TCCL is badly set and cannot load JCL. */ public class BadTCCLTestCase extends TestCase { public static Test suite() throws Exception { PathableClassLoader contextClassLoader = new PathableClassLoader(null); contextClassLoader.useExplicitLoader("junit.", Test.class.getClassLoader()); PathableTestSuite suite = new PathableTestSuite(BadTCCLTestCase.class, contextClassLoader); return suite; } // test methods /** * This test just tests that a log implementation can be found * by the LogFactory. */ public void testGetLog() { Log log = LogFactory.getLog(BadTCCLTestCase.class); log.debug("Hello, Mum"); } } ././@LongLink100644 0 0 145 12145235757 10266 Lustar 0 0 commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/tccl/custom/MyLogFactoryImpl.javacommons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/tccl/custom/MyLogFactoryImpl.java100664 2521 12145235705 31504 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.logging.tccl.custom; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; public class MyLogFactoryImpl extends LogFactory { public Object getAttribute(String name) { return null; } public String[] getAttributeNames() { return null; } public Log getInstance(Class clazz) { return null; } public Log getInstance(String name) { return null; } public void release() {} public void removeAttribute(String name) {} public void setAttribute(String name, Object value) {} } commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/tccl/custom/MyLog.java100664 3504 12145235705 27334 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.logging.tccl.custom; import org.apache.commons.logging.Log; public class MyLog implements Log { public MyLog(String category) {} public boolean isDebugEnabled() { return false; } public boolean isErrorEnabled() { return false; } public boolean isFatalEnabled() { return false; } public boolean isInfoEnabled() { return false; } public boolean isTraceEnabled() { return false; } public boolean isWarnEnabled() { return false; } public void trace(Object message) {} public void trace(Object message, Throwable t) {} public void debug(Object message) {} public void debug(Object message, Throwable t) {} public void info(Object message) {} public void info(Object message, Throwable t) {} public void warn(Object message) {} public void warn(Object message, Throwable t) {} public void error(Object message) {} public void error(Object message, Throwable t) {} public void fatal(Object message) {} public void fatal(Object message, Throwable t) {} } ././@LongLink100644 0 0 145 12145235757 10266 Lustar 0 0 commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/tccl/log/TcclEnabledTestCase.javacommons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/tccl/log/TcclEnabledTestCase.java100664 13331 12145235705 31367 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.logging.tccl.log; import java.net.URL; 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; /** * Verify that by default the standard LogFactoryImpl class loads a * custom Log implementation via the TCCL. */ public class TcclEnabledTestCase extends TestCase { public static final String MY_LOG_PKG = "org.apache.commons.logging.tccl.custom"; public static final String MY_LOG_IMPL = MY_LOG_PKG + ".MyLog"; // ------------------------------------------- JUnit Infrastructure Methods /** * Return the tests included in this test suite. */ public static Test suite() throws Exception { Class thisClass = TcclEnabledTestCase.class; // Determine the URL to this .class file, so that we can then // append the priority dirs to it. For tidiness, load this // class through a dummy loader though this is not absolutely // necessary... PathableClassLoader dummy = new PathableClassLoader(null); dummy.useExplicitLoader("junit.", Test.class.getClassLoader()); dummy.addLogicalLib("testclasses"); dummy.addLogicalLib("commons-logging"); String thisClassPath = thisClass.getName().replace('.', '/') + ".class"; URL baseUrl = dummy.findResource(thisClassPath); // Now set up the desired classloader hierarchy. Everything goes into // the parent classpath, but we exclude the custom Log class. // // We then create a tccl classloader that can see the custom // Log class. Therefore if that class can be found, then the // TCCL must have been used to load it. PathableClassLoader emptyLoader = new PathableClassLoader(null); PathableClassLoader parentLoader = new PathableClassLoader(null); parentLoader.useExplicitLoader("junit.", Test.class.getClassLoader()); parentLoader.addLogicalLib("commons-logging"); parentLoader.addLogicalLib("testclasses"); // hack to ensure that the testcase classloader can't see // the custom MyLogFactoryImpl parentLoader.useExplicitLoader(MY_LOG_PKG + ".", emptyLoader); URL propsEnableUrl = new URL(baseUrl, "props_enable_tccl/"); parentLoader.addURL(propsEnableUrl); PathableClassLoader tcclLoader = new PathableClassLoader(parentLoader); tcclLoader.addLogicalLib("testclasses"); Class testClass = parentLoader.loadClass(thisClass.getName()); return new PathableTestSuite(testClass, tcclLoader); } /** * Set up instance variables required by this test case. */ public void setUp() throws Exception { LogFactory.releaseAll(); } /** * Tear down instance variables required by this test case. */ public void tearDown() { LogFactory.releaseAll(); } // ----------------------------------------------------------- Test Methods /** * Verify that MyLogFactoryImpl is only loadable via the tccl. */ public void testLoader() throws Exception { ClassLoader thisClassLoader = this.getClass().getClassLoader(); ClassLoader tcclLoader = Thread.currentThread().getContextClassLoader(); // the tccl loader should NOT be the same as the loader that loaded this test class. assertNotSame("tccl not same as test classloader", thisClassLoader, tcclLoader); // MyLog should not be loadable via parent loader try { Class clazz = thisClassLoader.loadClass(MY_LOG_IMPL); fail("Unexpectedly able to load MyLog via test class classloader"); assertNotNull(clazz); // silence warnings about unused var } catch(ClassNotFoundException ex) { // ok, expected } // MyLog should be loadable via tccl loader try { Class clazz = tcclLoader.loadClass(MY_LOG_IMPL); assertNotNull(clazz); } catch(ClassNotFoundException ex) { fail("Unexpectedly unable to load MyLog via tccl classloader"); } } /** * Verify that the custom Log implementation which is only accessable * via the TCCL has successfully been loaded as specified in the config file. * This proves that the TCCL was used to load that class. */ public void testTcclLoading() throws Exception { LogFactory instance = LogFactory.getFactory(); assertEquals( "Correct LogFactory loaded", "org.apache.commons.logging.impl.LogFactoryImpl", instance.getClass().getName()); Log log = instance.getInstance("test"); assertEquals( "Correct Log loaded", MY_LOG_IMPL, log.getClass().getName()); } } ././@LongLink100644 0 0 146 12145235757 10267 Lustar 0 0 commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/tccl/log/TcclDisabledTestCase.javacommons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/tccl/log/TcclDisabledTestCase.jav100664 14152 12145235705 31405 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.logging.tccl.log; import java.net.URL; import junit.framework.Test; import junit.framework.TestCase; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogConfigurationException; import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.PathableClassLoader; import org.apache.commons.logging.PathableTestSuite; /** * Verify that by default LogFactoryImpl is loaded from the tccl classloader. */ public class TcclDisabledTestCase extends TestCase { public static final String MY_LOG_PKG = "org.apache.commons.logging.tccl.custom"; public static final String MY_LOG_IMPL = MY_LOG_PKG + ".MyLog"; // ------------------------------------------- JUnit Infrastructure Methods /** * Return the tests included in this test suite. */ public static Test suite() throws Exception { Class thisClass = TcclDisabledTestCase.class; // Determine the URL to this .class file, so that we can then // append the priority dirs to it. For tidiness, load this // class through a dummy loader though this is not absolutely // necessary... PathableClassLoader dummy = new PathableClassLoader(null); dummy.useExplicitLoader("junit.", Test.class.getClassLoader()); dummy.addLogicalLib("testclasses"); dummy.addLogicalLib("commons-logging"); String thisClassPath = thisClass.getName().replace('.', '/') + ".class"; URL baseUrl = dummy.findResource(thisClassPath); // Now set up the desired classloader hierarchy. Everything goes into // the parent classpath, but we exclude the custom Log class. // // We then create a tccl classloader that can see the custom // Log class. Therefore if that class can be found, then the // TCCL must have been used to load it. PathableClassLoader emptyLoader = new PathableClassLoader(null); PathableClassLoader parentLoader = new PathableClassLoader(null); parentLoader.useExplicitLoader("junit.", Test.class.getClassLoader()); parentLoader.addLogicalLib("commons-logging"); parentLoader.addLogicalLib("testclasses"); // hack to ensure that the testcase classloader can't see // the custom MyLog parentLoader.useExplicitLoader(MY_LOG_PKG + ".", emptyLoader); URL propsEnableUrl = new URL(baseUrl, "props_disable_tccl/"); parentLoader.addURL(propsEnableUrl); PathableClassLoader tcclLoader = new PathableClassLoader(parentLoader); tcclLoader.addLogicalLib("testclasses"); Class testClass = parentLoader.loadClass(thisClass.getName()); return new PathableTestSuite(testClass, tcclLoader); } /** * Set up instance variables required by this test case. */ public void setUp() throws Exception { LogFactory.releaseAll(); } /** * Tear down instance variables required by this test case. */ public void tearDown() { LogFactory.releaseAll(); } // ----------------------------------------------------------- Test Methods /** * Verify that MyLog is only loadable via the tccl. */ public void testLoader() throws Exception { ClassLoader thisClassLoader = this.getClass().getClassLoader(); ClassLoader tcclLoader = Thread.currentThread().getContextClassLoader(); // the tccl loader should NOT be the same as the loader that loaded this test class. assertNotSame("tccl not same as test classloader", thisClassLoader, tcclLoader); // MyLog should not be loadable via parent loader try { Class clazz = thisClassLoader.loadClass(MY_LOG_IMPL); fail("Unexpectedly able to load MyLog via test class classloader"); assertNotNull(clazz); // silence warnings about unused var } catch(ClassNotFoundException ex) { // ok, expected } // MyLog should be loadable via tccl loader try { Class clazz = tcclLoader.loadClass(MY_LOG_IMPL); assertNotNull(clazz); } catch(ClassNotFoundException ex) { fail("Unexpectedly unable to load MyLog via tccl classloader"); } } /** * Verify that the custom Log implementation which is only accessable * via the TCCL has NOT been loaded. Because this is only accessable via the * TCCL, and we've use a commons-logging.properties that disables TCCL loading, * we should see the default Log rather than the custom one. */ public void testTcclLoading() throws Exception { LogFactory instance = LogFactory.getFactory(); assertEquals( "Correct LogFactory loaded", "org.apache.commons.logging.impl.LogFactoryImpl", instance.getClass().getName()); try { Log log = instance.getInstance("test"); fail("Unexpectedly succeeded in loading a custom Log class" + " that is only accessable via the tccl."); assertNotNull(log); // silence compiler warning about unused var } catch(LogConfigurationException ex) { // ok, expected int index = ex.getMessage().indexOf(MY_LOG_IMPL); assertTrue("MyLog not found", index >= 0); } } } commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/tccl/NullTCCLTestCase.java100664 3064 12145235705 30010 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.logging.tccl; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.PathableTestSuite; import junit.framework.Test; import junit.framework.TestCase; /** * Simulates the case when TCCL is set to NULL. */ public class NullTCCLTestCase extends TestCase { public static Test suite() throws Exception { PathableTestSuite suite = new PathableTestSuite(NullTCCLTestCase.class, null); return suite; } // test methods /** * This test just tests that a log implementation can be found * by the LogFactory. */ public void testGetLog() { Log log = LogFactory.getLog(NullTCCLTestCase.class); log.debug("Hello, Mum"); } } ././@LongLink100644 0 0 154 12145235757 10266 Lustar 0 0 commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/tccl/logfactory/TcclEnabledTestCase.javacommons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/tccl/logfactory/TcclEnabledTestCa100664 13101 12145235705 31502 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.logging.tccl.logfactory; import java.net.URL; import junit.framework.Test; import junit.framework.TestCase; import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.PathableClassLoader; import org.apache.commons.logging.PathableTestSuite; /** * Verify that by default a custom LogFactoryImpl is loaded from the * tccl classloader. */ public class TcclEnabledTestCase extends TestCase { // ------------------------------------------- JUnit Infrastructure Methods /** * Return the tests included in this test suite. */ public static Test suite() throws Exception { Class thisClass = TcclEnabledTestCase.class; // Determine the URL to this .class file, so that we can then // append the priority dirs to it. For tidiness, load this // class through a dummy loader though this is not absolutely // necessary... PathableClassLoader dummy = new PathableClassLoader(null); dummy.useExplicitLoader("junit.", Test.class.getClassLoader()); dummy.addLogicalLib("testclasses"); dummy.addLogicalLib("commons-logging"); String thisClassPath = thisClass.getName().replace('.', '/') + ".class"; URL baseUrl = dummy.findResource(thisClassPath); // Now set up the desired classloader hierarchy. Everything goes into // the parent classpath, but we exclude the custom LogFactoryImpl // class. // // We then create a tccl classloader that can see the custom // LogFactory class. Therefore if that class can be found, then the // TCCL must have been used to load it. PathableClassLoader emptyLoader = new PathableClassLoader(null); PathableClassLoader parentLoader = new PathableClassLoader(null); parentLoader.useExplicitLoader("junit.", Test.class.getClassLoader()); parentLoader.addLogicalLib("commons-logging"); parentLoader.addLogicalLib("testclasses"); // hack to ensure that the testcase classloader can't see // the cust MyLogFactoryImpl parentLoader.useExplicitLoader( "org.apache.commons.logging.tccl.custom.", emptyLoader); URL propsEnableUrl = new URL(baseUrl, "props_enable_tccl/"); parentLoader.addURL(propsEnableUrl); PathableClassLoader tcclLoader = new PathableClassLoader(parentLoader); tcclLoader.addLogicalLib("testclasses"); Class testClass = parentLoader.loadClass(thisClass.getName()); return new PathableTestSuite(testClass, tcclLoader); } /** * Set up instance variables required by this test case. */ public void setUp() throws Exception { LogFactory.releaseAll(); } /** * Tear down instance variables required by this test case. */ public void tearDown() { LogFactory.releaseAll(); } // ----------------------------------------------------------- Test Methods /** * Verify that MyLogFactoryImpl is only loadable via the tccl. */ public void testLoader() throws Exception { ClassLoader thisClassLoader = this.getClass().getClassLoader(); ClassLoader tcclLoader = Thread.currentThread().getContextClassLoader(); // the tccl loader should NOT be the same as the loader that loaded this test class. assertNotSame("tccl not same as test classloader", thisClassLoader, tcclLoader); // MyLogFactoryImpl should not be loadable via parent loader try { Class clazz = thisClassLoader.loadClass( "org.apache.commons.logging.tccl.custom.MyLogFactoryImpl"); fail("Unexpectedly able to load MyLogFactoryImpl via test class classloader"); assertNotNull(clazz); // silence warning about unused var } catch(ClassNotFoundException ex) { // ok, expected } // MyLogFactoryImpl should be loadable via tccl loader try { Class clazz = tcclLoader.loadClass( "org.apache.commons.logging.tccl.custom.MyLogFactoryImpl"); assertNotNull(clazz); } catch(ClassNotFoundException ex) { fail("Unexpectedly unable to load MyLogFactoryImpl via tccl classloader"); } } /** * Verify that the custom LogFactory implementation which is only accessable * via the TCCL has successfully been loaded as specified in the config file. * This proves that the TCCL was used to load that class. */ public void testTcclLoading() throws Exception { LogFactory instance = LogFactory.getFactory(); assertEquals( "Correct LogFactory loaded", "org.apache.commons.logging.tccl.custom.MyLogFactoryImpl", instance.getClass().getName()); } } ././@LongLink100644 0 0 155 12145235757 10267 Lustar 0 0 commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/tccl/logfactory/TcclDisabledTestCase.javacommons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/tccl/logfactory/TcclDisabledTestC100664 14150 12145235705 31523 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.logging.tccl.logfactory; import java.net.URL; import junit.framework.Test; import junit.framework.TestCase; import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.PathableClassLoader; import org.apache.commons.logging.PathableTestSuite; /** * Verify that a commons-logging.properties file can prevent a custom * LogFactoryImpl being loaded from the tccl classloader. */ public class TcclDisabledTestCase extends TestCase { public static final String MY_LOG_FACTORY_PKG = "org.apache.commons.logging.tccl.custom"; public static final String MY_LOG_FACTORY_IMPL = MY_LOG_FACTORY_PKG + ".MyLogFactoryImpl"; // ------------------------------------------- JUnit Infrastructure Methods /** * Return the tests included in this test suite. */ public static Test suite() throws Exception { Class thisClass = TcclDisabledTestCase.class; // Determine the URL to this .class file, so that we can then // append the priority dirs to it. For tidiness, load this // class through a dummy loader though this is not absolutely // necessary... PathableClassLoader dummy = new PathableClassLoader(null); dummy.useExplicitLoader("junit.", Test.class.getClassLoader()); dummy.addLogicalLib("testclasses"); dummy.addLogicalLib("commons-logging"); String thisClassPath = thisClass.getName().replace('.', '/') + ".class"; URL baseUrl = dummy.findResource(thisClassPath); // Now set up the desired classloader hierarchy. Everything goes into // the parent classpath, but we exclude the custom LogFactoryImpl // class. // // We then create a tccl classloader that can see the custom // LogFactory class. Therefore if that class can be found, then the // TCCL must have been used to load it. PathableClassLoader emptyLoader = new PathableClassLoader(null); PathableClassLoader parentLoader = new PathableClassLoader(null); parentLoader.useExplicitLoader("junit.", Test.class.getClassLoader()); parentLoader.addLogicalLib("commons-logging"); parentLoader.addLogicalLib("testclasses"); // hack to ensure that the testcase classloader can't see // the custom MyLogFactoryImpl parentLoader.useExplicitLoader( MY_LOG_FACTORY_PKG + ".", emptyLoader); URL propsEnableUrl = new URL(baseUrl, "props_disable_tccl/"); parentLoader.addURL(propsEnableUrl); PathableClassLoader tcclLoader = new PathableClassLoader(parentLoader); tcclLoader.addLogicalLib("testclasses"); Class testClass = parentLoader.loadClass(thisClass.getName()); return new PathableTestSuite(testClass, tcclLoader); } /** * Set up instance variables required by this test case. */ public void setUp() throws Exception { LogFactory.releaseAll(); } /** * Tear down instance variables required by this test case. */ public void tearDown() { LogFactory.releaseAll(); } // ----------------------------------------------------------- Test Methods /** * Verify that MyLogFactoryImpl is only loadable via the tccl. */ public void testLoader() throws Exception { ClassLoader thisClassLoader = this.getClass().getClassLoader(); ClassLoader tcclLoader = Thread.currentThread().getContextClassLoader(); // the tccl loader should NOT be the same as the loader that loaded this test class. assertNotSame("tccl not same as test classloader", thisClassLoader, tcclLoader); // MyLogFactoryImpl should not be loadable via parent loader try { Class clazz = thisClassLoader.loadClass(MY_LOG_FACTORY_IMPL); fail("Unexpectedly able to load MyLogFactoryImpl via test class classloader"); assertNotNull(clazz); // silence warning about unused var } catch(ClassNotFoundException ex) { // ok, expected } // MyLogFactoryImpl should be loadable via tccl loader try { Class clazz = tcclLoader.loadClass(MY_LOG_FACTORY_IMPL); assertNotNull(clazz); } catch(ClassNotFoundException ex) { fail("Unexpectedly unable to load MyLogFactoryImpl via tccl classloader"); } } /** * Verify that the custom LogFactory implementation which is only accessable * via the TCCL has NOT been loaded. Because this is only accessable via the * TCCL, and we've use a commons-logging.properties that disables TCCL loading, * we should see the default LogFactoryImpl rather than the custom one. */ public void testTcclLoading() throws Exception { try { LogFactory instance = LogFactory.getFactory(); fail("Unexpectedly succeeded in loading custom factory, though TCCL disabled."); assertNotNull(instance); // silence warning about unused var } catch(org.apache.commons.logging.LogConfigurationException ex) { // ok, custom MyLogFactoryImpl as specified in props_disable_tccl // could not be found. int index = ex.getMessage().indexOf(MY_LOG_FACTORY_IMPL); assertTrue("MylogFactoryImpl not found", index >= 0); } } } commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/DummyException.java100664 2202 12145235705 27012 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.logging; /** * Dummy exception that unit tests create instances of when they want to test * logging of an Exception object. */ public class DummyException extends Exception { private static final long serialVersionUID = 1L; public DummyException() { // super("Dummy Exception for unit testing"); } } ././@LongLink100644 0 0 145 12145235757 10266 Lustar 0 0 commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/servlet/BasicServletTestCase.javacommons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/servlet/BasicServletTestCase.java100664 5166 12145235705 31562 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.logging.servlet; import junit.framework.Test; import junit.framework.TestCase; import org.apache.commons.logging.PathableClassLoader; import org.apache.commons.logging.PathableTestSuite; import org.apache.commons.logging.impl.ServletContextCleaner; /** * Tests for ServletContextCleaner utility class. */ public class BasicServletTestCase extends TestCase { /** * Return the tests included in this test suite. */ public static Test suite() throws Exception { // LogFactory in parent // LogFactory in child (loads test) // LogFactory in tccl // // Having the test loaded via a loader above the tccl emulates the situation // where a web.xml file specifies ServletContextCleaner as a listener, and // that class is deployed via a shared classloader. PathableClassLoader parent = new PathableClassLoader(null); parent.useExplicitLoader("junit.", Test.class.getClassLoader()); parent.addLogicalLib("commons-logging"); parent.addLogicalLib("servlet-api"); PathableClassLoader child = new PathableClassLoader(parent); child.setParentFirst(false); child.addLogicalLib("commons-logging"); child.addLogicalLib("testclasses"); PathableClassLoader tccl = new PathableClassLoader(child); tccl.setParentFirst(false); tccl.addLogicalLib("commons-logging"); Class testClass = child.loadClass(BasicServletTestCase.class.getName()); return new PathableTestSuite(testClass, tccl); } /** * Test that calling ServletContextCleaner.contextDestroyed doesn't crash. * Testing anything else is rather difficult... */ public void testBasics() { ServletContextCleaner scc = new ServletContextCleaner(); scc.contextDestroyed(null); } } commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/AbstractLogTest.java100664 5251 12145235705 27114 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.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. * * @author Sean C. Sullivan * @version $Revision: 1432587 $ */ public abstract class AbstractLogTest extends TestCase { public abstract Log getLogObject(); public void testLoggingWithNullParameters() { 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()); } } commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/LogTestCase.java100664 2057 12145235705 26225 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.logging; public class LogTestCase extends AbstractLogTest { public Log getLogObject() { /** * Pickup whatever is found/configured! */ return LogFactory.getLog(this.getClass().getName()); } } commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/noop/NoOpLogTestCase.java100664 6644 12145235705 30002 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.logging.noop; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.impl.NoOpLog; import org.apache.commons.logging.AbstractLogTest; /** * Tests for NoOpLog logging adapter. *

* This simply applies the tests defined in AbstractLogTest to this class. */ public class NoOpLogTestCase extends AbstractLogTest { /** * Set up instance variables required by this test case. */ public void setUp() throws Exception { LogFactory.releaseAll(); System.setProperty( "org.apache.commons.logging.Log", "org.apache.commons.logging.impl.NoOpLog"); } /** * Tear down instance variables required by this test case. */ public void tearDown() { LogFactory.releaseAll(); System.getProperties().remove("org.apache.commons.logging.Log"); } /** * Override the abstract method from the parent class so that the * inherited tests can access the right Log object type. */ public Log getLogObject() { return new NoOpLog(this.getClass().getName()); } // Test Serializability of standard instance public void testSerializable() throws Exception { Log log = LogFactory.getLog(this.getClass().getName()); checkLog(log); // Serialize and deserialize the instance ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos); oos.writeObject(log); oos.close(); ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bais); log = (Log) ois.readObject(); ois.close(); checkLog(log); } // -------------------------------------------------------- Support Methods private void checkLog(Log log) { assertNotNull("Log exists", log); assertEquals("Log class", "org.apache.commons.logging.impl.NoOpLog", log.getClass().getName()); // Can we call level checkers with no exceptions? // Note that *everything* is permanently disabled for NoOpLog assertFalse(log.isTraceEnabled()); assertFalse(log.isDebugEnabled()); assertFalse(log.isInfoEnabled()); assertFalse(log.isWarnEnabled()); assertFalse(log.isErrorEnabled()); assertFalse(log.isFatalEnabled()); } } commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/UserClass.java100664 3050 12145235705 25746 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.logging; import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.impl.LogFactoryImpl; public class UserClass { /** * Set the ALLOW_FLAWED_CONTEXT feature on the LogFactoryImpl object * associated with this class' classloader. *

* Don't forget to set the context classloader to whatever it will be * when an instance of this class is actually created before calling * this method! */ public static void setAllowFlawedContext(String state) { LogFactory f = LogFactory.getFactory(); f.setAttribute(LogFactoryImpl.ALLOW_FLAWED_CONTEXT_PROPERTY, state); } public UserClass() { Log log = LogFactory.getLog(LoadTestCase.class); } } commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/AltHashtableTestCase.java100664 7526 12145235705 30046 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.logging; import junit.framework.Test; import junit.framework.TestCase; /** * Test the ability to force the LogFactory class to use some * arbitrary Hashtable implementation to store its mapping from * context-classloader -> LogFactory object. */ public class AltHashtableTestCase extends TestCase { public static Test suite() throws Exception { Class thisClass = AltHashtableTestCase.class; ClassLoader thisClassLoader = thisClass.getClassLoader(); PathableClassLoader loader = new PathableClassLoader(null); loader.useExplicitLoader("junit.", thisClassLoader); loader.addLogicalLib("testclasses"); loader.addLogicalLib("commons-logging"); Class testClass = loader.loadClass(thisClass.getName()); return new PathableTestSuite(testClass, loader); } /** * Set up before each test. *

* This method ensures that the appropriate system property is defined * to force the LogFactory class to use the AltHashtable class as its * Hashtable implementation for storing factories in. *

* This does make the assumption that whatever JVM we are running in * doesn't initialise classes until they are actually referenced (ie the * LogFactory class hasn't been initialised before this method is called). * This is true of all JVMs I know of; and if it isn't then this test will * fail and someone will tell us. */ public void setUp() { System.setProperty( "org.apache.commons.logging.LogFactory.HashtableImpl", AltHashtable.class.getName()); } /** * Verify that initialising the LogFactory class will cause it * to instantiate an object of type specified in system property * "org.apache.commons.logging.LogFactory.HashtableImpl". */ public void testType() { // Here, the reference to the LogFactory class should cause the // class to be loaded and initialised. It will see the property // set and use the AltHashtable class. If other tests in this // class have already been run within the same classloader then // LogFactory will already have been initialised, but that // doesn't change the effectiveness of this test. assertTrue(LogFactory.factories instanceof AltHashtable); } /** * Verify that when LogFactory sees a context-classloader for the * first time that it creates a new entry in the LogFactory.factories * hashmap. In particular, this checks that this process works ok when * a system property has been used to specify an alternative Hashtable * implementation for LogFactory to use. */ public void testPutCalled() throws Exception { AltHashtable.lastKey = null; AltHashtable.lastValue = null; LogFactory.getLog(AltHashtableTestCase.class); ClassLoader contextLoader = Thread.currentThread().getContextClassLoader(); assertEquals(contextLoader, AltHashtable.lastKey); assertNotNull(AltHashtable.lastValue); } } commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/jdk14/CustomConfigTestCase.java100664 31230 12145235705 31034 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.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; /** *

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.

* * @author Craig R. McClanahan * @version $Revision: 1448063 $ $Date: 2013-02-20 11:01:41 +0100 (Wed, 20 Feb 2013) $ */ public class CustomConfigTestCase extends DefaultConfigTestCase { protected static final String HANDLER_NAME = "org.apache.commons.logging.jdk14.TestHandler"; // ----------------------------------------------------------- Constructors /** *

Construct a new instance of this test case.

* * @param name Name of the test case */ public CustomConfigTestCase(String name) { super(name); } // ----------------------------------------------------- Instance Variables /** *

The customized Handler we will be using.

*/ protected TestHandler handler = null; /** *

The underlying Handlers we will be using.

*/ protected Handler handlers[] = null; /** *

The underlying Logger we will be using.

*/ protected Logger logger = null; /** *

The underlying LogManager we will be using.

*/ protected LogManager manager = null; /** *

The message levels that should have been logged.

*/ protected Level testLevels[] = { Level.FINE, Level.INFO, Level.WARNING, Level.SEVERE, Level.SEVERE }; /** *

The message strings that should have been logged.

*/ 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(String name, ClassLoader srcCL) throws Exception { String resName = name.replace('.', '/') + ".class"; System.err.println("Trying to load resource [" + resName + "]"); InputStream is = srcCL.getResourceAsStream(resName); ByteArrayOutputStream baos = new ByteArrayOutputStream(); System.err.println("Reading resource [" + resName + "]"); byte[] buf = new byte[1000]; for(;;) { 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(String className, ClassLoader targetCL) { try { targetCL.loadClass(className); // fail("Class already in target classloader"); return; } catch(ClassNotFoundException ex) { // ok, go ahead and load it } try { ClassLoader srcCL = CustomConfigAPITestCase.class.getClassLoader(); byte[] classData = readClass(className, srcCL); Class[] params = new Class[] { String.class, classData.getClass(), Integer.TYPE, Integer.TYPE }; Method m = ClassLoader.class.getDeclaredMethod("defineClass", params); 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(Exception e) { e.printStackTrace(); fail("Unable to load class " + className); } } /** * Set up instance variables required by this test case. */ 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 { 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. ClassLoader scl = ClassLoader.getSystemClassLoader(); loadTestHandler(HANDLER_NAME, scl); cl.useExplicitLoader(HANDLER_NAME, scl); cl.addLogicalLib("commons-logging"); cl.addLogicalLib("testclasses"); Class testClass = cl.loadClass(CustomConfigTestCase.class.getName()); return new PathableTestSuite(testClass, cl); } /** * Tear down instance variables required by this test case. */ 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)); assertTrue(!logger.isLoggable(Level.FINER)); assertTrue(!logger.isLoggable(Level.FINEST)); } // Test Serializability of Log instance public void testSerializable() throws Exception { super.testSerializable(); testExceptionMessages(); } // -------------------------------------------------------- Support Methods // Check the log instance 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()); assertTrue(!log.isTraceEnabled()); } // Check the recorded messages protected void checkLogRecords(boolean thrown) { Iterator records = handler.records(); for (int i = 0; i < testMessages.length; i++) { assertTrue(records.hasNext()); 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()); } } assertTrue(!records.hasNext()); handler.flush(); } // Log the messages with exceptions protected void logExceptionMessages() { 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(String name) throws Exception { logger = Logger.getLogger(name); } // Set up LogManager instance protected void setUpManager(String config) throws Exception { manager = LogManager.getLogManager(); InputStream is = this.getClass().getClassLoader().getResourceAsStream(config); manager.readConfiguration(is); is.close(); } } commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/jdk14/DefaultConfigTestCase.java100664 12312 12145235705 31146 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.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; /** *

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.

* * @author Craig R. McClanahan * @version $Revision: 1432587 $ $Date: 2013-01-13 12:11:32 +0100 (Sun, 13 Jan 2013) $ */ public class DefaultConfigTestCase extends TestCase { // ----------------------------------------------------------- Constructors /** *

Construct a new instance of this test case.

* * @param name Name of the test case */ public DefaultConfigTestCase(String name) { super(name); } // ----------------------------------------------------- Instance Variables /** *

The {@link LogFactory} implementation we have selected.

*/ protected LogFactory factory = null; /** *

The {@link Log} implementation we have selected.

*/ protected Log log = null; // ------------------------------------------- JUnit Infrastructure Methods /** * Set up instance variables required by this test case. */ public void setUp() throws Exception { setUpFactory(); setUpLog("TestLogger"); } /** * Return the tests included in this test suite. */ public static Test suite() throws Exception { PathableClassLoader loader = new PathableClassLoader(null); loader.useExplicitLoader("junit.", Test.class.getClassLoader()); loader.addLogicalLib("testclasses"); loader.addLogicalLib("commons-logging"); Class testClass = loader.loadClass(DefaultConfigTestCase.class.getName()); return new PathableTestSuite(testClass, loader); } /** * Tear down instance variables required by this test case. */ public void tearDown() { log = null; factory = null; LogFactory.releaseAll(); } // ----------------------------------------------------------- Test Methods // 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()); 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 ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos); oos.writeObject(log); oos.close(); ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bais); log = (Log) ois.readObject(); ois.close(); // Check the characteristics of the resulting object checkLog(); } // -------------------------------------------------------- Support Methods // 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(String name) throws Exception { log = LogFactory.getLog(name); } } commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/jdk14/TestHandler.java100664 3465 12145235705 27206 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.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; /** *

Test implementation of java.util.logging.Handler.

* * @author Craig R. McClanahan * @version $Revision: 1432587 $ $Date: 2013-01-13 12:11:32 +0100 (Sun, 13 Jan 2013) $ */ public class TestHandler extends Handler { // ----------------------------------------------------- Instance Variables // The set of logged records for this handler private final List records = new ArrayList(); // --------------------------------------------------------- Public Methods public Iterator records() { return records.iterator(); } // -------------------------------------------------------- Handler Methods public void close() { } public void flush() { records.clear(); } public void publish(LogRecord record) { records.add(record); } } ././@LongLink100644 0 0 147 12145235757 10270 Lustar 0 0 commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/jdk14/CustomConfigFullTestCase.javacommons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/jdk14/CustomConfigFullTestCase.ja100664 4444 12145235705 31317 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.logging.jdk14; import junit.framework.Test; import org.apache.commons.logging.PathableTestSuite; import org.apache.commons.logging.PathableClassLoader; /** * TestCase for Jdk14 logging when the commons-logging jar file is in * the parent classpath. */ public class CustomConfigFullTestCase extends CustomConfigTestCase { public CustomConfigFullTestCase(String name) { super(name); } /** * Return the tests included in this test suite. */ public static Test suite() throws Exception { PathableClassLoader parent = new PathableClassLoader(null); parent.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. ClassLoader scl = ClassLoader.getSystemClassLoader(); loadTestHandler(HANDLER_NAME, scl); parent.useExplicitLoader(HANDLER_NAME, scl); parent.addLogicalLib("commons-logging"); PathableClassLoader child = new PathableClassLoader(parent); child.addLogicalLib("testclasses"); Class testClass = child.loadClass(CustomConfigFullTestCase.class.getName()); return new PathableTestSuite(testClass, child); } } ././@LongLink100644 0 0 146 12145235757 10267 Lustar 0 0 commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/jdk14/CustomConfigAPITestCase.javacommons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/jdk14/CustomConfigAPITestCase.jav100664 4576 12145235705 31222 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.logging.jdk14; import junit.framework.Test; import org.apache.commons.logging.PathableClassLoader; import org.apache.commons.logging.PathableTestSuite; /** * TestCase for Jdk14 logging when the commons-logging-api jar file is in * the parent classpath and commons-logging.jar is in the child. */ public class CustomConfigAPITestCase extends CustomConfigTestCase { public CustomConfigAPITestCase(String name) { super(name); } /** * Return the tests included in this test suite. */ public static Test suite() throws Exception { PathableClassLoader parent = new PathableClassLoader(null); parent.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. ClassLoader scl = ClassLoader.getSystemClassLoader(); loadTestHandler(HANDLER_NAME, scl); parent.useExplicitLoader(HANDLER_NAME, scl); parent.addLogicalLib("commons-logging-api"); PathableClassLoader child = new PathableClassLoader(parent); child.addLogicalLib("testclasses"); child.addLogicalLib("commons-logging"); Class testClass = child.loadClass(CustomConfigAPITestCase.class.getName()); return new PathableTestSuite(testClass, child); } } commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/PathableTestSuite.java100664 14452 12145235705 27464 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.logging; import java.util.Properties; import junit.framework.Test; import junit.framework.TestResult; import junit.framework.TestSuite; /** * Custom TestSuite class that can be used to control the context classloader * in operation when a test runs. *

* For tests that need to control exactly what the classloader hierarchy is * like when the test is run, something like the following is recommended: *

 * class SomeTestCase extends TestCase {
 *  public static Test suite() throws Exception {
 *   PathableClassLoader parent = new PathableClassLoader(null);
 *   parent.useSystemLoader("junit.");
 * 
 *   PathableClassLoader child = new PathableClassLoader(parent);
 *   child.addLogicalLib("testclasses");
 *   child.addLogicalLib("log4j12");
 *   child.addLogicalLib("commons-logging");
 * 
 *   Class testClass = child.loadClass(SomeTestCase.class.getName());
 *   ClassLoader contextClassLoader = child;
 * 
 *   PathableTestSuite suite = new PathableTestSuite(testClass, child);
 *   return suite;
 *  }
 * 
 *  // test methods go here
 * }
 * 
* Note that if the suite method throws an exception then this will be handled * reasonable gracefully by junit; it will report that the suite method for * a test case failed with exception yyy. *

* The use of PathableClassLoader is not required to use this class, but it * is expected that using the two classes together is common practice. *

* This class will run each test methods within the specified TestCase using * the specified context classloader and system classloader. If different * tests within the same class require different context classloaders, * then the context classloader passed to the constructor should be the * "lowest" one available, and tests that need the context set to some parent * of this "lowest" classloader can call *

 *  // NB: pseudo-code only
 *  setContextClassLoader(getContextClassLoader().getParent());
 * 
* This class ensures that any context classloader changes applied by a test * is undone after the test is run, so tests don't need to worry about * restoring the context classloader on exit. This class also ensures that * the system properties are restored to their original settings after each * test, so tests that manipulate those don't need to worry about resetting them. *

* This class does not provide facilities for manipulating system properties; * tests that need specific system properties can simply set them in the * fixture or at the start of a test method. *

* Important! When the test case is run, "this.getClass()" refers of * course to the Class object passed to the constructor of this class - which * is different from the class whose suite() method was executed to determine * the classpath. This means that the suite method cannot communicate with * the test cases simply by setting static variables (for example to make the * custom classloaders available to the test methods or setUp/tearDown fixtures). * If this is really necessary then it is possible to use reflection to invoke * static methods on the class object passed to the constructor of this class. *

*

Limitations

*

* This class cannot control the system classloader (ie what method * ClassLoader.getSystemClassLoader returns) because Java provides no * mechanism for setting the system classloader. In this case, the only * option is to invoke the unit test in a separate JVM with the appropriate * settings. *

* The effect of using this approach in a system that uses junit's * "reloading classloader" behaviour is unknown. This junit feature is * intended for junit GUI apps where a test may be run multiple times * within the same JVM - and in particular, when the .class file may * be modified between runs of the test. How junit achieves this is * actually rather weird (the whole junit code is rather weird in fact) * and it is not clear whether this approach will work as expected in * such situations. */ public class PathableTestSuite extends TestSuite { /** * The classloader that should be set as the context classloader * before each test in the suite is run. */ private final ClassLoader contextLoader; /** * Constructor. * * @param testClass is the TestCase that is to be run, as loaded by * the appropriate ClassLoader. * * @param contextClassLoader is the loader that should be returned by * calls to Thread.currentThread.getContextClassLoader from test methods * (or any method called by test methods). */ public PathableTestSuite(Class testClass, ClassLoader contextClassLoader) { super(testClass); contextLoader = contextClassLoader; } /** * This method is invoked once for each Test in the current TestSuite. * Note that a Test may itself be a TestSuite object (ie a collection * of tests). *

* The context classloader and system properties are saved before each * test, and restored after the test completes to better isolate tests. */ public void runTest(Test test, TestResult result) { ClassLoader origContext = Thread.currentThread().getContextClassLoader(); Properties oldSysProps = (Properties) System.getProperties().clone(); try { Thread.currentThread().setContextClassLoader(contextLoader); test.run(result); } finally { System.setProperties(oldSysProps); Thread.currentThread().setContextClassLoader(origContext); } } } ././@LongLink100644 0 0 153 12145235757 10265 Lustar 0 0 commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/config/FirstPriorityConfigTestCase.javacommons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/config/FirstPriorityConfigTestCas100664 11145 12145235705 31661 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.logging.config; import java.net.URL; import junit.framework.Test; import junit.framework.TestCase; import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.PathableClassLoader; import org.apache.commons.logging.PathableTestSuite; /** * Tests that verify that the process of configuring logging on startup * works correctly by selecting the file with the highest priority. *

* This test sets up a classpath where: *

    *
  • first file found has priority=20 *
  • second file found has priority=10 *
* The result should be that the first file is used. */ public class FirstPriorityConfigTestCase extends TestCase { // ------------------------------------------- JUnit Infrastructure Methods /** * Return the tests included in this test suite. */ public static Test suite() throws Exception { Class thisClass = FirstPriorityConfigTestCase.class; // Determine the URL to this .class file, so that we can then // append the priority dirs to it. For tidiness, load this // class through a dummy loader though this is not absolutely // necessary... PathableClassLoader dummy = new PathableClassLoader(null); dummy.useExplicitLoader("junit.", Test.class.getClassLoader()); dummy.addLogicalLib("testclasses"); dummy.addLogicalLib("commons-logging"); String thisClassPath = thisClass.getName().replace('.', '/') + ".class"; URL baseUrl = dummy.findResource(thisClassPath); // Now set up the desired classloader hierarchy. We'll put JCL // in the container path, the testcase in a webapp path, and // both config files into the webapp path too. PathableClassLoader containerLoader = new PathableClassLoader(null); containerLoader.useExplicitLoader("junit.", Test.class.getClassLoader()); containerLoader.addLogicalLib("commons-logging"); PathableClassLoader webappLoader = new PathableClassLoader(containerLoader); webappLoader.addLogicalLib("testclasses"); URL pri20URL = new URL(baseUrl, "priority20/"); webappLoader.addURL(pri20URL); URL pri10URL = new URL(baseUrl, "priority10/"); webappLoader.addURL(pri10URL); // load the test class via webapp loader, and use the webapp loader // as the tccl loader too. Class testClass = webappLoader.loadClass(thisClass.getName()); return new PathableTestSuite(testClass, webappLoader); } /** * Set up instance variables required by this test case. */ public void setUp() throws Exception { LogFactory.releaseAll(); } /** * Tear down instance variables required by this test case. */ public void tearDown() { LogFactory.releaseAll(); } // ----------------------------------------------------------- Test Methods /** * Verify that the config file being used is the one containing * the desired configId value. */ public void testPriority() throws Exception { LogFactory instance = LogFactory.getFactory(); ClassLoader thisClassLoader = this.getClass().getClassLoader(); ClassLoader lfClassLoader = instance.getClass().getClassLoader(); ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); // context classloader should be thisClassLoader assertEquals(thisClassLoader, contextClassLoader); // lfClassLoader should be parent of this classloader assertEquals(lfClassLoader, thisClassLoader.getParent()); assertEquals(PathableClassLoader.class.getName(), lfClassLoader.getClass().getName()); String id = (String) instance.getAttribute("configId"); assertEquals("Correct config file loaded", "priority20", id ); } } ././@LongLink100644 0 0 146 12145235757 10267 Lustar 0 0 commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/config/PriorityConfigTestCase.javacommons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/config/PriorityConfigTestCase.jav100664 11405 12145235705 31574 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.logging.config; import java.net.URL; import junit.framework.Test; import junit.framework.TestCase; import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.PathableClassLoader; import org.apache.commons.logging.PathableTestSuite; /** * Tests that verify that the process of configuring logging on startup * works correctly by selecting the file with the highest priority. *

* This test sets up a classpath where: *

    *
  • first file (in parent loader) has priority=10 (parentFirst=true) *
  • second file found has no priority set *
  • third file found has priority=20 *
  • fourth file found also has priority=20 *
* The result should be that the third file is used. *

* Note that parentFirst=true is used in this test because method * PathableClassLoader.getResources always behaves as if * parentFirst=true; see the PathableClassLoader javadoc for details. */ public class PriorityConfigTestCase extends TestCase { // ------------------------------------------- JUnit Infrastructure Methods /** * Return the tests included in this test suite. */ public static Test suite() throws Exception { Class thisClass = PriorityConfigTestCase.class; // Determine the URL to this .class file, so that we can then // append the priority dirs to it. For tidiness, load this // class through a dummy loader though this is not absolutely // necessary... PathableClassLoader dummy = new PathableClassLoader(null); dummy.useExplicitLoader("junit.", Test.class.getClassLoader()); dummy.addLogicalLib("testclasses"); dummy.addLogicalLib("commons-logging"); String thisClassPath = thisClass.getName().replace('.', '/') + ".class"; URL baseUrl = dummy.findResource(thisClassPath); // Now set up the desired classloader hierarchy. We'll put a config // file of priority=10 in the container path, and ones of both // "no priority" and priority=20 in the webapp path. // // A second properties file with priority=20 is also added, // so we can check that the first one in the classpath is // used. PathableClassLoader containerLoader = new PathableClassLoader(null); containerLoader.useExplicitLoader("junit.", Test.class.getClassLoader()); containerLoader.addLogicalLib("commons-logging"); URL pri10URL = new URL(baseUrl, "priority10/"); containerLoader.addURL(pri10URL); PathableClassLoader webappLoader = new PathableClassLoader(containerLoader); webappLoader.setParentFirst(true); webappLoader.addLogicalLib("testclasses"); URL noPriorityURL = new URL(baseUrl, "nopriority/"); webappLoader.addURL(noPriorityURL); URL pri20URL = new URL(baseUrl, "priority20/"); webappLoader.addURL(pri20URL); URL pri20aURL = new URL(baseUrl, "priority20a/"); webappLoader.addURL(pri20aURL); // load the test class via webapp loader, and use the webapp loader // as the tccl loader too. Class testClass = webappLoader.loadClass(thisClass.getName()); return new PathableTestSuite(testClass, webappLoader); } /** * Set up instance variables required by this test case. */ public void setUp() throws Exception { LogFactory.releaseAll(); } /** * Tear down instance variables required by this test case. */ public void tearDown() { LogFactory.releaseAll(); } // ----------------------------------------------------------- Test Methods /** * Verify that the config file being used is the one containing * the desired configId value. */ public void testPriority() throws Exception { LogFactory instance = LogFactory.getFactory(); String id = (String) instance.getAttribute("configId"); assertEquals("Correct config file loaded", "priority20", id ); } } commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/SimpleLogTestCase.java100664 2031 12145235705 27367 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.logging; import org.apache.commons.logging.impl.SimpleLog; public class SimpleLogTestCase extends AbstractLogTest { public Log getLogObject() { return new SimpleLog(this.getClass().getName()); } } commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/log4j/StandardTests.java100664 16474 12145235705 27702 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.logging.log4j; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.ArrayList; import java.util.List; import junit.framework.TestCase; import org.apache.commons.logging.DummyException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * Abstract set of tests that can be executed with various classpaths set. *

* The tests verify that when running on a system with Log4J present, * Log4J is selected and that the logger basically works. */ public abstract class StandardTests extends TestCase { /** * Simple structure to store information about messages that actually get * logged by the underlying logging library. */ public static class LogEvent { public String msg; public String level; public Throwable throwable; } // ------------------------------------------------------------------- // JUnit Infrastructure Methods // ------------------------------------------------------------------- /** * Set up instance variables required by this test case. */ public void setUp() throws Exception { LogFactory.releaseAll(); } /** * Tear down instance variables required by this test case. */ public void tearDown() { LogFactory.releaseAll(); } // ----------------------------------------------------------- // abstract methods // ----------------------------------------------------------- /** * Modify log4j's setup so that all messages actually logged get redirected * into the specified list. *

* This method also sets the logging level to INFO so that we * can test whether messages are getting properly filtered. */ public abstract void setUpTestAppender(List logEvents) throws Exception; // ----------------------------------------------------------- Test Methods /** * Test that a LogFactory gets created as expected. */ public void testCreateFactory() { LogFactory factory = LogFactory.getFactory(); assertNotNull("LogFactory exists", factory); assertEquals("LogFactory class", "org.apache.commons.logging.impl.LogFactoryImpl", factory.getClass().getName()); String names[] = factory.getAttributeNames(); assertNotNull("Names exists", names); assertEquals("Names empty", 0, names.length); } /** * Verify that we can log messages without exceptions. */ public void testPlainMessages() throws Exception { List logEvents = new ArrayList(); setUpTestAppender(logEvents); Log log = LogFactory.getLog("test-category"); logPlainMessages(log); checkLoggingEvents(logEvents, false); } /** * Verify that we can log exception messages. */ public void testExceptionMessages() throws Exception { List logEvents = new ArrayList(); setUpTestAppender(logEvents); Log log = LogFactory.getLog("test-category"); logExceptionMessages(log); checkLoggingEvents(logEvents, true); } /** * Test Serializability of Log instance */ public void testSerializable() throws Exception { List logEvents = new ArrayList(); setUpTestAppender(logEvents); Log log = LogFactory.getLog("test-category"); ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos); oos.writeObject(log); oos.close(); ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bais); Log newLog = (Log) ois.readObject(); ois.close(); // Check the characteristics of the resulting object logExceptionMessages(newLog); checkLoggingEvents(logEvents, true); } // -------------------------------------------------------- Support Methods /** * Verify that the TestAppender has received the expected * number of messages. This assumes that: *

    *
  • setUpTestAppender has been called *
  • logPlainMessages or logExceptionMessages has been * called to log a known number of messages at known levels. *
* * @param logEvents is the list of log events received. * * @param thrown False if logPlainMessages was called * (ie the TestAppender is expected to have received * logevents with no associated exception info). True if * logExceptionMessages was called. */ private void checkLoggingEvents(List logEvents, boolean thrown) { LogEvent ev; assertEquals("Unexpected number of log events", 4, logEvents.size()); ev = (LogEvent) logEvents.get(0); assertEquals("Info message expected", "info", ev.msg); assertEquals("Info level expected", "INFO", ev.level); assertEquals("Exception data incorrect", ev.throwable!=null, thrown); ev = (LogEvent) logEvents.get(1); assertEquals("Warn message expected", "warn", ev.msg); assertEquals("Warn level expected", "WARN", ev.level); assertEquals("Exception data incorrect", ev.throwable!=null, thrown); ev = (LogEvent) logEvents.get(2); assertEquals("Error message expected", "error", ev.msg); assertEquals("Error level expected", "ERROR", ev.level); assertEquals("Exception data incorrect", ev.throwable!=null, thrown); ev = (LogEvent) logEvents.get(3); assertEquals("Fatal message expected", "fatal", ev.msg); assertEquals("Fatal level expected", "FATAL", ev.level); assertEquals("Exception data incorrect", ev.throwable!=null, thrown); } /** * Log plain messages. */ private void logPlainMessages(Log log) { log.trace("trace"); // Should not actually get logged log.debug("debug"); // Should not actually get logged log.info("info"); log.warn("warn"); log.error("error"); log.fatal("fatal"); } /** * Log messages with exceptions */ private void logExceptionMessages(Log log) { Throwable t = new DummyException(); log.trace("trace", t); // Should not actually get logged log.debug("debug", t); // Should not actually get logged log.info("info", t); log.warn("warn", t); log.error("error", t); log.fatal("fatal", t); } } ././@LongLink100644 0 0 166 12145235757 10271 Lustar 0 0 commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/log4j/log4j12/ParentClasspathStandardTestCase.javacommons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/log4j/log4j12/ParentClasspathStan100664 3526 12145235705 31255 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.logging.log4j.log4j12; import junit.framework.Test; import junit.framework.TestCase; import org.apache.commons.logging.PathableClassLoader; import org.apache.commons.logging.PathableTestSuite; /** * Tests for Log4J logging that emulate a webapp running within * a container where all the necessary libs are in the parent. */ public class ParentClasspathStandardTestCase extends TestCase { /** * Return the tests included in this test suite. */ public static Test suite() throws Exception { PathableClassLoader parent = new PathableClassLoader(null); parent.useExplicitLoader("junit.", Test.class.getClassLoader()); parent.addLogicalLib("commons-logging"); parent.addLogicalLib("log4j12"); PathableClassLoader child = new PathableClassLoader(parent); child.addLogicalLib("testclasses"); Class testClass = child.loadClass( "org.apache.commons.logging.log4j.log4j12.Log4j12StandardTests"); return new PathableTestSuite(testClass, child); } } ././@LongLink100644 0 0 153 12145235757 10265 Lustar 0 0 commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/log4j/log4j12/Log4j12StandardTests.javacommons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/log4j/log4j12/Log4j12StandardTest100664 3101 12145235705 30763 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.logging.log4j.log4j12; import java.util.List; import org.apache.commons.logging.log4j.StandardTests; import org.apache.log4j.Level; import org.apache.log4j.Logger; /** * A concrete class that runs the standard tests, and is compiled * specifically against log4j12. The parent class can't call any * log4j methods at all as that would mean it has to be compiled * against a particular version of log4j. */ public class Log4j12StandardTests extends StandardTests { public void setUpTestAppender(List logEvents) { TestAppender appender = new TestAppender(logEvents); Logger rootLogger = Logger.getRootLogger(); rootLogger.removeAllAppenders(); rootLogger.addAppender(appender); rootLogger.setLevel(Level.INFO); } } ././@LongLink100644 0 0 163 12145235757 10266 Lustar 0 0 commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/log4j/log4j12/ApiClasspathStandardTestCase.javacommons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/log4j/log4j12/ApiClasspathStandar100664 3705 12145235705 31223 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.logging.log4j.log4j12; import junit.framework.Test; import junit.framework.TestCase; import org.apache.commons.logging.PathableClassLoader; import org.apache.commons.logging.PathableTestSuite; /** * Tests for Log4J logging that emulate a webapp running within * a container where the commons-logging-api jar file is in * the parent classpath and commons-logging.jar is in the child. */ public class ApiClasspathStandardTestCase extends TestCase { /** * Return the tests included in this test suite. */ public static Test suite() throws Exception { PathableClassLoader parent = new PathableClassLoader(null); parent.useExplicitLoader("junit.", Test.class.getClassLoader()); parent.addLogicalLib("commons-logging-api"); PathableClassLoader child = new PathableClassLoader(parent); child.addLogicalLib("log4j12"); child.addLogicalLib("commons-logging"); child.addLogicalLib("testclasses"); Class testClass = child.loadClass( "org.apache.commons.logging.log4j.log4j12.Log4j12StandardTests"); return new PathableTestSuite(testClass, child); } } commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/log4j/log4j12/TestAppender.java100664 4442 12145235705 30647 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.logging.log4j.log4j12; import java.util.List; import org.apache.commons.logging.log4j.StandardTests; import org.apache.log4j.AppenderSkeleton; import org.apache.log4j.spi.LoggingEvent; /** * A custom implementation of org.apache.log4j.Appender which * converts the log4j-specific log event record into a representation that * doesn't have a dependency on log4j and stores that new representation into * an external list. */ public class TestAppender extends AppenderSkeleton { /** * Constructor. */ public TestAppender(List logEvents) { events = logEvents; } // ----------------------------------------------------- Instance Variables // The set of logged events for this appender private final List events; // ------------------------------------------------------- Appender Methods protected void append(LoggingEvent event) { StandardTests.LogEvent lev = new StandardTests.LogEvent(); lev.level = event.getLevel().toString(); if (event.getMessage() == null) { lev.msg = null; } else { lev.msg = event.getMessage().toString(); } if (event.getThrowableInformation() == null) { lev.throwable = null; } else { lev.throwable = event.getThrowableInformation().getThrowable(); } events.add(lev); } public void close() { } public boolean requiresLayout() { return false; } } ././@LongLink100644 0 0 165 12145235757 10270 Lustar 0 0 commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/log4j/log4j12/ChildClasspathStandardTestCase.javacommons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/log4j/log4j12/ChildClasspathStand100664 3523 12145235705 31210 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.logging.log4j.log4j12; import junit.framework.Test; import junit.framework.TestCase; import org.apache.commons.logging.PathableClassLoader; import org.apache.commons.logging.PathableTestSuite; /** * Tests for Log4J logging that emulate a webapp running within * a container where all the necessary libs are in the child. */ public class ChildClasspathStandardTestCase extends TestCase { /** * Return the tests included in this test suite. */ public static Test suite() throws Exception { PathableClassLoader parent = new PathableClassLoader(null); parent.useExplicitLoader("junit.", Test.class.getClassLoader()); PathableClassLoader child = new PathableClassLoader(parent); child.addLogicalLib("testclasses"); child.addLogicalLib("log4j12"); child.addLogicalLib("commons-logging"); Class testClass = child.loadClass( "org.apache.commons.logging.log4j.log4j12.Log4j12StandardTests"); return new PathableTestSuite(testClass, child); } } ././@LongLink100644 0 0 163 12145235757 10266 Lustar 0 0 commons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/log4j/log4j12/AppClasspathStandardTestCase.javacommons-logging-1.1.3-src/src/test/java/org/apache/commons/logging/log4j/log4j12/AppClasspathStandar100664 3443 12145235705 31231 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.logging.log4j.log4j12; import junit.framework.Test; import junit.framework.TestCase; import org.apache.commons.logging.PathableClassLoader; import org.apache.commons.logging.PathableTestSuite; /** * Tests for Log4J logging when there is only one classloader and everything * is in it, as would be the situation for a standalone application. */ public class AppClasspathStandardTestCase extends TestCase { /** * Return the tests included in this test suite. */ public static Test suite() throws Exception { PathableClassLoader loader = new PathableClassLoader(null); loader.useExplicitLoader("junit.", Test.class.getClassLoader()); loader.addLogicalLib("testclasses"); loader.addLogicalLib("log4j12"); loader.addLogicalLib("commons-logging"); Class testClass = loader.loadClass( "org.apache.commons.logging.log4j.log4j12.Log4j12StandardTests"); return new PathableTestSuite(testClass, loader); } } commons-logging-1.1.3-src/src/main/assembly/bin.xml100664 2670 12145235705 20232 0ustartntn 0 0 bin tar.gz zip false LICENSE* NOTICE* RELEASE-NOTES* target *.jar target/site/apidocs apidocs commons-logging-1.1.3-src/src/main/assembly/src.xml100664 3204 12145235705 20243 0ustartntn 0 0 src tar.gz zip ${project.artifactId}-${project.version}-src checkstyle.xml LICENSE.txt NOTICE.txt pom.xml PROPOSAL.html RELEASE-NOTES.txt STATUS.txt build.xml build-testing.xml build.properties.sample license-header.txt src **/download*.cgi commons-logging-1.1.3-src/src/main/java/overview.html100664 2550 12145235706 20574 0ustartntn 0 0 Overview Documentation for COMMONS-LOGGING

The Logging Wrapper Library component of the Apache Commons subproject offers wrappers around an extensible set of concrete logging implementations, so that application code based on it does not need to be modified in order to select a different logging implementation.

See the Package Description for the org.apache.commons.logging package for more information.

commons-logging-1.1.3-src/src/main/java/org/apache/commons/logging/impl/Jdk13LumberjackLogger.java100664 22770 12145235705 31016 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.logging.impl; import java.io.Serializable; import java.util.logging.Level; import java.util.logging.Logger; import java.util.logging.LogRecord; import java.util.StringTokenizer; import java.io.PrintWriter; import java.io.StringWriter; import org.apache.commons.logging.Log; /** * Implementation of the org.apache.commons.logging.Log * interface that wraps the standard JDK logging mechanisms that are * available in SourceForge's Lumberjack for JDKs prior to 1.4. * * @version $Id: Jdk13LumberjackLogger.java 1432663 2013-01-13 17:24:18Z tn $ * @since 1.1 */ public class Jdk13LumberjackLogger implements Log, Serializable { /** Serializable version identifier. */ private static final long serialVersionUID = -8649807923527610591L; // ----------------------------------------------------- Instance Variables /** * The underlying Logger implementation we are using. */ protected transient Logger logger = null; protected String name = null; private String sourceClassName = "unknown"; private String sourceMethodName = "unknown"; private boolean classAndMethodFound = false; /** * This member variable simply ensures that any attempt to initialise * this class in a pre-1.4 JVM will result in an ExceptionInInitializerError. * It must not be private, as an optimising compiler could detect that it * is not used and optimise it away. */ protected static final Level dummyLevel = Level.FINE; // ----------------------------------------------------------- Constructors /** * Construct a named instance of this Logger. * * @param name Name of the logger to be constructed */ public Jdk13LumberjackLogger(String name) { this.name = name; logger = getLogger(); } // --------------------------------------------------------- Public Methods private void log( Level level, String msg, Throwable ex ) { if( getLogger().isLoggable(level) ) { LogRecord record = new LogRecord(level, msg); if( !classAndMethodFound ) { getClassAndMethod(); } record.setSourceClassName(sourceClassName); record.setSourceMethodName(sourceMethodName); if( ex != null ) { record.setThrown(ex); } getLogger().log(record); } } /** * Gets the class and method by looking at the stack trace for the * first entry that is not this class. */ private void getClassAndMethod() { try { Throwable throwable = new Throwable(); throwable.fillInStackTrace(); StringWriter stringWriter = new StringWriter(); PrintWriter printWriter = new PrintWriter( stringWriter ); throwable.printStackTrace( printWriter ); String traceString = stringWriter.getBuffer().toString(); StringTokenizer tokenizer = new StringTokenizer( traceString, "\n" ); tokenizer.nextToken(); String line = tokenizer.nextToken(); while ( line.indexOf( this.getClass().getName() ) == -1 ) { line = tokenizer.nextToken(); } while ( line.indexOf( this.getClass().getName() ) >= 0 ) { line = tokenizer.nextToken(); } int start = line.indexOf( "at " ) + 3; int end = line.indexOf( '(' ); String temp = line.substring( start, end ); int lastPeriod = temp.lastIndexOf( '.' ); sourceClassName = temp.substring( 0, lastPeriod ); sourceMethodName = temp.substring( lastPeriod + 1 ); } catch ( Exception ex ) { // ignore - leave class and methodname unknown } classAndMethodFound = true; } /** * Logs a message with java.util.logging.Level.FINE. * * @param message to log * @see org.apache.commons.logging.Log#debug(Object) */ public void debug(Object message) { log(Level.FINE, String.valueOf(message), null); } /** * Logs a message with java.util.logging.Level.FINE. * * @param message to log * @param exception log this cause * @see org.apache.commons.logging.Log#debug(Object, Throwable) */ public void debug(Object message, Throwable exception) { log(Level.FINE, String.valueOf(message), exception); } /** * Logs a message with java.util.logging.Level.SEVERE. * * @param message to log * @see org.apache.commons.logging.Log#error(Object) */ public void error(Object message) { log(Level.SEVERE, String.valueOf(message), null); } /** * Logs a message with java.util.logging.Level.SEVERE. * * @param message to log * @param exception log this cause * @see org.apache.commons.logging.Log#error(Object, Throwable) */ public void error(Object message, Throwable exception) { log(Level.SEVERE, String.valueOf(message), exception); } /** * Logs a message with java.util.logging.Level.SEVERE. * * @param message to log * @see org.apache.commons.logging.Log#fatal(Object) */ public void fatal(Object message) { log(Level.SEVERE, String.valueOf(message), null); } /** * Logs a message with java.util.logging.Level.SEVERE. * * @param message to log * @param exception log this cause * @see org.apache.commons.logging.Log#fatal(Object, Throwable) */ public void fatal(Object message, Throwable exception) { log(Level.SEVERE, String.valueOf(message), exception); } /** * Return the native Logger instance we are using. */ public Logger getLogger() { if (logger == null) { logger = Logger.getLogger(name); } return logger; } /** * Logs a message with java.util.logging.Level.INFO. * * @param message to log * @see org.apache.commons.logging.Log#info(Object) */ public void info(Object message) { log(Level.INFO, String.valueOf(message), null); } /** * Logs a message with java.util.logging.Level.INFO. * * @param message to log * @param exception log this cause * @see org.apache.commons.logging.Log#info(Object, Throwable) */ public void info(Object message, Throwable exception) { log(Level.INFO, String.valueOf(message), exception); } /** * Is debug logging currently enabled? */ public boolean isDebugEnabled() { return getLogger().isLoggable(Level.FINE); } /** * Is error logging currently enabled? */ public boolean isErrorEnabled() { return getLogger().isLoggable(Level.SEVERE); } /** * Is fatal logging currently enabled? */ public boolean isFatalEnabled() { return getLogger().isLoggable(Level.SEVERE); } /** * Is info logging currently enabled? */ public boolean isInfoEnabled() { return getLogger().isLoggable(Level.INFO); } /** * Is trace logging currently enabled? */ public boolean isTraceEnabled() { return getLogger().isLoggable(Level.FINEST); } /** * Is warn logging currently enabled? */ public boolean isWarnEnabled() { return getLogger().isLoggable(Level.WARNING); } /** * Logs a message with java.util.logging.Level.FINEST. * * @param message to log * @see org.apache.commons.logging.Log#trace(Object) */ public void trace(Object message) { log(Level.FINEST, String.valueOf(message), null); } /** * Logs a message with java.util.logging.Level.FINEST. * * @param message to log * @param exception log this cause * @see org.apache.commons.logging.Log#trace(Object, Throwable) */ public void trace(Object message, Throwable exception) { log(Level.FINEST, String.valueOf(message), exception); } /** * Logs a message with java.util.logging.Level.WARNING. * * @param message to log * @see org.apache.commons.logging.Log#warn(Object) */ public void warn(Object message) { log(Level.WARNING, String.valueOf(message), null); } /** * Logs a message with java.util.logging.Level.WARNING. * * @param message to log * @param exception log this cause * @see org.apache.commons.logging.Log#warn(Object, Throwable) */ public void warn(Object message, Throwable exception) { log(Level.WARNING, String.valueOf(message), exception); } } commons-logging-1.1.3-src/src/main/java/org/apache/commons/logging/impl/NoOpLog.java100664 5757 12145235705 26305 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.logging.impl; import java.io.Serializable; import org.apache.commons.logging.Log; /** * Trivial implementation of Log that throws away all messages. No * configurable system properties are supported. * * @version $Id: NoOpLog.java 1432663 2013-01-13 17:24:18Z tn $ */ public class NoOpLog implements Log, Serializable { /** Serializable version identifier. */ private static final long serialVersionUID = 561423906191706148L; /** Convenience constructor */ public NoOpLog() { } /** Base constructor */ public NoOpLog(String name) { } /** Do nothing */ public void trace(Object message) { } /** Do nothing */ public void trace(Object message, Throwable t) { } /** Do nothing */ public void debug(Object message) { } /** Do nothing */ public void debug(Object message, Throwable t) { } /** Do nothing */ public void info(Object message) { } /** Do nothing */ public void info(Object message, Throwable t) { } /** Do nothing */ public void warn(Object message) { } /** Do nothing */ public void warn(Object message, Throwable t) { } /** Do nothing */ public void error(Object message) { } /** Do nothing */ public void error(Object message, Throwable t) { } /** Do nothing */ public void fatal(Object message) { } /** Do nothing */ public void fatal(Object message, Throwable t) { } /** * Debug is never enabled. * * @return false */ public final boolean isDebugEnabled() { return false; } /** * Error is never enabled. * * @return false */ public final boolean isErrorEnabled() { return false; } /** * Fatal is never enabled. * * @return false */ public final boolean isFatalEnabled() { return false; } /** * Info is never enabled. * * @return false */ public final boolean isInfoEnabled() { return false; } /** * Trace is never enabled. * * @return false */ public final boolean isTraceEnabled() { return false; } /** * Warn is never enabled. * * @return false */ public final boolean isWarnEnabled() { return false; } } commons-logging-1.1.3-src/src/main/java/org/apache/commons/logging/impl/WeakHashtable.java100664 41046 12145235705 27502 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.logging.impl; import java.lang.ref.ReferenceQueue; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Collection; import java.util.Enumeration; import java.util.HashSet; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; /** * Implementation of Hashtable that uses WeakReference's * to hold its keys thus allowing them to be reclaimed by the garbage collector. * The associated values are retained using strong references. *

* This class follows the semantics of Hashtable as closely as * possible. It therefore does not accept null values or keys. *

* Note: * This is not intended to be a general purpose hash table replacement. * This implementation is also tuned towards a particular purpose: for use as a replacement * for Hashtable in LogFactory. This application requires * good liveliness for get and put. Various tradeoffs * have been made with this in mind. *

* Usage: typical use case is as a drop-in replacement * for the Hashtable used in LogFactory for J2EE environments * running 1.3+ JVMs. Use of this class in most cases (see below) will * allow classloaders to be collected by the garbage collector without the need * to call {@link org.apache.commons.logging.LogFactory#release(ClassLoader) LogFactory.release(ClassLoader)}. *

* org.apache.commons.logging.LogFactory checks whether this class * can be supported by the current JVM, and if so then uses it to store * references to the LogFactory implementation it loads * (rather than using a standard Hashtable instance). * Having this class used instead of Hashtable solves * certain issues related to dynamic reloading of applications in J2EE-style * environments. However this class requires java 1.3 or later (due to its use * of java.lang.ref.WeakReference and associates). * And by the way, this extends Hashtable rather than HashMap * for backwards compatibility reasons. See the documentation * for method LogFactory.createFactoryStore for more details. *

* The reason all this is necessary is due to a issue which * arises during hot deploy in a J2EE-like containers. * Each component running in the container owns one or more classloaders; when * the component loads a LogFactory instance via the component classloader * a reference to it gets stored in the static LogFactory.factories member, * keyed by the component's classloader so different components don't * stomp on each other. When the component is later unloaded, the container * sets the component's classloader to null with the intent that all the * component's classes get garbage-collected. However there's still a * reference to the component's classloader from a key in the "global" * LogFactory's factories member! If LogFactory.release() * is called whenever component is unloaded, the classloaders will be correctly * garbage collected; this should be done by any container that * bundles commons-logging by default. However, holding the classloader * references weakly ensures that the classloader will be garbage collected * without the container performing this step. *

* Limitations: * There is still one (unusual) scenario in which a component will not * be correctly unloaded without an explicit release. Though weak references * are used for its keys, it is necessary to use strong references for its values. *

* If the abstract class LogFactory is * loaded by the container classloader but a subclass of * LogFactory [LogFactory1] is loaded by the component's * classloader and an instance stored in the static map associated with the * base LogFactory class, then there is a strong reference from the LogFactory * class to the LogFactory1 instance (as normal) and a strong reference from * the LogFactory1 instance to the component classloader via * getClass().getClassLoader(). This chain of references will prevent * collection of the child classloader. *

* Such a situation occurs when the commons-logging.jar is * loaded by a parent classloader (e.g. a server level classloader in a * servlet container) and a custom LogFactory implementation is * loaded by a child classloader (e.g. a web app classloader). *

* To avoid this scenario, ensure * that any custom LogFactory subclass is loaded by the same classloader as * the base LogFactory. Creating custom LogFactory subclasses is, * however, rare. The standard LogFactoryImpl class should be sufficient * for most or all users. * * @version $Id: WeakHashtable.java 1435077 2013-01-18 10:51:35Z tn $ * @since 1.1 */ public final class WeakHashtable extends Hashtable { /** Serializable version identifier. */ private static final long serialVersionUID = -1546036869799732453L; /** * The maximum number of times put() or remove() can be called before * the map will be purged of all cleared entries. */ private static final int MAX_CHANGES_BEFORE_PURGE = 100; /** * The maximum number of times put() or remove() can be called before * the map will be purged of one cleared entry. */ private static final int PARTIAL_PURGE_COUNT = 10; /* ReferenceQueue we check for gc'd keys */ private final ReferenceQueue queue = new ReferenceQueue(); /* Counter used to control how often we purge gc'd entries */ private int changeCount = 0; /** * Constructs a WeakHashtable with the Hashtable default * capacity and load factor. */ public WeakHashtable() {} /** *@see Hashtable */ public boolean containsKey(Object key) { // purge should not be required Referenced referenced = new Referenced(key); return super.containsKey(referenced); } /** *@see Hashtable */ public Enumeration elements() { purge(); return super.elements(); } /** *@see Hashtable */ public Set entrySet() { purge(); Set referencedEntries = super.entrySet(); Set unreferencedEntries = new HashSet(); for (Iterator it=referencedEntries.iterator(); it.hasNext();) { Map.Entry entry = (Map.Entry) it.next(); Referenced referencedKey = (Referenced) entry.getKey(); Object key = referencedKey.getValue(); Object value = entry.getValue(); if (key != null) { Entry dereferencedEntry = new Entry(key, value); unreferencedEntries.add(dereferencedEntry); } } return unreferencedEntries; } /** *@see Hashtable */ public Object get(Object key) { // for performance reasons, no purge Referenced referenceKey = new Referenced(key); return super.get(referenceKey); } /** *@see Hashtable */ public Enumeration keys() { purge(); final Enumeration enumer = super.keys(); return new Enumeration() { public boolean hasMoreElements() { return enumer.hasMoreElements(); } public Object nextElement() { Referenced nextReference = (Referenced) enumer.nextElement(); return nextReference.getValue(); } }; } /** *@see Hashtable */ public Set keySet() { purge(); Set referencedKeys = super.keySet(); Set unreferencedKeys = new HashSet(); for (Iterator it=referencedKeys.iterator(); it.hasNext();) { Referenced referenceKey = (Referenced) it.next(); Object keyValue = referenceKey.getValue(); if (keyValue != null) { unreferencedKeys.add(keyValue); } } return unreferencedKeys; } /** *@see Hashtable */ public synchronized Object put(Object key, Object value) { // check for nulls, ensuring semantics match superclass if (key == null) { throw new NullPointerException("Null keys are not allowed"); } if (value == null) { throw new NullPointerException("Null values are not allowed"); } // for performance reasons, only purge every // MAX_CHANGES_BEFORE_PURGE times if (changeCount++ > MAX_CHANGES_BEFORE_PURGE) { purge(); changeCount = 0; } // do a partial purge more often else if (changeCount % PARTIAL_PURGE_COUNT == 0) { purgeOne(); } Referenced keyRef = new Referenced(key, queue); return super.put(keyRef, value); } /** *@see Hashtable */ public void putAll(Map t) { if (t != null) { Set entrySet = t.entrySet(); for (Iterator it=entrySet.iterator(); it.hasNext();) { Map.Entry entry = (Map.Entry) it.next(); put(entry.getKey(), entry.getValue()); } } } /** *@see Hashtable */ public Collection values() { purge(); return super.values(); } /** *@see Hashtable */ public synchronized Object remove(Object key) { // for performance reasons, only purge every // MAX_CHANGES_BEFORE_PURGE times if (changeCount++ > MAX_CHANGES_BEFORE_PURGE) { purge(); changeCount = 0; } // do a partial purge more often else if (changeCount % PARTIAL_PURGE_COUNT == 0) { purgeOne(); } return super.remove(new Referenced(key)); } /** *@see Hashtable */ public boolean isEmpty() { purge(); return super.isEmpty(); } /** *@see Hashtable */ public int size() { purge(); return super.size(); } /** *@see Hashtable */ public String toString() { purge(); return super.toString(); } /** * @see Hashtable */ protected void rehash() { // purge here to save the effort of rehashing dead entries purge(); super.rehash(); } /** * Purges all entries whose wrapped keys * have been garbage collected. */ private void purge() { final List toRemove = new ArrayList(); synchronized (queue) { WeakKey key; while ((key = (WeakKey) queue.poll()) != null) { toRemove.add(key.getReferenced()); } } // LOGGING-119: do the actual removal of the keys outside the sync block // to prevent deadlock scenarios as purge() may be called from // non-synchronized methods too final int size = toRemove.size(); for (int i = 0; i < size; i++) { super.remove(toRemove.get(i)); } } /** * Purges one entry whose wrapped key * has been garbage collected. */ private void purgeOne() { synchronized (queue) { WeakKey key = (WeakKey) queue.poll(); if (key != null) { super.remove(key.getReferenced()); } } } /** Entry implementation */ private final static class Entry implements Map.Entry { private final Object key; private final Object value; private Entry(Object key, Object value) { this.key = key; this.value = value; } public boolean equals(Object o) { boolean result = false; if (o != null && o instanceof Map.Entry) { Map.Entry entry = (Map.Entry) o; result = (getKey()==null ? entry.getKey() == null : getKey().equals(entry.getKey())) && (getValue()==null ? entry.getValue() == null : getValue().equals(entry.getValue())); } return result; } public int hashCode() { return (getKey()==null ? 0 : getKey().hashCode()) ^ (getValue()==null ? 0 : getValue().hashCode()); } public Object setValue(Object value) { throw new UnsupportedOperationException("Entry.setValue is not supported."); } public Object getValue() { return value; } public Object getKey() { return key; } } /** Wrapper giving correct symantics for equals and hashcode */ private final static class Referenced { private final WeakReference reference; private final int hashCode; /** * * @throws NullPointerException if referant is null */ private Referenced(Object referant) { reference = new WeakReference(referant); // Calc a permanent hashCode so calls to Hashtable.remove() // work if the WeakReference has been cleared hashCode = referant.hashCode(); } /** * * @throws NullPointerException if key is null */ private Referenced(Object key, ReferenceQueue queue) { reference = new WeakKey(key, queue, this); // Calc a permanent hashCode so calls to Hashtable.remove() // work if the WeakReference has been cleared hashCode = key.hashCode(); } public int hashCode() { return hashCode; } private Object getValue() { return reference.get(); } public boolean equals(Object o) { boolean result = false; if (o instanceof Referenced) { Referenced otherKey = (Referenced) o; Object thisKeyValue = getValue(); Object otherKeyValue = otherKey.getValue(); if (thisKeyValue == null) { result = otherKeyValue == null; // Since our hashcode was calculated from the original // non-null referant, the above check breaks the // hashcode/equals contract, as two cleared Referenced // objects could test equal but have different hashcodes. // We can reduce (not eliminate) the chance of this // happening by comparing hashcodes. result = result && this.hashCode() == otherKey.hashCode(); // In any case, as our c'tor does not allow null referants // and Hashtable does not do equality checks between // existing keys, normal hashtable operations should never // result in an equals comparison between null referants } else { result = thisKeyValue.equals(otherKeyValue); } } return result; } } /** * WeakReference subclass that holds a hard reference to an * associated value and also makes accessible * the Referenced object holding it. */ private final static class WeakKey extends WeakReference { private final Referenced referenced; private WeakKey(Object key, ReferenceQueue queue, Referenced referenced) { super(key, queue); this.referenced = referenced; } private Referenced getReferenced() { return referenced; } } } commons-logging-1.1.3-src/src/main/java/org/apache/commons/logging/impl/package.html100664 1536 12145235705 26375 0ustartntn 0 0

Concrete implementations of commons-logging wrapper APIs.

commons-logging-1.1.3-src/src/main/java/org/apache/commons/logging/impl/Log4JLogger.java100664 23745 12145235705 27064 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.logging.impl; import java.io.Serializable; import org.apache.commons.logging.Log; import org.apache.log4j.Logger; import org.apache.log4j.Priority; import org.apache.log4j.Level; /** * Implementation of {@link Log} that maps directly to a * Logger for log4J version 1.2. *

* Initial configuration of the corresponding Logger instances should be done * in the usual manner, as outlined in the Log4J documentation. *

* The reason this logger is distinct from the 1.3 logger is that in version 1.2 * of Log4J: *

    *
  • class Logger takes Priority parameters not Level parameters. *
  • class Level extends Priority *
* Log4J1.3 is expected to change Level so it no longer extends Priority, which is * a non-binary-compatible change. The class generated by compiling this code against * log4j 1.2 will therefore not run against log4j 1.3. * * @version $Id: Log4JLogger.java 1448119 2013-02-20 12:28:04Z tn $ */ public class Log4JLogger implements Log, Serializable { /** Serializable version identifier. */ private static final long serialVersionUID = 5160705895411730424L; // ------------------------------------------------------------- Attributes /** The fully qualified name of the Log4JLogger class. */ private static final String FQCN = Log4JLogger.class.getName(); /** Log to this logger */ private transient volatile Logger logger = null; /** Logger name */ private final String name; private static final Priority traceLevel; // ------------------------------------------------------------ // Static Initializer. // // Note that this must come after the static variable declarations // otherwise initialiser expressions associated with those variables // will override any settings done here. // // Verify that log4j is available, and that it is version 1.2. // If an ExceptionInInitializerError is generated, then LogFactoryImpl // will treat that as meaning that the appropriate underlying logging // library is just not present - if discovery is in progress then // discovery will continue. // ------------------------------------------------------------ static { if (!Priority.class.isAssignableFrom(Level.class)) { // nope, this is log4j 1.3, so force an ExceptionInInitializerError throw new InstantiationError("Log4J 1.2 not available"); } // Releases of log4j1.2 >= 1.2.12 have Priority.TRACE available, earlier // versions do not. If TRACE is not available, then we have to map // calls to Log.trace(...) onto the DEBUG level. Priority _traceLevel; try { _traceLevel = (Priority) Level.class.getDeclaredField("TRACE").get(null); } catch(Exception ex) { // ok, trace not available _traceLevel = Level.DEBUG; } traceLevel = _traceLevel; } // ------------------------------------------------------------ Constructor public Log4JLogger() { name = null; } /** * Base constructor. */ public Log4JLogger(String name) { this.name = name; this.logger = getLogger(); } /** * For use with a log4j factory. */ public Log4JLogger(Logger logger) { if (logger == null) { throw new IllegalArgumentException( "Warning - null logger in constructor; possible log4j misconfiguration."); } this.name = logger.getName(); this.logger = logger; } /** * Logs a message with org.apache.log4j.Priority.TRACE. * When using a log4j version that does not support the TRACE * level, the message will be logged at the DEBUG level. * * @param message to log * @see org.apache.commons.logging.Log#trace(Object) */ public void trace(Object message) { getLogger().log(FQCN, traceLevel, message, null); } /** * Logs a message with org.apache.log4j.Priority.TRACE. * When using a log4j version that does not support the TRACE * level, the message will be logged at the DEBUG level. * * @param message to log * @param t log this cause * @see org.apache.commons.logging.Log#trace(Object, Throwable) */ public void trace(Object message, Throwable t) { getLogger().log(FQCN, traceLevel, message, t); } /** * Logs a message with org.apache.log4j.Priority.DEBUG. * * @param message to log * @see org.apache.commons.logging.Log#debug(Object) */ public void debug(Object message) { getLogger().log(FQCN, Level.DEBUG, message, null); } /** * Logs a message with org.apache.log4j.Priority.DEBUG. * * @param message to log * @param t log this cause * @see org.apache.commons.logging.Log#debug(Object, Throwable) */ public void debug(Object message, Throwable t) { getLogger().log(FQCN, Level.DEBUG, message, t); } /** * Logs a message with org.apache.log4j.Priority.INFO. * * @param message to log * @see org.apache.commons.logging.Log#info(Object) */ public void info(Object message) { getLogger().log(FQCN, Level.INFO, message, null); } /** * Logs a message with org.apache.log4j.Priority.INFO. * * @param message to log * @param t log this cause * @see org.apache.commons.logging.Log#info(Object, Throwable) */ public void info(Object message, Throwable t) { getLogger().log(FQCN, Level.INFO, message, t); } /** * Logs a message with org.apache.log4j.Priority.WARN. * * @param message to log * @see org.apache.commons.logging.Log#warn(Object) */ public void warn(Object message) { getLogger().log(FQCN, Level.WARN, message, null); } /** * Logs a message with org.apache.log4j.Priority.WARN. * * @param message to log * @param t log this cause * @see org.apache.commons.logging.Log#warn(Object, Throwable) */ public void warn(Object message, Throwable t) { getLogger().log(FQCN, Level.WARN, message, t); } /** * Logs a message with org.apache.log4j.Priority.ERROR. * * @param message to log * @see org.apache.commons.logging.Log#error(Object) */ public void error(Object message) { getLogger().log(FQCN, Level.ERROR, message, null); } /** * Logs a message with org.apache.log4j.Priority.ERROR. * * @param message to log * @param t log this cause * @see org.apache.commons.logging.Log#error(Object, Throwable) */ public void error(Object message, Throwable t) { getLogger().log(FQCN, Level.ERROR, message, t); } /** * Logs a message with org.apache.log4j.Priority.FATAL. * * @param message to log * @see org.apache.commons.logging.Log#fatal(Object) */ public void fatal(Object message) { getLogger().log(FQCN, Level.FATAL, message, null); } /** * Logs a message with org.apache.log4j.Priority.FATAL. * * @param message to log * @param t log this cause * @see org.apache.commons.logging.Log#fatal(Object, Throwable) */ public void fatal(Object message, Throwable t) { getLogger().log(FQCN, Level.FATAL, message, t); } /** * Return the native Logger instance we are using. */ public Logger getLogger() { Logger result = logger; if (result == null) { synchronized(this) { result = logger; if (result == null) { logger = result = Logger.getLogger(name); } } } return result; } /** * Check whether the Log4j Logger used is enabled for DEBUG priority. */ public boolean isDebugEnabled() { return getLogger().isDebugEnabled(); } /** * Check whether the Log4j Logger used is enabled for ERROR priority. */ public boolean isErrorEnabled() { return getLogger().isEnabledFor(Level.ERROR); } /** * Check whether the Log4j Logger used is enabled for FATAL priority. */ public boolean isFatalEnabled() { return getLogger().isEnabledFor(Level.FATAL); } /** * Check whether the Log4j Logger used is enabled for INFO priority. */ public boolean isInfoEnabled() { return getLogger().isInfoEnabled(); } /** * Check whether the Log4j Logger used is enabled for TRACE priority. * When using a log4j version that does not support the TRACE level, this call * will report whether DEBUG is enabled or not. */ public boolean isTraceEnabled() { return getLogger().isEnabledFor(traceLevel); } /** * Check whether the Log4j Logger used is enabled for WARN priority. */ public boolean isWarnEnabled() { return getLogger().isEnabledFor(Level.WARN); } } commons-logging-1.1.3-src/src/main/java/org/apache/commons/logging/impl/SimpleLog.java100664 57014 12145235705 26674 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.logging.impl; import java.io.InputStream; import java.io.Serializable; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.security.AccessController; import java.security.PrivilegedAction; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Properties; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogConfigurationException; /** * Simple implementation of Log that sends all enabled log messages, * for all defined loggers, to System.err. The following system properties * are supported to configure the behavior of this logger: *
    *
  • org.apache.commons.logging.simplelog.defaultlog - * Default logging detail level for all instances of SimpleLog. * Must be one of ("trace", "debug", "info", "warn", "error", or "fatal"). * If not specified, defaults to "info".
  • *
  • org.apache.commons.logging.simplelog.log.xxxxx - * Logging detail level for a SimpleLog instance named "xxxxx". * Must be one of ("trace", "debug", "info", "warn", "error", or "fatal"). * If not specified, the default logging detail level is used.
  • *
  • org.apache.commons.logging.simplelog.showlogname - * Set to true if you want the Log instance name to be * included in output messages. Defaults to false.
  • *
  • org.apache.commons.logging.simplelog.showShortLogname - * Set to true if you want the last component of the name to be * included in output messages. Defaults to true.
  • *
  • org.apache.commons.logging.simplelog.showdatetime - * Set to true if you want the current date and time * to be included in output messages. Default is false.
  • *
  • org.apache.commons.logging.simplelog.dateTimeFormat - * The date and time format to be used in the output messages. * The pattern describing the date and time format is the same that is * used in java.text.SimpleDateFormat. If the format is not * specified or is invalid, the default format is used. * The default format is yyyy/MM/dd HH:mm:ss:SSS zzz.
  • *
*

* In addition to looking for system properties with the names specified * above, this implementation also checks for a class loader resource named * "simplelog.properties", and includes any matching definitions * from this resource (if it exists). * * @version $Id: SimpleLog.java 1435115 2013-01-18 12:40:19Z tn $ */ public class SimpleLog implements Log, Serializable { /** Serializable version identifier. */ private static final long serialVersionUID = 136942970684951178L; // ------------------------------------------------------- Class Attributes /** All system properties used by SimpleLog start with this */ static protected final String systemPrefix = "org.apache.commons.logging.simplelog."; /** Properties loaded from simplelog.properties */ static protected final Properties simpleLogProps = new Properties(); /** The default format to use when formating dates */ static protected final String DEFAULT_DATE_TIME_FORMAT = "yyyy/MM/dd HH:mm:ss:SSS zzz"; /** Include the instance name in the log message? */ static volatile protected boolean showLogName = false; /** Include the short name ( last component ) of the logger in the log * message. Defaults to true - otherwise we'll be lost in a flood of * messages without knowing who sends them. */ static volatile protected boolean showShortName = true; /** Include the current time in the log message */ static volatile protected boolean showDateTime = false; /** The date and time format to use in the log message */ static volatile protected String dateTimeFormat = DEFAULT_DATE_TIME_FORMAT; /** * Used to format times. *

* Any code that accesses this object should first obtain a lock on it, * ie use synchronized(dateFormatter); this requirement was introduced * in 1.1.1 to fix an existing thread safety bug (SimpleDateFormat.format * is not thread-safe). */ static protected DateFormat dateFormatter = null; // ---------------------------------------------------- Log Level Constants /** "Trace" level logging. */ public static final int LOG_LEVEL_TRACE = 1; /** "Debug" level logging. */ public static final int LOG_LEVEL_DEBUG = 2; /** "Info" level logging. */ public static final int LOG_LEVEL_INFO = 3; /** "Warn" level logging. */ public static final int LOG_LEVEL_WARN = 4; /** "Error" level logging. */ public static final int LOG_LEVEL_ERROR = 5; /** "Fatal" level logging. */ public static final int LOG_LEVEL_FATAL = 6; /** Enable all logging levels */ public static final int LOG_LEVEL_ALL = LOG_LEVEL_TRACE - 1; /** Enable no logging levels */ public static final int LOG_LEVEL_OFF = LOG_LEVEL_FATAL + 1; // ------------------------------------------------------------ Initializer private static String getStringProperty(String name) { String prop = null; try { prop = System.getProperty(name); } catch (SecurityException e) { // Ignore } return prop == null ? simpleLogProps.getProperty(name) : prop; } private static String getStringProperty(String name, String dephault) { String prop = getStringProperty(name); return prop == null ? dephault : prop; } private static boolean getBooleanProperty(String name, boolean dephault) { String prop = getStringProperty(name); return prop == null ? dephault : "true".equalsIgnoreCase(prop); } // Initialize class attributes. // Load properties file, if found. // Override with system properties. static { // Add props from the resource simplelog.properties InputStream in = getResourceAsStream("simplelog.properties"); if(null != in) { try { simpleLogProps.load(in); in.close(); } catch(java.io.IOException e) { // ignored } } showLogName = getBooleanProperty(systemPrefix + "showlogname", showLogName); showShortName = getBooleanProperty(systemPrefix + "showShortLogname", showShortName); showDateTime = getBooleanProperty(systemPrefix + "showdatetime", showDateTime); if(showDateTime) { dateTimeFormat = getStringProperty(systemPrefix + "dateTimeFormat", dateTimeFormat); try { dateFormatter = new SimpleDateFormat(dateTimeFormat); } catch(IllegalArgumentException e) { // If the format pattern is invalid - use the default format dateTimeFormat = DEFAULT_DATE_TIME_FORMAT; dateFormatter = new SimpleDateFormat(dateTimeFormat); } } } // ------------------------------------------------------------- Attributes /** The name of this simple log instance */ protected volatile String logName = null; /** The current log level */ protected volatile int currentLogLevel; /** The short name of this simple log instance */ private volatile String shortLogName = null; // ------------------------------------------------------------ Constructor /** * Construct a simple log with given name. * * @param name log name */ public SimpleLog(String name) { logName = name; // Set initial log level // Used to be: set default log level to ERROR // IMHO it should be lower, but at least info ( costin ). setLevel(SimpleLog.LOG_LEVEL_INFO); // Set log level from properties String lvl = getStringProperty(systemPrefix + "log." + logName); int i = String.valueOf(name).lastIndexOf("."); while(null == lvl && i > -1) { name = name.substring(0,i); lvl = getStringProperty(systemPrefix + "log." + name); i = String.valueOf(name).lastIndexOf("."); } if(null == lvl) { lvl = getStringProperty(systemPrefix + "defaultlog"); } if("all".equalsIgnoreCase(lvl)) { setLevel(SimpleLog.LOG_LEVEL_ALL); } else if("trace".equalsIgnoreCase(lvl)) { setLevel(SimpleLog.LOG_LEVEL_TRACE); } else if("debug".equalsIgnoreCase(lvl)) { setLevel(SimpleLog.LOG_LEVEL_DEBUG); } else if("info".equalsIgnoreCase(lvl)) { setLevel(SimpleLog.LOG_LEVEL_INFO); } else if("warn".equalsIgnoreCase(lvl)) { setLevel(SimpleLog.LOG_LEVEL_WARN); } else if("error".equalsIgnoreCase(lvl)) { setLevel(SimpleLog.LOG_LEVEL_ERROR); } else if("fatal".equalsIgnoreCase(lvl)) { setLevel(SimpleLog.LOG_LEVEL_FATAL); } else if("off".equalsIgnoreCase(lvl)) { setLevel(SimpleLog.LOG_LEVEL_OFF); } } // -------------------------------------------------------- Properties /** * Set logging level. * * @param currentLogLevel new logging level */ public void setLevel(int currentLogLevel) { this.currentLogLevel = currentLogLevel; } /** * Get logging level. */ public int getLevel() { return currentLogLevel; } // -------------------------------------------------------- Logging Methods /** * Do the actual logging. *

* This method assembles the message and then calls write() * to cause it to be written. * * @param type One of the LOG_LEVEL_XXX constants defining the log level * @param message The message itself (typically a String) * @param t The exception whose stack trace should be logged */ protected void log(int type, Object message, Throwable t) { // Use a string buffer for better performance final StringBuffer buf = new StringBuffer(); // Append date-time if so configured if(showDateTime) { final Date now = new Date(); String dateText; synchronized(dateFormatter) { dateText = dateFormatter.format(now); } buf.append(dateText); buf.append(" "); } // Append a readable representation of the log level switch(type) { case SimpleLog.LOG_LEVEL_TRACE: buf.append("[TRACE] "); break; case SimpleLog.LOG_LEVEL_DEBUG: buf.append("[DEBUG] "); break; case SimpleLog.LOG_LEVEL_INFO: buf.append("[INFO] "); break; case SimpleLog.LOG_LEVEL_WARN: buf.append("[WARN] "); break; case SimpleLog.LOG_LEVEL_ERROR: buf.append("[ERROR] "); break; case SimpleLog.LOG_LEVEL_FATAL: buf.append("[FATAL] "); break; } // Append the name of the log instance if so configured if(showShortName) { if(shortLogName == null) { // Cut all but the last component of the name for both styles final String slName = logName.substring(logName.lastIndexOf(".") + 1); shortLogName = slName.substring(slName.lastIndexOf("/") + 1); } buf.append(String.valueOf(shortLogName)).append(" - "); } else if(showLogName) { buf.append(String.valueOf(logName)).append(" - "); } // Append the message buf.append(String.valueOf(message)); // Append stack trace if not null if(t != null) { buf.append(" <"); buf.append(t.toString()); buf.append(">"); final java.io.StringWriter sw = new java.io.StringWriter(1024); final java.io.PrintWriter pw = new java.io.PrintWriter(sw); t.printStackTrace(pw); pw.close(); buf.append(sw.toString()); } // Print to the appropriate destination write(buf); } /** * Write the content of the message accumulated in the specified * StringBuffer to the appropriate output destination. The * default implementation writes to System.err. * * @param buffer A StringBuffer containing the accumulated * text to be logged */ protected void write(StringBuffer buffer) { System.err.println(buffer.toString()); } /** * Is the given log level currently enabled? * * @param logLevel is this level enabled? */ protected boolean isLevelEnabled(int logLevel) { // log level are numerically ordered so can use simple numeric // comparison return logLevel >= currentLogLevel; } // -------------------------------------------------------- Log Implementation /** * Logs a message with * org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_DEBUG. * * @param message to log * @see org.apache.commons.logging.Log#debug(Object) */ public final void debug(Object message) { if (isLevelEnabled(SimpleLog.LOG_LEVEL_DEBUG)) { log(SimpleLog.LOG_LEVEL_DEBUG, message, null); } } /** * Logs a message with * org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_DEBUG. * * @param message to log * @param t log this cause * @see org.apache.commons.logging.Log#debug(Object, Throwable) */ public final void debug(Object message, Throwable t) { if (isLevelEnabled(SimpleLog.LOG_LEVEL_DEBUG)) { log(SimpleLog.LOG_LEVEL_DEBUG, message, t); } } /** * Logs a message with org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_TRACE. * * @param message to log * @see org.apache.commons.logging.Log#trace(Object) */ public final void trace(Object message) { if (isLevelEnabled(SimpleLog.LOG_LEVEL_TRACE)) { log(SimpleLog.LOG_LEVEL_TRACE, message, null); } } /** * Logs a message with org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_TRACE. * * @param message to log * @param t log this cause * @see org.apache.commons.logging.Log#trace(Object, Throwable) */ public final void trace(Object message, Throwable t) { if (isLevelEnabled(SimpleLog.LOG_LEVEL_TRACE)) { log(SimpleLog.LOG_LEVEL_TRACE, message, t); } } /** * Logs a message with org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_INFO. * * @param message to log * @see org.apache.commons.logging.Log#info(Object) */ public final void info(Object message) { if (isLevelEnabled(SimpleLog.LOG_LEVEL_INFO)) { log(SimpleLog.LOG_LEVEL_INFO,message,null); } } /** * Logs a message with org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_INFO. * * @param message to log * @param t log this cause * @see org.apache.commons.logging.Log#info(Object, Throwable) */ public final void info(Object message, Throwable t) { if (isLevelEnabled(SimpleLog.LOG_LEVEL_INFO)) { log(SimpleLog.LOG_LEVEL_INFO, message, t); } } /** * Logs a message with org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_WARN. * * @param message to log * @see org.apache.commons.logging.Log#warn(Object) */ public final void warn(Object message) { if (isLevelEnabled(SimpleLog.LOG_LEVEL_WARN)) { log(SimpleLog.LOG_LEVEL_WARN, message, null); } } /** * Logs a message with org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_WARN. * * @param message to log * @param t log this cause * @see org.apache.commons.logging.Log#warn(Object, Throwable) */ public final void warn(Object message, Throwable t) { if (isLevelEnabled(SimpleLog.LOG_LEVEL_WARN)) { log(SimpleLog.LOG_LEVEL_WARN, message, t); } } /** * Logs a message with org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_ERROR. * * @param message to log * @see org.apache.commons.logging.Log#error(Object) */ public final void error(Object message) { if (isLevelEnabled(SimpleLog.LOG_LEVEL_ERROR)) { log(SimpleLog.LOG_LEVEL_ERROR, message, null); } } /** * Logs a message with org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_ERROR. * * @param message to log * @param t log this cause * @see org.apache.commons.logging.Log#error(Object, Throwable) */ public final void error(Object message, Throwable t) { if (isLevelEnabled(SimpleLog.LOG_LEVEL_ERROR)) { log(SimpleLog.LOG_LEVEL_ERROR, message, t); } } /** * Log a message with org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_FATAL. * * @param message to log * @see org.apache.commons.logging.Log#fatal(Object) */ public final void fatal(Object message) { if (isLevelEnabled(SimpleLog.LOG_LEVEL_FATAL)) { log(SimpleLog.LOG_LEVEL_FATAL, message, null); } } /** * Logs a message with org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_FATAL. * * @param message to log * @param t log this cause * @see org.apache.commons.logging.Log#fatal(Object, Throwable) */ public final void fatal(Object message, Throwable t) { if (isLevelEnabled(SimpleLog.LOG_LEVEL_FATAL)) { log(SimpleLog.LOG_LEVEL_FATAL, message, t); } } /** * Are debug messages currently enabled? *

* This allows expensive operations such as String * concatenation to be avoided when the message will be ignored by the * logger. */ public final boolean isDebugEnabled() { return isLevelEnabled(SimpleLog.LOG_LEVEL_DEBUG); } /** * Are error messages currently enabled? *

* This allows expensive operations such as String * concatenation to be avoided when the message will be ignored by the * logger. */ public final boolean isErrorEnabled() { return isLevelEnabled(SimpleLog.LOG_LEVEL_ERROR); } /** * Are fatal messages currently enabled? *

* This allows expensive operations such as String * concatenation to be avoided when the message will be ignored by the * logger. */ public final boolean isFatalEnabled() { return isLevelEnabled(SimpleLog.LOG_LEVEL_FATAL); } /** * Are info messages currently enabled? *

* This allows expensive operations such as String * concatenation to be avoided when the message will be ignored by the * logger. */ public final boolean isInfoEnabled() { return isLevelEnabled(SimpleLog.LOG_LEVEL_INFO); } /** * Are trace messages currently enabled? *

* This allows expensive operations such as String * concatenation to be avoided when the message will be ignored by the * logger. */ public final boolean isTraceEnabled() { return isLevelEnabled(SimpleLog.LOG_LEVEL_TRACE); } /** * Are warn messages currently enabled? *

* This allows expensive operations such as String * concatenation to be avoided when the message will be ignored by the * logger. */ public final boolean isWarnEnabled() { return isLevelEnabled(SimpleLog.LOG_LEVEL_WARN); } /** * Return the thread context class loader if available. * Otherwise return null. * * The thread context class loader is available for JDK 1.2 * or later, if certain security conditions are met. * * @exception LogConfigurationException if a suitable class loader * cannot be identified. */ private static ClassLoader getContextClassLoader() { ClassLoader classLoader = null; try { // Are we running on a JDK 1.2 or later system? final Method method = Thread.class.getMethod("getContextClassLoader", (Class[]) null); // Get the thread context class loader (if there is one) try { classLoader = (ClassLoader)method.invoke(Thread.currentThread(), (Class[]) null); } catch (IllegalAccessException e) { // ignore } catch (InvocationTargetException e) { /** * InvocationTargetException is thrown by 'invoke' when * the method being invoked (getContextClassLoader) throws * an exception. * * getContextClassLoader() throws SecurityException when * the context class loader isn't an ancestor of the * calling class's class loader, or if security * permissions are restricted. * * In the first case (not related), we want to ignore and * keep going. We cannot help but also ignore the second * with the logic below, but other calls elsewhere (to * obtain a class loader) will trigger this exception where * we can make a distinction. */ if (e.getTargetException() instanceof SecurityException) { // ignore } else { // Capture 'e.getTargetException()' exception for details // alternate: log 'e.getTargetException()', and pass back 'e'. throw new LogConfigurationException ("Unexpected InvocationTargetException", e.getTargetException()); } } } catch (NoSuchMethodException e) { // Assume we are running on JDK 1.1 // ignore } if (classLoader == null) { classLoader = SimpleLog.class.getClassLoader(); } // Return the selected class loader return classLoader; } private static InputStream getResourceAsStream(final String name) { return (InputStream)AccessController.doPrivileged( new PrivilegedAction() { public Object run() { ClassLoader threadCL = getContextClassLoader(); if (threadCL != null) { return threadCL.getResourceAsStream(name); } else { return ClassLoader.getSystemResourceAsStream(name); } } }); } } commons-logging-1.1.3-src/src/main/java/org/apache/commons/logging/impl/ServletContextCleaner.java100664 15042 12145235705 31257 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.logging.impl; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import org.apache.commons.logging.LogFactory; /** * This class is capable of receiving notifications about the undeployment of * a webapp, and responds by ensuring that commons-logging releases all * memory associated with the undeployed webapp. *

* In general, the WeakHashtable support added in commons-logging release 1.1 * ensures that logging classes do not hold references that prevent an * undeployed webapp's memory from being garbage-collected even when multiple * copies of commons-logging are deployed via multiple classloaders (a * situation that earlier versions had problems with). However there are * some rare cases where the WeakHashtable approach does not work; in these * situations specifying this class as a listener for the web application will * ensure that all references held by commons-logging are fully released. *

* To use this class, configure the webapp deployment descriptor to call * this class on webapp undeploy; the contextDestroyed method will tell * every accessible LogFactory class that the entry in its map for the * current webapp's context classloader should be cleared. * * @version $Id: ServletContextCleaner.java 1432580 2013-01-13 10:41:05Z tn $ * @since 1.1 */ public class ServletContextCleaner implements ServletContextListener { private static final Class[] RELEASE_SIGNATURE = {ClassLoader.class}; /** * Invoked when a webapp is undeployed, this tells the LogFactory * class to release any logging information related to the current * contextClassloader. */ public void contextDestroyed(ServletContextEvent sce) { ClassLoader tccl = Thread.currentThread().getContextClassLoader(); Object[] params = new Object[1]; params[0] = tccl; // Walk up the tree of classloaders, finding all the available // LogFactory classes and releasing any objects associated with // the tccl (ie the webapp). // // When there is only one LogFactory in the classpath, and it // is within the webapp being undeployed then there is no problem; // garbage collection works fine. // // When there are multiple LogFactory classes in the classpath but // parent-first classloading is used everywhere, this loop is really // short. The first instance of LogFactory found will // be the highest in the classpath, and then no more will be found. // This is ok, as with this setup this will be the only LogFactory // holding any data associated with the tccl being released. // // When there are multiple LogFactory classes in the classpath and // child-first classloading is used in any classloader, then multiple // LogFactory instances may hold info about this TCCL; whenever the // webapp makes a call into a class loaded via an ancestor classloader // and that class calls LogFactory the tccl gets registered in // the LogFactory instance that is visible from the ancestor // classloader. However the concrete logging library it points // to is expected to have been loaded via the TCCL, so the // underlying logging lib is only initialised/configured once. // These references from ancestor LogFactory classes down to // TCCL classloaders are held via weak references and so should // be released but there are circumstances where they may not. // Walking up the classloader ancestry ladder releasing // the current tccl at each level tree, though, will definitely // clear any problem references. ClassLoader loader = tccl; while (loader != null) { // Load via the current loader. Note that if the class is not accessible // via this loader, but is accessible via some ancestor then that class // will be returned. try { Class logFactoryClass = loader.loadClass("org.apache.commons.logging.LogFactory"); Method releaseMethod = logFactoryClass.getMethod("release", RELEASE_SIGNATURE); releaseMethod.invoke(null, params); loader = logFactoryClass.getClassLoader().getParent(); } catch(ClassNotFoundException ex) { // Neither the current classloader nor any of its ancestors could find // the LogFactory class, so we can stop now. loader = null; } catch(NoSuchMethodException ex) { // This is not expected; every version of JCL has this method System.err.println("LogFactory instance found which does not support release method!"); loader = null; } catch(IllegalAccessException ex) { // This is not expected; every ancestor class should be accessible System.err.println("LogFactory instance found which is not accessable!"); loader = null; } catch(InvocationTargetException ex) { // This is not expected System.err.println("LogFactory instance release method failed!"); loader = null; } } // Just to be sure, invoke release on the LogFactory that is visible from // this ServletContextCleaner class too. This should already have been caught // by the above loop but just in case... LogFactory.release(tccl); } /** * Invoked when a webapp is deployed. Nothing needs to be done here. */ public void contextInitialized(ServletContextEvent sce) { // do nothing } } commons-logging-1.1.3-src/src/main/java/org/apache/commons/logging/impl/Jdk14Logger.java100664 20436 12145235705 27014 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.logging.impl; import java.io.Serializable; import java.util.logging.Level; import java.util.logging.Logger; import org.apache.commons.logging.Log; /** * Implementation of the org.apache.commons.logging.Log * interface that wraps the standard JDK logging mechanisms that were * introduced in the Merlin release (JDK 1.4). * * @version $Id: Jdk14Logger.java 1448063 2013-02-20 10:01:41Z tn $ */ public class Jdk14Logger implements Log, Serializable { /** Serializable version identifier. */ private static final long serialVersionUID = 4784713551416303804L; /** * This member variable simply ensures that any attempt to initialise * this class in a pre-1.4 JVM will result in an ExceptionInInitializerError. * It must not be private, as an optimising compiler could detect that it * is not used and optimise it away. */ protected static final Level dummyLevel = Level.FINE; // ----------------------------------------------------------- Constructors /** * Construct a named instance of this Logger. * * @param name Name of the logger to be constructed */ public Jdk14Logger(String name) { this.name = name; logger = getLogger(); } // ----------------------------------------------------- Instance Variables /** * The underlying Logger implementation we are using. */ protected transient Logger logger = null; /** * The name of the logger we are wrapping. */ protected String name = null; // --------------------------------------------------------- Protected Methods protected void log( Level level, String msg, Throwable ex ) { Logger logger = getLogger(); if (logger.isLoggable(level)) { // Hack (?) to get the stack trace. Throwable dummyException = new Throwable(); StackTraceElement locations[] = dummyException.getStackTrace(); // LOGGING-132: use the provided logger name instead of the class name String cname = name; String method = "unknown"; // Caller will be the third element if( locations != null && locations.length > 2 ) { StackTraceElement caller = locations[2]; method = caller.getMethodName(); } if( ex == null ) { logger.logp( level, cname, method, msg ); } else { logger.logp( level, cname, method, msg, ex ); } } } // --------------------------------------------------------- Public Methods /** * Logs a message with java.util.logging.Level.FINE. * * @param message to log * @see org.apache.commons.logging.Log#debug(Object) */ public void debug(Object message) { log(Level.FINE, String.valueOf(message), null); } /** * Logs a message with java.util.logging.Level.FINE. * * @param message to log * @param exception log this cause * @see org.apache.commons.logging.Log#debug(Object, Throwable) */ public void debug(Object message, Throwable exception) { log(Level.FINE, String.valueOf(message), exception); } /** * Logs a message with java.util.logging.Level.SEVERE. * * @param message to log * @see org.apache.commons.logging.Log#error(Object) */ public void error(Object message) { log(Level.SEVERE, String.valueOf(message), null); } /** * Logs a message with java.util.logging.Level.SEVERE. * * @param message to log * @param exception log this cause * @see org.apache.commons.logging.Log#error(Object, Throwable) */ public void error(Object message, Throwable exception) { log(Level.SEVERE, String.valueOf(message), exception); } /** * Logs a message with java.util.logging.Level.SEVERE. * * @param message to log * @see org.apache.commons.logging.Log#fatal(Object) */ public void fatal(Object message) { log(Level.SEVERE, String.valueOf(message), null); } /** * Logs a message with java.util.logging.Level.SEVERE. * * @param message to log * @param exception log this cause * @see org.apache.commons.logging.Log#fatal(Object, Throwable) */ public void fatal(Object message, Throwable exception) { log(Level.SEVERE, String.valueOf(message), exception); } /** * Return the native Logger instance we are using. */ public Logger getLogger() { if (logger == null) { logger = Logger.getLogger(name); } return logger; } /** * Logs a message with java.util.logging.Level.INFO. * * @param message to log * @see org.apache.commons.logging.Log#info(Object) */ public void info(Object message) { log(Level.INFO, String.valueOf(message), null); } /** * Logs a message with java.util.logging.Level.INFO. * * @param message to log * @param exception log this cause * @see org.apache.commons.logging.Log#info(Object, Throwable) */ public void info(Object message, Throwable exception) { log(Level.INFO, String.valueOf(message), exception); } /** * Is debug logging currently enabled? */ public boolean isDebugEnabled() { return getLogger().isLoggable(Level.FINE); } /** * Is error logging currently enabled? */ public boolean isErrorEnabled() { return getLogger().isLoggable(Level.SEVERE); } /** * Is fatal logging currently enabled? */ public boolean isFatalEnabled() { return getLogger().isLoggable(Level.SEVERE); } /** * Is info logging currently enabled? */ public boolean isInfoEnabled() { return getLogger().isLoggable(Level.INFO); } /** * Is trace logging currently enabled? */ public boolean isTraceEnabled() { return getLogger().isLoggable(Level.FINEST); } /** * Is warn logging currently enabled? */ public boolean isWarnEnabled() { return getLogger().isLoggable(Level.WARNING); } /** * Logs a message with java.util.logging.Level.FINEST. * * @param message to log * @see org.apache.commons.logging.Log#trace(Object) */ public void trace(Object message) { log(Level.FINEST, String.valueOf(message), null); } /** * Logs a message with java.util.logging.Level.FINEST. * * @param message to log * @param exception log this cause * @see org.apache.commons.logging.Log#trace(Object, Throwable) */ public void trace(Object message, Throwable exception) { log(Level.FINEST, String.valueOf(message), exception); } /** * Logs a message with java.util.logging.Level.WARNING. * * @param message to log * @see org.apache.commons.logging.Log#warn(Object) */ public void warn(Object message) { log(Level.WARNING, String.valueOf(message), null); } /** * Logs a message with java.util.logging.Level.WARNING. * * @param message to log * @param exception log this cause * @see org.apache.commons.logging.Log#warn(Object, Throwable) */ public void warn(Object message, Throwable exception) { log(Level.WARNING, String.valueOf(message), exception); } } commons-logging-1.1.3-src/src/main/java/org/apache/commons/logging/impl/AvalonLogger.java100664 23615 12145235705 27361 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.logging.impl; import org.apache.avalon.framework.logger.Logger; import org.apache.commons.logging.Log; /** * Implementation of commons-logging Log interface that delegates all * logging calls to the Avalon logging abstraction: the Logger interface. *

* There are two ways in which this class can be used: *

    *
  • the instance can be constructed with an Avalon logger * (by calling {@link #AvalonLogger(Logger)}). In this case, it acts * as a simple thin wrapping implementation over the logger. This is * particularly useful when using a property setter. *
  • *
  • the {@link #setDefaultLogger} class property can be called which * sets the ancestral Avalon logger for this class. Any AvalonLogger * instances created through the LogFactory mechanisms will output * to child loggers of this Logger. *
  • *
*

* Note: AvalonLogger does not implement Serializable * because the constructors available for it make this impossible to achieve in all * circumstances; there is no way to "reconnect" to an underlying Logger object on * deserialization if one was just passed in to the constructor of the original * object. This class was marked Serializable in the 1.0.4 release of * commons-logging, but this never actually worked (a NullPointerException would * be thrown as soon as the deserialized object was used), so removing this marker * is not considered to be an incompatible change. * * @version $Id: AvalonLogger.java 1435115 2013-01-18 12:40:19Z tn $ */ public class AvalonLogger implements Log { /** Ancestral Avalon logger. */ private static volatile Logger defaultLogger = null; /** Avalon logger used to perform log. */ private final transient Logger logger; /** * Constructs an AvalonLogger that outputs to the given * Logger instance. * * @param logger the Avalon logger implementation to delegate to */ public AvalonLogger(Logger logger) { this.logger = logger; } /** * Constructs an AvalonLogger that will log to a child * of the Logger set by calling {@link #setDefaultLogger}. * * @param name the name of the avalon logger implementation to delegate to */ public AvalonLogger(String name) { if (defaultLogger == null) { throw new NullPointerException("default logger has to be specified if this constructor is used!"); } this.logger = defaultLogger.getChildLogger(name); } /** * Gets the Avalon logger implementation used to perform logging. * * @return avalon logger implementation */ public Logger getLogger() { return logger; } /** * Sets the ancestral Avalon logger from which the delegating loggers will descend. * * @param logger the default avalon logger, * in case there is no logger instance supplied in constructor */ public static void setDefaultLogger(Logger logger) { defaultLogger = logger; } /** * Logs a message with org.apache.avalon.framework.logger.Logger.debug. * * @param message to log * @param t log this cause * @see org.apache.commons.logging.Log#debug(Object, Throwable) */ public void debug(Object message, Throwable t) { if (getLogger().isDebugEnabled()) { getLogger().debug(String.valueOf(message), t); } } /** * Logs a message with org.apache.avalon.framework.logger.Logger.debug. * * @param message to log. * @see org.apache.commons.logging.Log#debug(Object) */ public void debug(Object message) { if (getLogger().isDebugEnabled()) { getLogger().debug(String.valueOf(message)); } } /** * Logs a message with org.apache.avalon.framework.logger.Logger.error. * * @param message to log * @param t log this cause * @see org.apache.commons.logging.Log#error(Object, Throwable) */ public void error(Object message, Throwable t) { if (getLogger().isErrorEnabled()) { getLogger().error(String.valueOf(message), t); } } /** * Logs a message with org.apache.avalon.framework.logger.Logger.error. * * @param message to log * @see org.apache.commons.logging.Log#error(Object) */ public void error(Object message) { if (getLogger().isErrorEnabled()) { getLogger().error(String.valueOf(message)); } } /** * Logs a message with org.apache.avalon.framework.logger.Logger.fatalError. * * @param message to log. * @param t log this cause. * @see org.apache.commons.logging.Log#fatal(Object, Throwable) */ public void fatal(Object message, Throwable t) { if (getLogger().isFatalErrorEnabled()) { getLogger().fatalError(String.valueOf(message), t); } } /** * Logs a message with org.apache.avalon.framework.logger.Logger.fatalError. * * @param message to log * @see org.apache.commons.logging.Log#fatal(Object) */ public void fatal(Object message) { if (getLogger().isFatalErrorEnabled()) { getLogger().fatalError(String.valueOf(message)); } } /** * Logs a message with org.apache.avalon.framework.logger.Logger.info. * * @param message to log * @param t log this cause * @see org.apache.commons.logging.Log#info(Object, Throwable) */ public void info(Object message, Throwable t) { if (getLogger().isInfoEnabled()) { getLogger().info(String.valueOf(message), t); } } /** * Logs a message with org.apache.avalon.framework.logger.Logger.info. * * @param message to log * @see org.apache.commons.logging.Log#info(Object) */ public void info(Object message) { if (getLogger().isInfoEnabled()) { getLogger().info(String.valueOf(message)); } } /** * Is logging to org.apache.avalon.framework.logger.Logger.debug enabled? * @see org.apache.commons.logging.Log#isDebugEnabled() */ public boolean isDebugEnabled() { return getLogger().isDebugEnabled(); } /** * Is logging to org.apache.avalon.framework.logger.Logger.error enabled? * @see org.apache.commons.logging.Log#isErrorEnabled() */ public boolean isErrorEnabled() { return getLogger().isErrorEnabled(); } /** * Is logging to org.apache.avalon.framework.logger.Logger.fatalError enabled? * @see org.apache.commons.logging.Log#isFatalEnabled() */ public boolean isFatalEnabled() { return getLogger().isFatalErrorEnabled(); } /** * Is logging to org.apache.avalon.framework.logger.Logger.info enabled? * @see org.apache.commons.logging.Log#isInfoEnabled() */ public boolean isInfoEnabled() { return getLogger().isInfoEnabled(); } /** * Is logging to org.apache.avalon.framework.logger.Logger.debug enabled? * @see org.apache.commons.logging.Log#isTraceEnabled() */ public boolean isTraceEnabled() { return getLogger().isDebugEnabled(); } /** * Is logging to org.apache.avalon.framework.logger.Logger.warn enabled? * @see org.apache.commons.logging.Log#isWarnEnabled() */ public boolean isWarnEnabled() { return getLogger().isWarnEnabled(); } /** * Logs a message with org.apache.avalon.framework.logger.Logger.debug. * * @param message to log. * @param t log this cause. * @see org.apache.commons.logging.Log#trace(Object, Throwable) */ public void trace(Object message, Throwable t) { if (getLogger().isDebugEnabled()) { getLogger().debug(String.valueOf(message), t); } } /** * Logs a message with org.apache.avalon.framework.logger.Logger.debug. * * @param message to log * @see org.apache.commons.logging.Log#trace(Object) */ public void trace(Object message) { if (getLogger().isDebugEnabled()) { getLogger().debug(String.valueOf(message)); } } /** * Logs a message with org.apache.avalon.framework.logger.Logger.warn. * * @param message to log * @param t log this cause * @see org.apache.commons.logging.Log#warn(Object, Throwable) */ public void warn(Object message, Throwable t) { if (getLogger().isWarnEnabled()) { getLogger().warn(String.valueOf(message), t); } } /** * Logs a message with org.apache.avalon.framework.logger.Logger.warn. * * @param message to log * @see org.apache.commons.logging.Log#warn(Object) */ public void warn(Object message) { if (getLogger().isWarnEnabled()) { getLogger().warn(String.valueOf(message)); } } } commons-logging-1.1.3-src/src/main/java/org/apache/commons/logging/impl/LogKitLogger.java100664 20037 12145235705 27325 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.logging.impl; import java.io.Serializable; import org.apache.log.Logger; import org.apache.log.Hierarchy; import org.apache.commons.logging.Log; /** * Implementation of org.apache.commons.logging.Log * that wraps the avalon-logkit * logging system. Configuration of LogKit is left to the user. *

* LogKit accepts only String messages. * Therefore, this implementation converts object messages into strings * by called their toString() method before logging them. * * @version $Id: LogKitLogger.java 1448119 2013-02-20 12:28:04Z tn $ */ public class LogKitLogger implements Log, Serializable { /** Serializable version identifier. */ private static final long serialVersionUID = 3768538055836059519L; // ------------------------------------------------------------- Attributes /** Logging goes to this LogKit logger */ protected transient volatile Logger logger = null; /** Name of this logger */ protected String name = null; // ------------------------------------------------------------ Constructor /** * Construct LogKitLogger which wraps the LogKit * logger with given name. * * @param name log name */ public LogKitLogger(String name) { this.name = name; this.logger = getLogger(); } // --------------------------------------------------------- Public Methods /** * Return the underlying Logger we are using. */ public Logger getLogger() { Logger result = logger; if (result == null) { synchronized(this) { result = logger; if (result == null) { logger = result = Hierarchy.getDefaultHierarchy().getLoggerFor(name); } } } return result; } // ----------------------------------------------------- Log Implementation /** * Logs a message with org.apache.log.Priority.DEBUG. * * @param message to log * @see org.apache.commons.logging.Log#trace(Object) */ public void trace(Object message) { debug(message); } /** * Logs a message with org.apache.log.Priority.DEBUG. * * @param message to log * @param t log this cause * @see org.apache.commons.logging.Log#trace(Object, Throwable) */ public void trace(Object message, Throwable t) { debug(message, t); } /** * Logs a message with org.apache.log.Priority.DEBUG. * * @param message to log * @see org.apache.commons.logging.Log#debug(Object) */ public void debug(Object message) { if (message != null) { getLogger().debug(String.valueOf(message)); } } /** * Logs a message with org.apache.log.Priority.DEBUG. * * @param message to log * @param t log this cause * @see org.apache.commons.logging.Log#debug(Object, Throwable) */ public void debug(Object message, Throwable t) { if (message != null) { getLogger().debug(String.valueOf(message), t); } } /** * Logs a message with org.apache.log.Priority.INFO. * * @param message to log * @see org.apache.commons.logging.Log#info(Object) */ public void info(Object message) { if (message != null) { getLogger().info(String.valueOf(message)); } } /** * Logs a message with org.apache.log.Priority.INFO. * * @param message to log * @param t log this cause * @see org.apache.commons.logging.Log#info(Object, Throwable) */ public void info(Object message, Throwable t) { if (message != null) { getLogger().info(String.valueOf(message), t); } } /** * Logs a message with org.apache.log.Priority.WARN. * * @param message to log * @see org.apache.commons.logging.Log#warn(Object) */ public void warn(Object message) { if (message != null) { getLogger().warn(String.valueOf(message)); } } /** * Logs a message with org.apache.log.Priority.WARN. * * @param message to log * @param t log this cause * @see org.apache.commons.logging.Log#warn(Object, Throwable) */ public void warn(Object message, Throwable t) { if (message != null) { getLogger().warn(String.valueOf(message), t); } } /** * Logs a message with org.apache.log.Priority.ERROR. * * @param message to log * @see org.apache.commons.logging.Log#error(Object) */ public void error(Object message) { if (message != null) { getLogger().error(String.valueOf(message)); } } /** * Logs a message with org.apache.log.Priority.ERROR. * * @param message to log * @param t log this cause * @see org.apache.commons.logging.Log#error(Object, Throwable) */ public void error(Object message, Throwable t) { if (message != null) { getLogger().error(String.valueOf(message), t); } } /** * Logs a message with org.apache.log.Priority.FATAL_ERROR. * * @param message to log * @see org.apache.commons.logging.Log#fatal(Object) */ public void fatal(Object message) { if (message != null) { getLogger().fatalError(String.valueOf(message)); } } /** * Logs a message with org.apache.log.Priority.FATAL_ERROR. * * @param message to log * @param t log this cause * @see org.apache.commons.logging.Log#fatal(Object, Throwable) */ public void fatal(Object message, Throwable t) { if (message != null) { getLogger().fatalError(String.valueOf(message), t); } } /** * Checks whether the LogKit logger will log messages of priority DEBUG. */ public boolean isDebugEnabled() { return getLogger().isDebugEnabled(); } /** * Checks whether the LogKit logger will log messages of priority ERROR. */ public boolean isErrorEnabled() { return getLogger().isErrorEnabled(); } /** * Checks whether the LogKit logger will log messages of priority FATAL_ERROR. */ public boolean isFatalEnabled() { return getLogger().isFatalErrorEnabled(); } /** * Checks whether the LogKit logger will log messages of priority INFO. */ public boolean isInfoEnabled() { return getLogger().isInfoEnabled(); } /** * Checks whether the LogKit logger will log messages of priority DEBUG. */ public boolean isTraceEnabled() { return getLogger().isDebugEnabled(); } /** * Checks whether the LogKit logger will log messages of priority WARN. */ public boolean isWarnEnabled() { return getLogger().isWarnEnabled(); } } commons-logging-1.1.3-src/src/main/java/org/apache/commons/logging/impl/LogFactoryImpl.java100664 161022 12145235705 27707 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.logging.impl; import java.io.PrintWriter; import java.io.StringWriter; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.URL; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.Hashtable; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogConfigurationException; import org.apache.commons.logging.LogFactory; /** * Concrete subclass of {@link LogFactory} that implements the * following algorithm to dynamically select a logging implementation * class to instantiate a wrapper for: *

    *
  • Use a factory configuration attribute named * org.apache.commons.logging.Log to identify the * requested implementation class.
  • *
  • Use the org.apache.commons.logging.Log system property * to identify the requested implementation class.
  • *
  • If Log4J is available, return an instance of * org.apache.commons.logging.impl.Log4JLogger.
  • *
  • If JDK 1.4 or later is available, return an instance of * org.apache.commons.logging.impl.Jdk14Logger.
  • *
  • Otherwise, return an instance of * org.apache.commons.logging.impl.SimpleLog.
  • *
*

* If the selected {@link Log} implementation class has a * setLogFactory() method that accepts a {@link LogFactory} * parameter, this method will be called on each newly created instance * to identify the associated factory. This makes factory configuration * attributes available to the Log instance, if it so desires. *

* This factory will remember previously created Log instances * for the same name, and will return them on repeated requests to the * getInstance() method. * * @version $Id: LogFactoryImpl.java 1449064 2013-02-22 14:49:22Z tn $ */ public class LogFactoryImpl extends LogFactory { /** Log4JLogger class name */ private static final String LOGGING_IMPL_LOG4J_LOGGER = "org.apache.commons.logging.impl.Log4JLogger"; /** Jdk14Logger class name */ private static final String LOGGING_IMPL_JDK14_LOGGER = "org.apache.commons.logging.impl.Jdk14Logger"; /** Jdk13LumberjackLogger class name */ private static final String LOGGING_IMPL_LUMBERJACK_LOGGER = "org.apache.commons.logging.impl.Jdk13LumberjackLogger"; /** SimpleLog class name */ private static final String LOGGING_IMPL_SIMPLE_LOGGER = "org.apache.commons.logging.impl.SimpleLog"; private static final String PKG_IMPL="org.apache.commons.logging.impl."; private static final int PKG_LEN = PKG_IMPL.length(); // ----------------------------------------------------------- Constructors /** * Public no-arguments constructor required by the lookup mechanism. */ public LogFactoryImpl() { super(); initDiagnostics(); // method on this object if (isDiagnosticsEnabled()) { logDiagnostic("Instance created."); } } // ----------------------------------------------------- Manifest Constants /** * The name (org.apache.commons.logging.Log) of the system * property identifying our {@link Log} implementation class. */ public static final String LOG_PROPERTY = "org.apache.commons.logging.Log"; /** * The deprecated system property used for backwards compatibility with * old versions of JCL. */ protected static final String LOG_PROPERTY_OLD = "org.apache.commons.logging.log"; /** * The name (org.apache.commons.logging.Log.allowFlawedContext) * of the system property which can be set true/false to * determine system behaviour when a bad context-classloader is encountered. * When set to false, a LogConfigurationException is thrown if * LogFactoryImpl is loaded via a child classloader of the TCCL (this * should never happen in sane systems). * * Default behaviour: true (tolerates bad context classloaders) * * See also method setAttribute. */ public static final String ALLOW_FLAWED_CONTEXT_PROPERTY = "org.apache.commons.logging.Log.allowFlawedContext"; /** * The name (org.apache.commons.logging.Log.allowFlawedDiscovery) * of the system property which can be set true/false to * determine system behaviour when a bad logging adapter class is * encountered during logging discovery. When set to false, an * exception will be thrown and the app will fail to start. When set * to true, discovery will continue (though the user might end up * with a different logging implementation than they expected). *

* Default behaviour: true (tolerates bad logging adapters) * * See also method setAttribute. */ public static final String ALLOW_FLAWED_DISCOVERY_PROPERTY = "org.apache.commons.logging.Log.allowFlawedDiscovery"; /** * The name (org.apache.commons.logging.Log.allowFlawedHierarchy) * of the system property which can be set true/false to * determine system behaviour when a logging adapter class is * encountered which has bound to the wrong Log class implementation. * When set to false, an exception will be thrown and the app will fail * to start. When set to true, discovery will continue (though the user * might end up with a different logging implementation than they expected). *

* Default behaviour: true (tolerates bad Log class hierarchy) * * See also method setAttribute. */ public static final String ALLOW_FLAWED_HIERARCHY_PROPERTY = "org.apache.commons.logging.Log.allowFlawedHierarchy"; /** * The names of classes that will be tried (in order) as logging * adapters. Each class is expected to implement the Log interface, * and to throw NoClassDefFound or ExceptionInInitializerError when * loaded if the underlying logging library is not available. Any * other error indicates that the underlying logging library is available * but broken/unusable for some reason. */ private static final String[] classesToDiscover = { LOGGING_IMPL_LOG4J_LOGGER, "org.apache.commons.logging.impl.Jdk14Logger", "org.apache.commons.logging.impl.Jdk13LumberjackLogger", "org.apache.commons.logging.impl.SimpleLog" }; // ----------------------------------------------------- Instance Variables /** * Determines whether logging classes should be loaded using the thread-context * classloader, or via the classloader that loaded this LogFactoryImpl class. */ private boolean useTCCL = true; /** * The string prefixed to every message output by the logDiagnostic method. */ private String diagnosticPrefix; /** * Configuration attributes. */ protected Hashtable attributes = new Hashtable(); /** * The {@link org.apache.commons.logging.Log} instances that have * already been created, keyed by logger name. */ protected Hashtable instances = new Hashtable(); /** * Name of the class implementing the Log interface. */ private String logClassName; /** * The one-argument constructor of the * {@link org.apache.commons.logging.Log} * implementation class that will be used to create new instances. * This value is initialized by getLogConstructor(), * and then returned repeatedly. */ protected Constructor logConstructor = null; /** * The signature of the Constructor to be used. */ protected Class logConstructorSignature[] = { java.lang.String.class }; /** * The one-argument setLogFactory method of the selected * {@link org.apache.commons.logging.Log} method, if it exists. */ protected Method logMethod = null; /** * The signature of the setLogFactory method to be used. */ protected Class logMethodSignature[] = { LogFactory.class }; /** * See getBaseClassLoader and initConfiguration. */ private boolean allowFlawedContext; /** * See handleFlawedDiscovery and initConfiguration. */ private boolean allowFlawedDiscovery; /** * See handleFlawedHierarchy and initConfiguration. */ private boolean allowFlawedHierarchy; // --------------------------------------------------------- Public Methods /** * Return the configuration attribute with the specified name (if any), * or null if there is no such attribute. * * @param name Name of the attribute to return */ public Object getAttribute(String name) { return attributes.get(name); } /** * Return an array containing the names of all currently defined * configuration attributes. If there are no such attributes, a zero * length array is returned. */ public String[] getAttributeNames() { return (String[]) attributes.keySet().toArray(new String[attributes.size()]); } /** * Convenience method to derive a name from the specified class and * call getInstance(String) with it. * * @param clazz Class for which a suitable Log name will be derived * * @exception LogConfigurationException if a suitable Log * instance cannot be returned */ public Log getInstance(Class clazz) throws LogConfigurationException { return getInstance(clazz.getName()); } /** *

Construct (if necessary) and return a Log instance, * using the factory's current set of configuration attributes.

* *

NOTE - Depending upon the implementation of * the LogFactory you are using, the Log * instance you are returned may or may not be local to the current * application, and may or may not be returned again on a subsequent * call with the same name argument.

* * @param name Logical name of the Log instance to be * returned (the meaning of this name is only known to the underlying * logging implementation that is being wrapped) * * @exception LogConfigurationException if a suitable Log * instance cannot be returned */ public Log getInstance(String name) throws LogConfigurationException { Log instance = (Log) instances.get(name); if (instance == null) { instance = newInstance(name); instances.put(name, instance); } return instance; } /** * Release any internal references to previously created * {@link org.apache.commons.logging.Log} * instances returned by this factory. This is useful in environments * like servlet containers, which implement application reloading by * throwing away a ClassLoader. Dangling references to objects in that * class loader would prevent garbage collection. */ public void release() { logDiagnostic("Releasing all known loggers"); instances.clear(); } /** * Remove any configuration attribute associated with the specified name. * If there is no such attribute, no action is taken. * * @param name Name of the attribute to remove */ public void removeAttribute(String name) { attributes.remove(name); } /** * Set the configuration attribute with the specified name. Calling * this with a null value is equivalent to calling * removeAttribute(name). *

* This method can be used to set logging configuration programmatically * rather than via system properties. It can also be used in code running * within a container (such as a webapp) to configure behaviour on a * per-component level instead of globally as system properties would do. * To use this method instead of a system property, call *

     * LogFactory.getFactory().setAttribute(...)
     * 
* This must be done before the first Log object is created; configuration * changes after that point will be ignored. *

* This method is also called automatically if LogFactory detects a * commons-logging.properties file; every entry in that file is set * automatically as an attribute here. * * @param name Name of the attribute to set * @param value Value of the attribute to set, or null * to remove any setting for this attribute */ public void setAttribute(String name, Object value) { if (logConstructor != null) { logDiagnostic("setAttribute: call too late; configuration already performed."); } if (value == null) { attributes.remove(name); } else { attributes.put(name, value); } if (name.equals(TCCL_KEY)) { useTCCL = value != null && Boolean.valueOf(value.toString()).booleanValue(); } } // ------------------------------------------------------ // Static Methods // // These methods only defined as workarounds for a java 1.2 bug; // theoretically none of these are needed. // ------------------------------------------------------ /** * Gets the context classloader. * This method is a workaround for a java 1.2 compiler bug. * @since 1.1 */ protected static ClassLoader getContextClassLoader() throws LogConfigurationException { return LogFactory.getContextClassLoader(); } /** * Workaround for bug in Java1.2; in theory this method is not needed. * See LogFactory.isDiagnosticsEnabled. */ protected static boolean isDiagnosticsEnabled() { return LogFactory.isDiagnosticsEnabled(); } /** * Workaround for bug in Java1.2; in theory this method is not needed. * See LogFactory.getClassLoader. * @since 1.1 */ protected static ClassLoader getClassLoader(Class clazz) { return LogFactory.getClassLoader(clazz); } // ------------------------------------------------------ Protected Methods /** * Calculate and cache a string that uniquely identifies this instance, * including which classloader the object was loaded from. *

* This string will later be prefixed to each "internal logging" message * emitted, so that users can clearly see any unexpected behaviour. *

* Note that this method does not detect whether internal logging is * enabled or not, nor where to output stuff if it is; that is all * handled by the parent LogFactory class. This method just computes * its own unique prefix for log messages. */ private void initDiagnostics() { // It would be nice to include an identifier of the context classloader // that this LogFactoryImpl object is responsible for. However that // isn't possible as that information isn't available. It is possible // to figure this out by looking at the logging from LogFactory to // see the context & impl ids from when this object was instantiated, // in order to link the impl id output as this object's prefix back to // the context it is intended to manage. // Note that this prefix should be kept consistent with that // in LogFactory. Class clazz = this.getClass(); ClassLoader classLoader = getClassLoader(clazz); String classLoaderName; try { if (classLoader == null) { classLoaderName = "BOOTLOADER"; } else { classLoaderName = objectId(classLoader); } } catch (SecurityException e) { classLoaderName = "UNKNOWN"; } diagnosticPrefix = "[LogFactoryImpl@" + System.identityHashCode(this) + " from " + classLoaderName + "] "; } /** * Output a diagnostic message to a user-specified destination (if the * user has enabled diagnostic logging). * * @param msg diagnostic message * @since 1.1 */ protected void logDiagnostic(String msg) { if (isDiagnosticsEnabled()) { logRawDiagnostic(diagnosticPrefix + msg); } } /** * Return the fully qualified Java classname of the {@link Log} * implementation we will be using. * * @deprecated Never invoked by this class; subclasses should not assume * it will be. */ protected String getLogClassName() { if (logClassName == null) { discoverLogImplementation(getClass().getName()); } return logClassName; } /** *

Return the Constructor that can be called to instantiate * new {@link org.apache.commons.logging.Log} instances.

* *

IMPLEMENTATION NOTE - Race conditions caused by * calling this method from more than one thread are ignored, because * the same Constructor instance will ultimately be derived * in all circumstances.

* * @exception LogConfigurationException if a suitable constructor * cannot be returned * * @deprecated Never invoked by this class; subclasses should not assume * it will be. */ protected Constructor getLogConstructor() throws LogConfigurationException { // Return the previously identified Constructor (if any) if (logConstructor == null) { discoverLogImplementation(getClass().getName()); } return logConstructor; } /** * Is JDK 1.3 with Lumberjack logging available? * * @deprecated Never invoked by this class; subclasses should not assume * it will be. */ protected boolean isJdk13LumberjackAvailable() { return isLogLibraryAvailable( "Jdk13Lumberjack", "org.apache.commons.logging.impl.Jdk13LumberjackLogger"); } /** * Return true if JDK 1.4 or later logging * is available. Also checks that the Throwable class * supports getStackTrace(), which is required by * Jdk14Logger. * * @deprecated Never invoked by this class; subclasses should not assume * it will be. */ protected boolean isJdk14Available() { return isLogLibraryAvailable( "Jdk14", "org.apache.commons.logging.impl.Jdk14Logger"); } /** * Is a Log4J implementation available? * * @deprecated Never invoked by this class; subclasses should not assume * it will be. */ protected boolean isLog4JAvailable() { return isLogLibraryAvailable( "Log4J", LOGGING_IMPL_LOG4J_LOGGER); } /** * Create and return a new {@link org.apache.commons.logging.Log} * instance for the specified name. * * @param name Name of the new logger * * @exception LogConfigurationException if a new instance cannot * be created */ protected Log newInstance(String name) throws LogConfigurationException { Log instance; try { if (logConstructor == null) { instance = discoverLogImplementation(name); } else { Object params[] = { name }; instance = (Log) logConstructor.newInstance(params); } if (logMethod != null) { Object params[] = { this }; logMethod.invoke(instance, params); } return instance; } catch (LogConfigurationException lce) { // this type of exception means there was a problem in discovery // and we've already output diagnostics about the issue, etc.; // just pass it on throw lce; } catch (InvocationTargetException e) { // A problem occurred invoking the Constructor or Method // previously discovered Throwable c = e.getTargetException(); throw new LogConfigurationException(c == null ? e : c); } catch (Throwable t) { handleThrowable(t); // may re-throw t // A problem occurred invoking the Constructor or Method // previously discovered throw new LogConfigurationException(t); } } // ------------------------------------------------------ Private Methods /** * Calls LogFactory.directGetContextClassLoader under the control of an * AccessController class. This means that java code running under a * security manager that forbids access to ClassLoaders will still work * if this class is given appropriate privileges, even when the caller * doesn't have such privileges. Without using an AccessController, the * the entire call stack must have the privilege before the call is * allowed. * * @return the context classloader associated with the current thread, * or null if security doesn't allow it. * * @throws LogConfigurationException if there was some weird error while * attempting to get the context classloader. * * @throws SecurityException if the current java security policy doesn't * allow this class to access the context classloader. */ private static ClassLoader getContextClassLoaderInternal() throws LogConfigurationException { return (ClassLoader)AccessController.doPrivileged( new PrivilegedAction() { public Object run() { return LogFactory.directGetContextClassLoader(); } }); } /** * Read the specified system property, using an AccessController so that * the property can be read if JCL has been granted the appropriate * security rights even if the calling code has not. *

* Take care not to expose the value returned by this method to the * calling application in any way; otherwise the calling app can use that * info to access data that should not be available to it. */ private static String getSystemProperty(final String key, final String def) throws SecurityException { return (String) AccessController.doPrivileged( new PrivilegedAction() { public Object run() { return System.getProperty(key, def); } }); } /** * Fetch the parent classloader of a specified classloader. *

* If a SecurityException occurs, null is returned. *

* Note that this method is non-static merely so logDiagnostic is available. */ private ClassLoader getParentClassLoader(final ClassLoader cl) { try { return (ClassLoader)AccessController.doPrivileged( new PrivilegedAction() { public Object run() { return cl.getParent(); } }); } catch (SecurityException ex) { logDiagnostic("[SECURITY] Unable to obtain parent classloader"); return null; } } /** * Utility method to check whether a particular logging library is * present and available for use. Note that this does not * affect the future behaviour of this class. */ private boolean isLogLibraryAvailable(String name, String classname) { if (isDiagnosticsEnabled()) { logDiagnostic("Checking for '" + name + "'."); } try { Log log = createLogFromClass( classname, this.getClass().getName(), // dummy category false); if (log == null) { if (isDiagnosticsEnabled()) { logDiagnostic("Did not find '" + name + "'."); } return false; } else { if (isDiagnosticsEnabled()) { logDiagnostic("Found '" + name + "'."); } return true; } } catch (LogConfigurationException e) { if (isDiagnosticsEnabled()) { logDiagnostic("Logging system '" + name + "' is available but not useable."); } return false; } } /** * Attempt to find an attribute (see method setAttribute) or a * system property with the provided name and return its value. *

* The attributes associated with this object are checked before * system properties in case someone has explicitly called setAttribute, * or a configuration property has been set in a commons-logging.properties * file. * * @return the value associated with the property, or null. */ private String getConfigurationValue(String property) { if (isDiagnosticsEnabled()) { logDiagnostic("[ENV] Trying to get configuration for item " + property); } Object valueObj = getAttribute(property); if (valueObj != null) { if (isDiagnosticsEnabled()) { logDiagnostic("[ENV] Found LogFactory attribute [" + valueObj + "] for " + property); } return valueObj.toString(); } if (isDiagnosticsEnabled()) { logDiagnostic("[ENV] No LogFactory attribute found for " + property); } try { // warning: minor security hole here, in that we potentially read a system // property that the caller cannot, then output it in readable form as a // diagnostic message. However it's only ever JCL-specific properties // involved here, so the harm is truly trivial. String value = getSystemProperty(property, null); if (value != null) { if (isDiagnosticsEnabled()) { logDiagnostic("[ENV] Found system property [" + value + "] for " + property); } return value; } if (isDiagnosticsEnabled()) { logDiagnostic("[ENV] No system property found for property " + property); } } catch (SecurityException e) { if (isDiagnosticsEnabled()) { logDiagnostic("[ENV] Security prevented reading system property " + property); } } if (isDiagnosticsEnabled()) { logDiagnostic("[ENV] No configuration defined for item " + property); } return null; } /** * Get the setting for the user-configurable behaviour specified by key. * If nothing has explicitly been set, then return dflt. */ private boolean getBooleanConfiguration(String key, boolean dflt) { String val = getConfigurationValue(key); if (val == null) { return dflt; } return Boolean.valueOf(val).booleanValue(); } /** * Initialize a number of variables that control the behaviour of this * class and that can be tweaked by the user. This is done when the first * logger is created, not in the constructor of this class, because we * need to give the user a chance to call method setAttribute in order to * configure this object. */ private void initConfiguration() { allowFlawedContext = getBooleanConfiguration(ALLOW_FLAWED_CONTEXT_PROPERTY, true); allowFlawedDiscovery = getBooleanConfiguration(ALLOW_FLAWED_DISCOVERY_PROPERTY, true); allowFlawedHierarchy = getBooleanConfiguration(ALLOW_FLAWED_HIERARCHY_PROPERTY, true); } /** * Attempts to create a Log instance for the given category name. * Follows the discovery process described in the class javadoc. * * @param logCategory the name of the log category * * @throws LogConfigurationException if an error in discovery occurs, * or if no adapter at all can be instantiated */ private Log discoverLogImplementation(String logCategory) throws LogConfigurationException { if (isDiagnosticsEnabled()) { logDiagnostic("Discovering a Log implementation..."); } initConfiguration(); Log result = null; // See if the user specified the Log implementation to use String specifiedLogClassName = findUserSpecifiedLogClassName(); if (specifiedLogClassName != null) { if (isDiagnosticsEnabled()) { logDiagnostic("Attempting to load user-specified log class '" + specifiedLogClassName + "'..."); } result = createLogFromClass(specifiedLogClassName, logCategory, true); if (result == null) { StringBuffer messageBuffer = new StringBuffer("User-specified log class '"); messageBuffer.append(specifiedLogClassName); messageBuffer.append("' cannot be found or is not useable."); // Mistyping or misspelling names is a common fault. // Construct a good error message, if we can informUponSimilarName(messageBuffer, specifiedLogClassName, LOGGING_IMPL_LOG4J_LOGGER); informUponSimilarName(messageBuffer, specifiedLogClassName, LOGGING_IMPL_JDK14_LOGGER); informUponSimilarName(messageBuffer, specifiedLogClassName, LOGGING_IMPL_LUMBERJACK_LOGGER); informUponSimilarName(messageBuffer, specifiedLogClassName, LOGGING_IMPL_SIMPLE_LOGGER); throw new LogConfigurationException(messageBuffer.toString()); } return result; } // No user specified log; try to discover what's on the classpath // // Note that we deliberately loop here over classesToDiscover and // expect method createLogFromClass to loop over the possible source // classloaders. The effect is: // for each discoverable log adapter // for each possible classloader // see if it works // // It appears reasonable at first glance to do the opposite: // for each possible classloader // for each discoverable log adapter // see if it works // // The latter certainly has advantages for user-installable logging // libraries such as log4j; in a webapp for example this code should // first check whether the user has provided any of the possible // logging libraries before looking in the parent classloader. // Unfortunately, however, Jdk14Logger will always work in jvm>=1.4, // and SimpleLog will always work in any JVM. So the loop would never // ever look for logging libraries in the parent classpath. Yet many // users would expect that putting log4j there would cause it to be // detected (and this is the historical JCL behaviour). So we go with // the first approach. A user that has bundled a specific logging lib // in a webapp should use a commons-logging.properties file or a // service file in META-INF to force use of that logging lib anyway, // rather than relying on discovery. if (isDiagnosticsEnabled()) { logDiagnostic( "No user-specified Log implementation; performing discovery" + " using the standard supported logging implementations..."); } for(int i=0; iStringBuffer the message should be appended to, * not null * @param name the (trimmed) name to be test against the candidate, not null * @param candidate the candidate name (not null) */ private void informUponSimilarName(final StringBuffer messageBuffer, final String name, final String candidate) { if (name.equals(candidate)) { // Don't suggest a name that is exactly the same as the one the // user tried... return; } // If the user provides a name that is in the right package, and gets // the first 5 characters of the adapter class right (ignoring case), // then suggest the candidate adapter class name. if (name.regionMatches(true, 0, candidate, 0, PKG_LEN + 5)) { messageBuffer.append(" Did you mean '"); messageBuffer.append(candidate); messageBuffer.append("'?"); } } /** * Checks system properties and the attribute map for * a Log implementation specified by the user under the * property names {@link #LOG_PROPERTY} or {@link #LOG_PROPERTY_OLD}. * * @return classname specified by the user, or null */ private String findUserSpecifiedLogClassName() { if (isDiagnosticsEnabled()) { logDiagnostic("Trying to get log class from attribute '" + LOG_PROPERTY + "'"); } String specifiedClass = (String) getAttribute(LOG_PROPERTY); if (specifiedClass == null) { // @deprecated if (isDiagnosticsEnabled()) { logDiagnostic("Trying to get log class from attribute '" + LOG_PROPERTY_OLD + "'"); } specifiedClass = (String) getAttribute(LOG_PROPERTY_OLD); } if (specifiedClass == null) { if (isDiagnosticsEnabled()) { logDiagnostic("Trying to get log class from system property '" + LOG_PROPERTY + "'"); } try { specifiedClass = getSystemProperty(LOG_PROPERTY, null); } catch (SecurityException e) { if (isDiagnosticsEnabled()) { logDiagnostic("No access allowed to system property '" + LOG_PROPERTY + "' - " + e.getMessage()); } } } if (specifiedClass == null) { // @deprecated if (isDiagnosticsEnabled()) { logDiagnostic("Trying to get log class from system property '" + LOG_PROPERTY_OLD + "'"); } try { specifiedClass = getSystemProperty(LOG_PROPERTY_OLD, null); } catch (SecurityException e) { if (isDiagnosticsEnabled()) { logDiagnostic("No access allowed to system property '" + LOG_PROPERTY_OLD + "' - " + e.getMessage()); } } } // Remove any whitespace; it's never valid in a classname so its // presence just means a user mistake. As we know what they meant, // we may as well strip the spaces. if (specifiedClass != null) { specifiedClass = specifiedClass.trim(); } return specifiedClass; } /** * Attempts to load the given class, find a suitable constructor, * and instantiate an instance of Log. * * @param logAdapterClassName classname of the Log implementation * @param logCategory argument to pass to the Log implementation's constructor * @param affectState true if this object's state should * be affected by this method call, false otherwise. * @return an instance of the given class, or null if the logging * library associated with the specified adapter is not available. * @throws LogConfigurationException if there was a serious error with * configuration and the handleFlawedDiscovery method decided this * problem was fatal. */ private Log createLogFromClass(String logAdapterClassName, String logCategory, boolean affectState) throws LogConfigurationException { if (isDiagnosticsEnabled()) { logDiagnostic("Attempting to instantiate '" + logAdapterClassName + "'"); } Object[] params = { logCategory }; Log logAdapter = null; Constructor constructor = null; Class logAdapterClass = null; ClassLoader currentCL = getBaseClassLoader(); for(;;) { // Loop through the classloader hierarchy trying to find // a viable classloader. logDiagnostic("Trying to load '" + logAdapterClassName + "' from classloader " + objectId(currentCL)); try { if (isDiagnosticsEnabled()) { // Show the location of the first occurrence of the .class file // in the classpath. This is the location that ClassLoader.loadClass // will load the class from -- unless the classloader is doing // something weird. URL url; String resourceName = logAdapterClassName.replace('.', '/') + ".class"; if (currentCL != null) { url = currentCL.getResource(resourceName ); } else { url = ClassLoader.getSystemResource(resourceName + ".class"); } if (url == null) { logDiagnostic("Class '" + logAdapterClassName + "' [" + resourceName + "] cannot be found."); } else { logDiagnostic("Class '" + logAdapterClassName + "' was found at '" + url + "'"); } } Class c; try { c = Class.forName(logAdapterClassName, true, currentCL); } catch (ClassNotFoundException originalClassNotFoundException) { // The current classloader was unable to find the log adapter // in this or any ancestor classloader. There's no point in // trying higher up in the hierarchy in this case.. String msg = originalClassNotFoundException.getMessage(); logDiagnostic("The log adapter '" + logAdapterClassName + "' is not available via classloader " + objectId(currentCL) + ": " + msg.trim()); try { // Try the class classloader. // This may work in cases where the TCCL // does not contain the code executed or JCL. // This behaviour indicates that the application // classloading strategy is not consistent with the // Java 1.2 classloading guidelines but JCL can // and so should handle this case. c = Class.forName(logAdapterClassName); } catch (ClassNotFoundException secondaryClassNotFoundException) { // no point continuing: this adapter isn't available msg = secondaryClassNotFoundException.getMessage(); logDiagnostic("The log adapter '" + logAdapterClassName + "' is not available via the LogFactoryImpl class classloader: " + msg.trim()); break; } } constructor = c.getConstructor(logConstructorSignature); Object o = constructor.newInstance(params); // Note that we do this test after trying to create an instance // [rather than testing Log.class.isAssignableFrom(c)] so that // we don't complain about Log hierarchy problems when the // adapter couldn't be instantiated anyway. if (o instanceof Log) { logAdapterClass = c; logAdapter = (Log) o; break; } // Oops, we have a potential problem here. An adapter class // has been found and its underlying lib is present too, but // there are multiple Log interface classes available making it // impossible to cast to the type the caller wanted. We // certainly can't use this logger, but we need to know whether // to keep on discovering or terminate now. // // The handleFlawedHierarchy method will throw // LogConfigurationException if it regards this problem as // fatal, and just return if not. handleFlawedHierarchy(currentCL, c); } catch (NoClassDefFoundError e) { // We were able to load the adapter but it had references to // other classes that could not be found. This simply means that // the underlying logger library is not present in this or any // ancestor classloader. There's no point in trying higher up // in the hierarchy in this case.. String msg = e.getMessage(); logDiagnostic("The log adapter '" + logAdapterClassName + "' is missing dependencies when loaded via classloader " + objectId(currentCL) + ": " + msg.trim()); break; } catch (ExceptionInInitializerError e) { // A static initializer block or the initializer code associated // with a static variable on the log adapter class has thrown // an exception. // // We treat this as meaning the adapter's underlying logging // library could not be found. String msg = e.getMessage(); logDiagnostic("The log adapter '" + logAdapterClassName + "' is unable to initialize itself when loaded via classloader " + objectId(currentCL) + ": " + msg.trim()); break; } catch (LogConfigurationException e) { // call to handleFlawedHierarchy above must have thrown // a LogConfigurationException, so just throw it on throw e; } catch (Throwable t) { handleThrowable(t); // may re-throw t // handleFlawedDiscovery will determine whether this is a fatal // problem or not. If it is fatal, then a LogConfigurationException // will be thrown. handleFlawedDiscovery(logAdapterClassName, currentCL, t); } if (currentCL == null) { break; } // try the parent classloader // currentCL = currentCL.getParent(); currentCL = getParentClassLoader(currentCL); } if (logAdapterClass != null && affectState) { // We've succeeded, so set instance fields this.logClassName = logAdapterClassName; this.logConstructor = constructor; // Identify the setLogFactory method (if there is one) try { this.logMethod = logAdapterClass.getMethod("setLogFactory", logMethodSignature); logDiagnostic("Found method setLogFactory(LogFactory) in '" + logAdapterClassName + "'"); } catch (Throwable t) { handleThrowable(t); // may re-throw t this.logMethod = null; logDiagnostic("[INFO] '" + logAdapterClassName + "' from classloader " + objectId(currentCL) + " does not declare optional method " + "setLogFactory(LogFactory)"); } logDiagnostic("Log adapter '" + logAdapterClassName + "' from classloader " + objectId(logAdapterClass.getClassLoader()) + " has been selected for use."); } return logAdapter; } /** * Return the classloader from which we should try to load the logging * adapter classes. *

* This method usually returns the context classloader. However if it * is discovered that the classloader which loaded this class is a child * of the context classloader and the allowFlawedContext option * has been set then the classloader which loaded this class is returned * instead. *

* The only time when the classloader which loaded this class is a * descendant (rather than the same as or an ancestor of the context * classloader) is when an app has created custom classloaders but * failed to correctly set the context classloader. This is a bug in * the calling application; however we provide the option for JCL to * simply generate a warning rather than fail outright. * */ private ClassLoader getBaseClassLoader() throws LogConfigurationException { ClassLoader thisClassLoader = getClassLoader(LogFactoryImpl.class); if (!useTCCL) { return thisClassLoader; } ClassLoader contextClassLoader = getContextClassLoaderInternal(); ClassLoader baseClassLoader = getLowestClassLoader( contextClassLoader, thisClassLoader); if (baseClassLoader == null) { // The two classloaders are not part of a parent child relationship. // In some classloading setups (e.g. JBoss with its // UnifiedLoaderRepository) this can still work, so if user hasn't // forbidden it, just return the contextClassLoader. if (allowFlawedContext) { if (isDiagnosticsEnabled()) { logDiagnostic("[WARNING] the context classloader is not part of a" + " parent-child relationship with the classloader that" + " loaded LogFactoryImpl."); } // If contextClassLoader were null, getLowestClassLoader() would // have returned thisClassLoader. The fact we are here means // contextClassLoader is not null, so we can just return it. return contextClassLoader; } else { throw new LogConfigurationException("Bad classloader hierarchy; LogFactoryImpl was loaded via" + " a classloader that is not related to the current context" + " classloader."); } } if (baseClassLoader != contextClassLoader) { // We really should just use the contextClassLoader as the starting // point for scanning for log adapter classes. However it is expected // that there are a number of broken systems out there which create // custom classloaders but fail to set the context classloader so // we handle those flawed systems anyway. if (allowFlawedContext) { if (isDiagnosticsEnabled()) { logDiagnostic( "Warning: the context classloader is an ancestor of the" + " classloader that loaded LogFactoryImpl; it should be" + " the same or a descendant. The application using" + " commons-logging should ensure the context classloader" + " is used correctly."); } } else { throw new LogConfigurationException( "Bad classloader hierarchy; LogFactoryImpl was loaded via" + " a classloader that is not related to the current context" + " classloader."); } } return baseClassLoader; } /** * Given two related classloaders, return the one which is a child of * the other. *

* @param c1 is a classloader (including the null classloader) * @param c2 is a classloader (including the null classloader) * * @return c1 if it has c2 as an ancestor, c2 if it has c1 as an ancestor, * and null if neither is an ancestor of the other. */ private ClassLoader getLowestClassLoader(ClassLoader c1, ClassLoader c2) { // TODO: use AccessController when dealing with classloaders here if (c1 == null) { return c2; } if (c2 == null) { return c1; } ClassLoader current; // scan c1's ancestors to find c2 current = c1; while (current != null) { if (current == c2) { return c1; } // current = current.getParent(); current = getParentClassLoader(current); } // scan c2's ancestors to find c1 current = c2; while (current != null) { if (current == c1) { return c2; } // current = current.getParent(); current = getParentClassLoader(current); } return null; } /** * Generates an internal diagnostic logging of the discovery failure and * then throws a LogConfigurationException that wraps * the passed Throwable. * * @param logAdapterClassName is the class name of the Log implementation * that could not be instantiated. Cannot be null. * * @param classLoader is the classloader that we were trying to load the * logAdapterClassName from when the exception occurred. * * @param discoveryFlaw is the Throwable created by the classloader * * @throws LogConfigurationException ALWAYS */ private void handleFlawedDiscovery(String logAdapterClassName, ClassLoader classLoader, // USED? Throwable discoveryFlaw) { if (isDiagnosticsEnabled()) { logDiagnostic("Could not instantiate Log '" + logAdapterClassName + "' -- " + discoveryFlaw.getClass().getName() + ": " + discoveryFlaw.getLocalizedMessage()); if (discoveryFlaw instanceof InvocationTargetException ) { // Ok, the lib is there but while trying to create a real underlying // logger something failed in the underlying lib; display info about // that if possible. InvocationTargetException ite = (InvocationTargetException)discoveryFlaw; Throwable cause = ite.getTargetException(); if (cause != null) { logDiagnostic("... InvocationTargetException: " + cause.getClass().getName() + ": " + cause.getLocalizedMessage()); if (cause instanceof ExceptionInInitializerError) { ExceptionInInitializerError eiie = (ExceptionInInitializerError)cause; Throwable cause2 = eiie.getException(); if (cause2 != null) { final StringWriter sw = new StringWriter(); cause2.printStackTrace(new PrintWriter(sw, true)); logDiagnostic("... ExceptionInInitializerError: " + sw.toString()); } } } } } if (!allowFlawedDiscovery) { throw new LogConfigurationException(discoveryFlaw); } } /** * Report a problem loading the log adapter, then either return * (if the situation is considered recoverable) or throw a * LogConfigurationException. *

* There are two possible reasons why we successfully loaded the * specified log adapter class then failed to cast it to a Log object: *

    *
  1. the specific class just doesn't implement the Log interface * (user screwed up), or *
  2. the specified class has bound to a Log class loaded by some other * classloader; Log@classloaderX cannot be cast to Log@classloaderY. *
*

* Here we try to figure out which case has occurred so we can give the * user some reasonable feedback. * * @param badClassLoader is the classloader we loaded the problem class from, * ie it is equivalent to badClass.getClassLoader(). * * @param badClass is a Class object with the desired name, but which * does not implement Log correctly. * * @throws LogConfigurationException when the situation * should not be recovered from. */ private void handleFlawedHierarchy(ClassLoader badClassLoader, Class badClass) throws LogConfigurationException { boolean implementsLog = false; String logInterfaceName = Log.class.getName(); Class interfaces[] = badClass.getInterfaces(); for (int i = 0; i < interfaces.length; i++) { if (logInterfaceName.equals(interfaces[i].getName())) { implementsLog = true; break; } } if (implementsLog) { // the class does implement an interface called Log, but // it is in the wrong classloader if (isDiagnosticsEnabled()) { try { ClassLoader logInterfaceClassLoader = getClassLoader(Log.class); logDiagnostic("Class '" + badClass.getName() + "' was found in classloader " + objectId(badClassLoader) + ". It is bound to a Log interface which is not" + " the one loaded from classloader " + objectId(logInterfaceClassLoader)); } catch (Throwable t) { handleThrowable(t); // may re-throw t logDiagnostic("Error while trying to output diagnostics about" + " bad class '" + badClass + "'"); } } if (!allowFlawedHierarchy) { StringBuffer msg = new StringBuffer(); msg.append("Terminating logging for this context "); msg.append("due to bad log hierarchy. "); msg.append("You have more than one version of '"); msg.append(Log.class.getName()); msg.append("' visible."); if (isDiagnosticsEnabled()) { logDiagnostic(msg.toString()); } throw new LogConfigurationException(msg.toString()); } if (isDiagnosticsEnabled()) { StringBuffer msg = new StringBuffer(); msg.append("Warning: bad log hierarchy. "); msg.append("You have more than one version of '"); msg.append(Log.class.getName()); msg.append("' visible."); logDiagnostic(msg.toString()); } } else { // this is just a bad adapter class if (!allowFlawedDiscovery) { StringBuffer msg = new StringBuffer(); msg.append("Terminating logging for this context. "); msg.append("Log class '"); msg.append(badClass.getName()); msg.append("' does not implement the Log interface."); if (isDiagnosticsEnabled()) { logDiagnostic(msg.toString()); } throw new LogConfigurationException(msg.toString()); } if (isDiagnosticsEnabled()) { StringBuffer msg = new StringBuffer(); msg.append("[WARNING] Log class '"); msg.append(badClass.getName()); msg.append("' does not implement the Log interface."); logDiagnostic(msg.toString()); } } } } commons-logging-1.1.3-src/src/main/java/org/apache/commons/logging/LogFactory.java100664 235252 12145235706 26134 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.logging; import java.io.BufferedReader; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.PrintStream; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.URL; import java.net.URLConnection; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.Enumeration; import java.util.Hashtable; import java.util.Properties; /** * Factory for creating {@link Log} instances, with discovery and * configuration features similar to that employed by standard Java APIs * such as JAXP. *

* IMPLEMENTATION NOTE - This implementation is heavily * based on the SAXParserFactory and DocumentBuilderFactory implementations * (corresponding to the JAXP pluggability APIs) found in Apache Xerces. * * @version $Id: LogFactory.java 1449064 2013-02-22 14:49:22Z tn $ */ public abstract class LogFactory { // Implementation note re AccessController usage // // It is important to keep code invoked via an AccessController to small // auditable blocks. Such code must carefully evaluate all user input // (parameters, system properties, config file contents, etc). As an // example, a Log implementation should not write to its logfile // with an AccessController anywhere in the call stack, otherwise an // insecure application could configure the log implementation to write // to a protected file using the privileges granted to JCL rather than // to the calling application. // // Under no circumstance should a non-private method return data that is // retrieved via an AccessController. That would allow an insecure app // to invoke that method and obtain data that it is not permitted to have. // // Invoking user-supplied code with an AccessController set is not a major // issue (eg invoking the constructor of the class specified by // HASHTABLE_IMPLEMENTATION_PROPERTY). That class will be in a different // trust domain, and therefore must have permissions to do whatever it // is trying to do regardless of the permissions granted to JCL. There is // a slight issue in that untrusted code may point that environment var // to another trusted library, in which case the code runs if both that // lib and JCL have the necessary permissions even when the untrusted // caller does not. That's a pretty hard route to exploit though. // ----------------------------------------------------- Manifest Constants /** * The name (priority) of the key in the config file used to * specify the priority of that particular config file. The associated value * is a floating-point number; higher values take priority over lower values. */ public static final String PRIORITY_KEY = "priority"; /** * The name (use_tccl) of the key in the config file used * to specify whether logging classes should be loaded via the thread * context class loader (TCCL), or not. By default, the TCCL is used. */ public static final String TCCL_KEY = "use_tccl"; /** * The name (org.apache.commons.logging.LogFactory) of the property * used to identify the LogFactory implementation * class name. This can be used as a system property, or as an entry in a * configuration properties file. */ public static final String FACTORY_PROPERTY = "org.apache.commons.logging.LogFactory"; /** * The fully qualified class name of the fallback LogFactory * implementation class to use, if no other can be found. */ public static final String FACTORY_DEFAULT = "org.apache.commons.logging.impl.LogFactoryImpl"; /** * The name (commons-logging.properties) of the properties file to search for. */ public static final String FACTORY_PROPERTIES = "commons-logging.properties"; /** * JDK1.3+ * 'Service Provider' specification. */ protected static final String SERVICE_ID = "META-INF/services/org.apache.commons.logging.LogFactory"; /** * The name (org.apache.commons.logging.diagnostics.dest) * of the property used to enable internal commons-logging * diagnostic output, in order to get information on what logging * implementations are being discovered, what classloaders they * are loaded through, etc. *

* If a system property of this name is set then the value is * assumed to be the name of a file. The special strings * STDOUT or STDERR (case-sensitive) indicate output to * System.out and System.err respectively. *

* Diagnostic logging should be used only to debug problematic * configurations and should not be set in normal production use. */ public static final String DIAGNOSTICS_DEST_PROPERTY = "org.apache.commons.logging.diagnostics.dest"; /** * When null (the usual case), no diagnostic output will be * generated by LogFactory or LogFactoryImpl. When non-null, * interesting events will be written to the specified object. */ private static PrintStream diagnosticsStream = null; /** * A string that gets prefixed to every message output by the * logDiagnostic method, so that users can clearly see which * LogFactory class is generating the output. */ private static final String diagnosticPrefix; /** * Setting this system property * (org.apache.commons.logging.LogFactory.HashtableImpl) * value allows the Hashtable used to store * classloaders to be substituted by an alternative implementation. *

* Note: LogFactory will print: *

     * [ERROR] LogFactory: Load of custom hashtable failed
     * 
* to system error and then continue using a standard Hashtable. *

* Usage: Set this property when Java is invoked * and LogFactory will attempt to load a new instance * of the given implementation class. * For example, running the following ant scriplet: *

     *  <java classname="${test.runner}" fork="yes" failonerror="${test.failonerror}">
     *     ...
     *     <sysproperty
     *        key="org.apache.commons.logging.LogFactory.HashtableImpl"
     *        value="org.apache.commons.logging.AltHashtable"/>
     *  </java>
     * 
* will mean that LogFactory will load an instance of * org.apache.commons.logging.AltHashtable. *

* A typical use case is to allow a custom * Hashtable implementation using weak references to be substituted. * This will allow classloaders to be garbage collected without * the need to release them (on 1.3+ JVMs only, of course ;). */ public static final String HASHTABLE_IMPLEMENTATION_PROPERTY = "org.apache.commons.logging.LogFactory.HashtableImpl"; /** Name used to load the weak hashtable implementation by names. */ private static final String WEAK_HASHTABLE_CLASSNAME = "org.apache.commons.logging.impl.WeakHashtable"; /** * A reference to the classloader that loaded this class. This is the * same as LogFactory.class.getClassLoader(). However computing this * value isn't quite as simple as that, as we potentially need to use * AccessControllers etc. It's more efficient to compute it once and * cache it here. */ private static final ClassLoader thisClassLoader; // ----------------------------------------------------------- Constructors /** * Protected constructor that is not available for public use. */ protected LogFactory() { } // --------------------------------------------------------- Public Methods /** * Return the configuration attribute with the specified name (if any), * or null if there is no such attribute. * * @param name Name of the attribute to return */ public abstract Object getAttribute(String name); /** * Return an array containing the names of all currently defined * configuration attributes. If there are no such attributes, a zero * length array is returned. */ public abstract String[] getAttributeNames(); /** * Convenience method to derive a name from the specified class and * call getInstance(String) with it. * * @param clazz Class for which a suitable Log name will be derived * @throws LogConfigurationException if a suitable Log * instance cannot be returned */ public abstract Log getInstance(Class clazz) throws LogConfigurationException; /** * Construct (if necessary) and return a Log instance, * using the factory's current set of configuration attributes. *

* NOTE - Depending upon the implementation of * the LogFactory you are using, the Log * instance you are returned may or may not be local to the current * application, and may or may not be returned again on a subsequent * call with the same name argument. * * @param name Logical name of the Log instance to be * returned (the meaning of this name is only known to the underlying * logging implementation that is being wrapped) * @throws LogConfigurationException if a suitable Log * instance cannot be returned */ public abstract Log getInstance(String name) throws LogConfigurationException; /** * Release any internal references to previously created {@link Log} * instances returned by this factory. This is useful in environments * like servlet containers, which implement application reloading by * throwing away a ClassLoader. Dangling references to objects in that * class loader would prevent garbage collection. */ public abstract void release(); /** * Remove any configuration attribute associated with the specified name. * If there is no such attribute, no action is taken. * * @param name Name of the attribute to remove */ public abstract void removeAttribute(String name); /** * Set the configuration attribute with the specified name. Calling * this with a null value is equivalent to calling * removeAttribute(name). * * @param name Name of the attribute to set * @param value Value of the attribute to set, or null * to remove any setting for this attribute */ public abstract void setAttribute(String name, Object value); // ------------------------------------------------------- Static Variables /** * The previously constructed LogFactory instances, keyed by * the ClassLoader with which it was created. */ protected static Hashtable factories = null; /** * Previously constructed LogFactory instance as in the * factories map, but for the case where * getClassLoader returns null. * This can happen when: *

    *
  • using JDK1.1 and the calling code is loaded via the system * classloader (very common)
  • *
  • using JDK1.2+ and the calling code is loaded via the boot * classloader (only likely for embedded systems work).
  • *
* Note that factories is a Hashtable (not a HashMap), * and hashtables don't allow null as a key. * @deprecated since 1.1.2 */ protected static volatile LogFactory nullClassLoaderFactory = null; /** * Create the hashtable which will be used to store a map of * (context-classloader -> logfactory-object). Version 1.2+ of Java * supports "weak references", allowing a custom Hashtable class * to be used which uses only weak references to its keys. Using weak * references can fix memory leaks on webapp unload in some cases (though * not all). Version 1.1 of Java does not support weak references, so we * must dynamically determine which we are using. And just for fun, this * code also supports the ability for a system property to specify an * arbitrary Hashtable implementation name. *

* Note that the correct way to ensure no memory leaks occur is to ensure * that LogFactory.release(contextClassLoader) is called whenever a * webapp is undeployed. */ private static final Hashtable createFactoryStore() { Hashtable result = null; String storeImplementationClass; try { storeImplementationClass = getSystemProperty(HASHTABLE_IMPLEMENTATION_PROPERTY, null); } catch (SecurityException ex) { // Permissions don't allow this to be accessed. Default to the "modern" // weak hashtable implementation if it is available. storeImplementationClass = null; } if (storeImplementationClass == null) { storeImplementationClass = WEAK_HASHTABLE_CLASSNAME; } try { Class implementationClass = Class.forName(storeImplementationClass); result = (Hashtable) implementationClass.newInstance(); } catch (Throwable t) { handleThrowable(t); // may re-throw t // ignore if (!WEAK_HASHTABLE_CLASSNAME.equals(storeImplementationClass)) { // if the user's trying to set up a custom implementation, give a clue if (isDiagnosticsEnabled()) { // use internal logging to issue the warning logDiagnostic("[ERROR] LogFactory: Load of custom hashtable failed"); } else { // we *really* want this output, even if diagnostics weren't // explicitly enabled by the user. System.err.println("[ERROR] LogFactory: Load of custom hashtable failed"); } } } if (result == null) { result = new Hashtable(); } return result; } // --------------------------------------------------------- Static Methods /** Utility method to safely trim a string. */ private static String trim(String src) { if (src == null) { return null; } return src.trim(); } /** * Checks whether the supplied Throwable is one that needs to be * re-thrown and ignores all others. * * The following errors are re-thrown: *

    *
  • ThreadDeath
  • *
  • VirtualMachineError
  • *
* * @param t the Throwable to check */ protected static void handleThrowable(Throwable t) { if (t instanceof ThreadDeath) { throw (ThreadDeath) t; } if (t instanceof VirtualMachineError) { throw (VirtualMachineError) t; } // All other instances of Throwable will be silently ignored } /** * Construct (if necessary) and return a LogFactory * instance, using the following ordered lookup procedure to determine * the name of the implementation class to be loaded. *

*

    *
  • The org.apache.commons.logging.LogFactory system * property.
  • *
  • The JDK 1.3 Service Discovery mechanism
  • *
  • Use the properties file commons-logging.properties * file, if found in the class path of this class. The configuration * file is in standard java.util.Properties format and * contains the fully qualified name of the implementation class * with the key being the system property defined above.
  • *
  • Fall back to a default implementation class * (org.apache.commons.logging.impl.LogFactoryImpl).
  • *
*

* NOTE - If the properties file method of identifying the * LogFactory implementation class is utilized, all of the * properties defined in this file will be set as configuration attributes * on the corresponding LogFactory instance. *

* NOTE - In a multi-threaded environment it is possible * that two different instances will be returned for the same * classloader environment. * * @throws LogConfigurationException if the implementation class is not * available or cannot be instantiated. */ public static LogFactory getFactory() throws LogConfigurationException { // Identify the class loader we will be using ClassLoader contextClassLoader = getContextClassLoaderInternal(); if (contextClassLoader == null) { // This is an odd enough situation to report about. This // output will be a nuisance on JDK1.1, as the system // classloader is null in that environment. if (isDiagnosticsEnabled()) { logDiagnostic("Context classloader is null."); } } // Return any previously registered factory for this class loader LogFactory factory = getCachedFactory(contextClassLoader); if (factory != null) { return factory; } if (isDiagnosticsEnabled()) { logDiagnostic( "[LOOKUP] LogFactory implementation requested for the first time for context classloader " + objectId(contextClassLoader)); logHierarchy("[LOOKUP] ", contextClassLoader); } // Load properties file. // // If the properties file exists, then its contents are used as // "attributes" on the LogFactory implementation class. One particular // property may also control which LogFactory concrete subclass is // used, but only if other discovery mechanisms fail.. // // As the properties file (if it exists) will be used one way or // another in the end we may as well look for it first. Properties props = getConfigurationFile(contextClassLoader, FACTORY_PROPERTIES); // Determine whether we will be using the thread context class loader to // load logging classes or not by checking the loaded properties file (if any). ClassLoader baseClassLoader = contextClassLoader; if (props != null) { String useTCCLStr = props.getProperty(TCCL_KEY); if (useTCCLStr != null) { // The Boolean.valueOf(useTCCLStr).booleanValue() formulation // is required for Java 1.2 compatibility. if (Boolean.valueOf(useTCCLStr).booleanValue() == false) { // Don't use current context classloader when locating any // LogFactory or Log classes, just use the class that loaded // this abstract class. When this class is deployed in a shared // classpath of a container, it means webapps cannot deploy their // own logging implementations. It also means that it is up to the // implementation whether to load library-specific config files // from the TCCL or not. baseClassLoader = thisClassLoader; } } } // Determine which concrete LogFactory subclass to use. // First, try a global system property if (isDiagnosticsEnabled()) { logDiagnostic("[LOOKUP] Looking for system property [" + FACTORY_PROPERTY + "] to define the LogFactory subclass to use..."); } try { String factoryClass = getSystemProperty(FACTORY_PROPERTY, null); if (factoryClass != null) { if (isDiagnosticsEnabled()) { logDiagnostic("[LOOKUP] Creating an instance of LogFactory class '" + factoryClass + "' as specified by system property " + FACTORY_PROPERTY); } factory = newFactory(factoryClass, baseClassLoader, contextClassLoader); } else { if (isDiagnosticsEnabled()) { logDiagnostic("[LOOKUP] No system property [" + FACTORY_PROPERTY + "] defined."); } } } catch (SecurityException e) { if (isDiagnosticsEnabled()) { logDiagnostic("[LOOKUP] A security exception occurred while trying to create an" + " instance of the custom factory class" + ": [" + trim(e.getMessage()) + "]. Trying alternative implementations..."); } // ignore } catch (RuntimeException e) { // This is not consistent with the behaviour when a bad LogFactory class is // specified in a services file. // // One possible exception that can occur here is a ClassCastException when // the specified class wasn't castable to this LogFactory type. if (isDiagnosticsEnabled()) { logDiagnostic("[LOOKUP] An exception occurred while trying to create an" + " instance of the custom factory class" + ": [" + trim(e.getMessage()) + "] as specified by a system property."); } throw e; } // Second, try to find a service by using the JDK1.3 class // discovery mechanism, which involves putting a file with the name // of an interface class in the META-INF/services directory, where the // contents of the file is a single line specifying a concrete class // that implements the desired interface. if (factory == null) { if (isDiagnosticsEnabled()) { logDiagnostic("[LOOKUP] Looking for a resource file of name [" + SERVICE_ID + "] to define the LogFactory subclass to use..."); } try { final InputStream is = getResourceAsStream(contextClassLoader, SERVICE_ID); if( is != null ) { // This code is needed by EBCDIC and other strange systems. // It's a fix for bugs reported in xerces BufferedReader rd; try { rd = new BufferedReader(new InputStreamReader(is, "UTF-8")); } catch (java.io.UnsupportedEncodingException e) { rd = new BufferedReader(new InputStreamReader(is)); } String factoryClassName = rd.readLine(); rd.close(); if (factoryClassName != null && ! "".equals(factoryClassName)) { if (isDiagnosticsEnabled()) { logDiagnostic("[LOOKUP] Creating an instance of LogFactory class " + factoryClassName + " as specified by file '" + SERVICE_ID + "' which was present in the path of the context classloader."); } factory = newFactory(factoryClassName, baseClassLoader, contextClassLoader ); } } else { // is == null if (isDiagnosticsEnabled()) { logDiagnostic("[LOOKUP] No resource file with name '" + SERVICE_ID + "' found."); } } } catch (Exception ex) { // note: if the specified LogFactory class wasn't compatible with LogFactory // for some reason, a ClassCastException will be caught here, and attempts will // continue to find a compatible class. if (isDiagnosticsEnabled()) { logDiagnostic( "[LOOKUP] A security exception occurred while trying to create an" + " instance of the custom factory class" + ": [" + trim(ex.getMessage()) + "]. Trying alternative implementations..."); } // ignore } } // Third try looking into the properties file read earlier (if found) if (factory == null) { if (props != null) { if (isDiagnosticsEnabled()) { logDiagnostic( "[LOOKUP] Looking in properties file for entry with key '" + FACTORY_PROPERTY + "' to define the LogFactory subclass to use..."); } String factoryClass = props.getProperty(FACTORY_PROPERTY); if (factoryClass != null) { if (isDiagnosticsEnabled()) { logDiagnostic( "[LOOKUP] Properties file specifies LogFactory subclass '" + factoryClass + "'"); } factory = newFactory(factoryClass, baseClassLoader, contextClassLoader); // TODO: think about whether we need to handle exceptions from newFactory } else { if (isDiagnosticsEnabled()) { logDiagnostic("[LOOKUP] Properties file has no entry specifying LogFactory subclass."); } } } else { if (isDiagnosticsEnabled()) { logDiagnostic("[LOOKUP] No properties file available to determine" + " LogFactory subclass from.."); } } } // Fourth, try the fallback implementation class if (factory == null) { if (isDiagnosticsEnabled()) { logDiagnostic( "[LOOKUP] Loading the default LogFactory implementation '" + FACTORY_DEFAULT + "' via the same classloader that loaded this LogFactory" + " class (ie not looking in the context classloader)."); } // Note: unlike the above code which can try to load custom LogFactory // implementations via the TCCL, we don't try to load the default LogFactory // implementation via the context classloader because: // * that can cause problems (see comments in newFactory method) // * no-one should be customising the code of the default class // Yes, we do give up the ability for the child to ship a newer // version of the LogFactoryImpl class and have it used dynamically // by an old LogFactory class in the parent, but that isn't // necessarily a good idea anyway. factory = newFactory(FACTORY_DEFAULT, thisClassLoader, contextClassLoader); } if (factory != null) { /** * Always cache using context class loader. */ cacheFactory(contextClassLoader, factory); if (props != null) { Enumeration names = props.propertyNames(); while (names.hasMoreElements()) { String name = (String) names.nextElement(); String value = props.getProperty(name); factory.setAttribute(name, value); } } } return factory; } /** * Convenience method to return a named logger, without the application * having to care about factories. * * @param clazz Class from which a log name will be derived * @throws LogConfigurationException if a suitable Log * instance cannot be returned */ public static Log getLog(Class clazz) throws LogConfigurationException { return getFactory().getInstance(clazz); } /** * Convenience method to return a named logger, without the application * having to care about factories. * * @param name Logical name of the Log instance to be * returned (the meaning of this name is only known to the underlying * logging implementation that is being wrapped) * @throws LogConfigurationException if a suitable Log * instance cannot be returned */ public static Log getLog(String name) throws LogConfigurationException { return getFactory().getInstance(name); } /** * Release any internal references to previously created {@link LogFactory} * instances that have been associated with the specified class loader * (if any), after calling the instance method release() on * each of them. * * @param classLoader ClassLoader for which to release the LogFactory */ public static void release(ClassLoader classLoader) { if (isDiagnosticsEnabled()) { logDiagnostic("Releasing factory for classloader " + objectId(classLoader)); } // factories is not final and could be replaced in this block. final Hashtable factories = LogFactory.factories; synchronized (factories) { if (classLoader == null) { if (nullClassLoaderFactory != null) { nullClassLoaderFactory.release(); nullClassLoaderFactory = null; } } else { final LogFactory factory = (LogFactory) factories.get(classLoader); if (factory != null) { factory.release(); factories.remove(classLoader); } } } } /** * Release any internal references to previously created {@link LogFactory} * instances, after calling the instance method release() on * each of them. This is useful in environments like servlet containers, * which implement application reloading by throwing away a ClassLoader. * Dangling references to objects in that class loader would prevent * garbage collection. */ public static void releaseAll() { if (isDiagnosticsEnabled()) { logDiagnostic("Releasing factory for all classloaders."); } // factories is not final and could be replaced in this block. final Hashtable factories = LogFactory.factories; synchronized (factories) { final Enumeration elements = factories.elements(); while (elements.hasMoreElements()) { LogFactory element = (LogFactory) elements.nextElement(); element.release(); } factories.clear(); if (nullClassLoaderFactory != null) { nullClassLoaderFactory.release(); nullClassLoaderFactory = null; } } } // ------------------------------------------------------ Protected Methods /** * Safely get access to the classloader for the specified class. *

* Theoretically, calling getClassLoader can throw a security exception, * and so should be done under an AccessController in order to provide * maximum flexibility. However in practice people don't appear to use * security policies that forbid getClassLoader calls. So for the moment * all code is written to call this method rather than Class.getClassLoader, * so that we could put AccessController stuff in this method without any * disruption later if we need to. *

* Even when using an AccessController, however, this method can still * throw SecurityException. Commons-logging basically relies on the * ability to access classloaders, ie a policy that forbids all * classloader access will also prevent commons-logging from working: * currently this method will throw an exception preventing the entire app * from starting up. Maybe it would be good to detect this situation and * just disable all commons-logging? Not high priority though - as stated * above, security policies that prevent classloader access aren't common. *

* Note that returning an object fetched via an AccessController would * technically be a security flaw anyway; untrusted code that has access * to a trusted JCL library could use it to fetch the classloader for * a class even when forbidden to do so directly. * * @since 1.1 */ protected static ClassLoader getClassLoader(Class clazz) { try { return clazz.getClassLoader(); } catch (SecurityException ex) { if (isDiagnosticsEnabled()) { logDiagnostic("Unable to get classloader for class '" + clazz + "' due to security restrictions - " + ex.getMessage()); } throw ex; } } /** * Returns the current context classloader. *

* In versions prior to 1.1, this method did not use an AccessController. * In version 1.1, an AccessController wrapper was incorrectly added to * this method, causing a minor security flaw. *

* In version 1.1.1 this change was reverted; this method no longer uses * an AccessController. User code wishing to obtain the context classloader * must invoke this method via AccessController.doPrivileged if it needs * support for that. * * @return the context classloader associated with the current thread, * or null if security doesn't allow it. * @throws LogConfigurationException if there was some weird error while * attempting to get the context classloader. * @throws SecurityException if the current java security policy doesn't * allow this class to access the context classloader. */ protected static ClassLoader getContextClassLoader() throws LogConfigurationException { return directGetContextClassLoader(); } /** * Calls LogFactory.directGetContextClassLoader under the control of an * AccessController class. This means that java code running under a * security manager that forbids access to ClassLoaders will still work * if this class is given appropriate privileges, even when the caller * doesn't have such privileges. Without using an AccessController, the * the entire call stack must have the privilege before the call is * allowed. * * @return the context classloader associated with the current thread, * or null if security doesn't allow it. * @throws LogConfigurationException if there was some weird error while * attempting to get the context classloader. * @throws SecurityException if the current java security policy doesn't * allow this class to access the context classloader. */ private static ClassLoader getContextClassLoaderInternal() throws LogConfigurationException { return (ClassLoader)AccessController.doPrivileged( new PrivilegedAction() { public Object run() { return directGetContextClassLoader(); } }); } /** * Return the thread context class loader if available; otherwise return null. *

* Most/all code should call getContextClassLoaderInternal rather than * calling this method directly. *

* The thread context class loader is available for JDK 1.2 * or later, if certain security conditions are met. *

* Note that no internal logging is done within this method because * this method is called every time LogFactory.getLogger() is called, * and we don't want too much output generated here. * * @throws LogConfigurationException if a suitable class loader * cannot be identified. * @throws SecurityException if the java security policy forbids * access to the context classloader from one of the classes in the * current call stack. * @since 1.1 */ protected static ClassLoader directGetContextClassLoader() throws LogConfigurationException { ClassLoader classLoader = null; try { // Are we running on a JDK 1.2 or later system? final Method method = Thread.class.getMethod("getContextClassLoader", (Class[]) null); // Get the thread context class loader (if there is one) try { classLoader = (ClassLoader)method.invoke(Thread.currentThread(), (Object[]) null); } catch (IllegalAccessException e) { throw new LogConfigurationException ("Unexpected IllegalAccessException", e); } catch (InvocationTargetException e) { /** * InvocationTargetException is thrown by 'invoke' when * the method being invoked (getContextClassLoader) throws * an exception. * * getContextClassLoader() throws SecurityException when * the context class loader isn't an ancestor of the * calling class's class loader, or if security * permissions are restricted. * * In the first case (not related), we want to ignore and * keep going. We cannot help but also ignore the second * with the logic below, but other calls elsewhere (to * obtain a class loader) will trigger this exception where * we can make a distinction. */ if (e.getTargetException() instanceof SecurityException) { // ignore } else { // Capture 'e.getTargetException()' exception for details // alternate: log 'e.getTargetException()', and pass back 'e'. throw new LogConfigurationException("Unexpected InvocationTargetException", e.getTargetException()); } } } catch (NoSuchMethodException e) { // Assume we are running on JDK 1.1 classLoader = getClassLoader(LogFactory.class); // We deliberately don't log a message here to outputStream; // this message would be output for every call to LogFactory.getLog() // when running on JDK1.1 // // if (outputStream != null) { // outputStream.println( // "Method Thread.getContextClassLoader does not exist;" // + " assuming this is JDK 1.1, and that the context" // + " classloader is the same as the class that loaded" // + " the concrete LogFactory class."); // } } // Return the selected class loader return classLoader; } /** * Check cached factories (keyed by contextClassLoader) * * @param contextClassLoader is the context classloader associated * with the current thread. This allows separate LogFactory objects * per component within a container, provided each component has * a distinct context classloader set. This parameter may be null * in JDK1.1, and in embedded systems where jcl-using code is * placed in the bootclasspath. * * @return the factory associated with the specified classloader if * one has previously been created, or null if this is the first time * we have seen this particular classloader. */ private static LogFactory getCachedFactory(ClassLoader contextClassLoader) { if (contextClassLoader == null) { // We have to handle this specially, as factories is a Hashtable // and those don't accept null as a key value. // // nb: nullClassLoaderFactory might be null. That's ok. return nullClassLoaderFactory; } else { return (LogFactory) factories.get(contextClassLoader); } } /** * Remember this factory, so later calls to LogFactory.getCachedFactory * can return the previously created object (together with all its * cached Log objects). * * @param classLoader should be the current context classloader. Note that * this can be null under some circumstances; this is ok. * @param factory should be the factory to cache. This should never be null. */ private static void cacheFactory(ClassLoader classLoader, LogFactory factory) { // Ideally we would assert(factory != null) here. However reporting // errors from within a logging implementation is a little tricky! if (factory != null) { if (classLoader == null) { nullClassLoaderFactory = factory; } else { factories.put(classLoader, factory); } } } /** * Return a new instance of the specified LogFactory * implementation class, loaded by the specified class loader. * If that fails, try the class loader used to load this * (abstract) LogFactory. *

*

ClassLoader conflicts

* Note that there can be problems if the specified ClassLoader is not the * same as the classloader that loaded this class, ie when loading a * concrete LogFactory subclass via a context classloader. *

* The problem is the same one that can occur when loading a concrete Log * subclass via a context classloader. *

* The problem occurs when code running in the context classloader calls * class X which was loaded via a parent classloader, and class X then calls * LogFactory.getFactory (either directly or via LogFactory.getLog). Because * class X was loaded via the parent, it binds to LogFactory loaded via * the parent. When the code in this method finds some LogFactoryYYYY * class in the child (context) classloader, and there also happens to be a * LogFactory class defined in the child classloader, then LogFactoryYYYY * will be bound to LogFactory@childloader. It cannot be cast to * LogFactory@parentloader, ie this method cannot return the object as * the desired type. Note that it doesn't matter if the LogFactory class * in the child classloader is identical to the LogFactory class in the * parent classloader, they are not compatible. *

* The solution taken here is to simply print out an error message when * this occurs then throw an exception. The deployer of the application * must ensure they remove all occurrences of the LogFactory class from * the child classloader in order to resolve the issue. Note that they * do not have to move the custom LogFactory subclass; that is ok as * long as the only LogFactory class it can find to bind to is in the * parent classloader. * * @param factoryClass Fully qualified name of the LogFactory * implementation class * @param classLoader ClassLoader from which to load this class * @param contextClassLoader is the context that this new factory will * manage logging for. * @throws LogConfigurationException if a suitable instance * cannot be created * @since 1.1 */ protected static LogFactory newFactory(final String factoryClass, final ClassLoader classLoader, final ClassLoader contextClassLoader) throws LogConfigurationException { // Note that any unchecked exceptions thrown by the createFactory // method will propagate out of this method; in particular a // ClassCastException can be thrown. Object result = AccessController.doPrivileged( new PrivilegedAction() { public Object run() { return createFactory(factoryClass, classLoader); } }); if (result instanceof LogConfigurationException) { LogConfigurationException ex = (LogConfigurationException) result; if (isDiagnosticsEnabled()) { logDiagnostic("An error occurred while loading the factory class:" + ex.getMessage()); } throw ex; } if (isDiagnosticsEnabled()) { logDiagnostic("Created object " + objectId(result) + " to manage classloader " + objectId(contextClassLoader)); } return (LogFactory)result; } /** * Method provided for backwards compatibility; see newFactory version that * takes 3 parameters. *

* This method would only ever be called in some rather odd situation. * Note that this method is static, so overriding in a subclass doesn't * have any effect unless this method is called from a method in that * subclass. However this method only makes sense to use from the * getFactory method, and as that is almost always invoked via * LogFactory.getFactory, any custom definition in a subclass would be * pointless. Only a class with a custom getFactory method, then invoked * directly via CustomFactoryImpl.getFactory or similar would ever call * this. Anyway, it's here just in case, though the "managed class loader" * value output to the diagnostics will not report the correct value. */ protected static LogFactory newFactory(final String factoryClass, final ClassLoader classLoader) { return newFactory(factoryClass, classLoader, null); } /** * Implements the operations described in the javadoc for newFactory. * * @param factoryClass * @param classLoader used to load the specified factory class. This is * expected to be either the TCCL or the classloader which loaded this * class. Note that the classloader which loaded this class might be * "null" (ie the bootloader) for embedded systems. * @return either a LogFactory object or a LogConfigurationException object. * @since 1.1 */ protected static Object createFactory(String factoryClass, ClassLoader classLoader) { // This will be used to diagnose bad configurations // and allow a useful message to be sent to the user Class logFactoryClass = null; try { if (classLoader != null) { try { // First the given class loader param (thread class loader) // Warning: must typecast here & allow exception // to be generated/caught & recast properly. logFactoryClass = classLoader.loadClass(factoryClass); if (LogFactory.class.isAssignableFrom(logFactoryClass)) { if (isDiagnosticsEnabled()) { logDiagnostic("Loaded class " + logFactoryClass.getName() + " from classloader " + objectId(classLoader)); } } else { // // This indicates a problem with the ClassLoader tree. // An incompatible ClassLoader was used to load the // implementation. // As the same classes // must be available in multiple class loaders, // it is very likely that multiple JCL jars are present. // The most likely fix for this // problem is to remove the extra JCL jars from the // ClassLoader hierarchy. // if (isDiagnosticsEnabled()) { logDiagnostic("Factory class " + logFactoryClass.getName() + " loaded from classloader " + objectId(logFactoryClass.getClassLoader()) + " does not extend '" + LogFactory.class.getName() + "' as loaded by this classloader."); logHierarchy("[BAD CL TREE] ", classLoader); } } return (LogFactory) logFactoryClass.newInstance(); } catch (ClassNotFoundException ex) { if (classLoader == thisClassLoader) { // Nothing more to try, onwards. if (isDiagnosticsEnabled()) { logDiagnostic("Unable to locate any class called '" + factoryClass + "' via classloader " + objectId(classLoader)); } throw ex; } // ignore exception, continue } catch (NoClassDefFoundError e) { if (classLoader == thisClassLoader) { // Nothing more to try, onwards. if (isDiagnosticsEnabled()) { logDiagnostic("Class '" + factoryClass + "' cannot be loaded" + " via classloader " + objectId(classLoader) + " - it depends on some other class that cannot be found."); } throw e; } // ignore exception, continue } catch (ClassCastException e) { if (classLoader == thisClassLoader) { // There's no point in falling through to the code below that // tries again with thisClassLoader, because we've just tried // loading with that loader (not the TCCL). Just throw an // appropriate exception here. final boolean implementsLogFactory = implementsLogFactory(logFactoryClass); // // Construct a good message: users may not actual expect that a custom implementation // has been specified. Several well known containers use this mechanism to adapt JCL // to their native logging system. // final StringBuffer msg = new StringBuffer(); msg.append("The application has specified that a custom LogFactory implementation "); msg.append("should be used but Class '"); msg.append(factoryClass); msg.append("' cannot be converted to '"); msg.append(LogFactory.class.getName()); msg.append("'. "); if (implementsLogFactory) { msg.append("The conflict is caused by the presence of multiple LogFactory classes "); msg.append("in incompatible classloaders. "); msg.append("Background can be found in http://commons.apache.org/logging/tech.html. "); msg.append("If you have not explicitly specified a custom LogFactory then it is likely "); msg.append("that the container has set one without your knowledge. "); msg.append("In this case, consider using the commons-logging-adapters.jar file or "); msg.append("specifying the standard LogFactory from the command line. "); } else { msg.append("Please check the custom implementation. "); } msg.append("Help can be found @http://commons.apache.org/logging/troubleshooting.html."); if (isDiagnosticsEnabled()) { logDiagnostic(msg.toString()); } throw new ClassCastException(msg.toString()); } // Ignore exception, continue. Presumably the classloader was the // TCCL; the code below will try to load the class via thisClassLoader. // This will handle the case where the original calling class is in // a shared classpath but the TCCL has a copy of LogFactory and the // specified LogFactory implementation; we will fall back to using the // LogFactory implementation from the same classloader as this class. // // Issue: this doesn't handle the reverse case, where this LogFactory // is in the webapp, and the specified LogFactory implementation is // in a shared classpath. In that case: // (a) the class really does implement LogFactory (bad log msg above) // (b) the fallback code will result in exactly the same problem. } } /* At this point, either classLoader == null, OR * classLoader was unable to load factoryClass. * * In either case, we call Class.forName, which is equivalent * to LogFactory.class.getClassLoader().load(name), ie we ignore * the classloader parameter the caller passed, and fall back * to trying the classloader associated with this class. See the * javadoc for the newFactory method for more info on the * consequences of this. * * Notes: * * LogFactory.class.getClassLoader() may return 'null' * if LogFactory is loaded by the bootstrap classloader. */ // Warning: must typecast here & allow exception // to be generated/caught & recast properly. if (isDiagnosticsEnabled()) { logDiagnostic("Unable to load factory class via classloader " + objectId(classLoader) + " - trying the classloader associated with this LogFactory."); } logFactoryClass = Class.forName(factoryClass); return (LogFactory) logFactoryClass.newInstance(); } catch (Exception e) { // Check to see if we've got a bad configuration if (isDiagnosticsEnabled()) { logDiagnostic("Unable to create LogFactory instance."); } if (logFactoryClass != null && !LogFactory.class.isAssignableFrom(logFactoryClass)) { return new LogConfigurationException( "The chosen LogFactory implementation does not extend LogFactory." + " Please check your configuration.", e); } return new LogConfigurationException(e); } } /** * Determines whether the given class actually implements LogFactory. * Diagnostic information is also logged. *

* Usage: to diagnose whether a classloader conflict is the cause * of incompatibility. The test used is whether the class is assignable from * the LogFactory class loaded by the class's classloader. * @param logFactoryClass Class which may implement LogFactory * @return true if the logFactoryClass does extend * LogFactory when that class is loaded via the same * classloader that loaded the logFactoryClass. */ private static boolean implementsLogFactory(Class logFactoryClass) { boolean implementsLogFactory = false; if (logFactoryClass != null) { try { ClassLoader logFactoryClassLoader = logFactoryClass.getClassLoader(); if (logFactoryClassLoader == null) { logDiagnostic("[CUSTOM LOG FACTORY] was loaded by the boot classloader"); } else { logHierarchy("[CUSTOM LOG FACTORY] ", logFactoryClassLoader); Class factoryFromCustomLoader = Class.forName("org.apache.commons.logging.LogFactory", false, logFactoryClassLoader); implementsLogFactory = factoryFromCustomLoader.isAssignableFrom(logFactoryClass); if (implementsLogFactory) { logDiagnostic("[CUSTOM LOG FACTORY] " + logFactoryClass.getName() + " implements LogFactory but was loaded by an incompatible classloader."); } else { logDiagnostic("[CUSTOM LOG FACTORY] " + logFactoryClass.getName() + " does not implement LogFactory."); } } } catch (SecurityException e) { // // The application is running within a hostile security environment. // This will make it very hard to diagnose issues with JCL. // Consider running less securely whilst debugging this issue. // logDiagnostic("[CUSTOM LOG FACTORY] SecurityException thrown whilst trying to determine whether " + "the compatibility was caused by a classloader conflict: " + e.getMessage()); } catch (LinkageError e) { // // This should be an unusual circumstance. // LinkageError's usually indicate that a dependent class has incompatibly changed. // Another possibility may be an exception thrown by an initializer. // Time for a clean rebuild? // logDiagnostic("[CUSTOM LOG FACTORY] LinkageError thrown whilst trying to determine whether " + "the compatibility was caused by a classloader conflict: " + e.getMessage()); } catch (ClassNotFoundException e) { // // LogFactory cannot be loaded by the classloader which loaded the custom factory implementation. // The custom implementation is not viable until this is corrected. // Ensure that the JCL jar and the custom class are available from the same classloader. // Running with diagnostics on should give information about the classloaders used // to load the custom factory. // logDiagnostic("[CUSTOM LOG FACTORY] LogFactory class cannot be loaded by classloader which loaded " + "the custom LogFactory implementation. Is the custom factory in the right classloader?"); } } return implementsLogFactory; } /** * Applets may run in an environment where accessing resources of a loader is * a secure operation, but where the commons-logging library has explicitly * been granted permission for that operation. In this case, we need to * run the operation using an AccessController. */ private static InputStream getResourceAsStream(final ClassLoader loader, final String name) { return (InputStream)AccessController.doPrivileged( new PrivilegedAction() { public Object run() { if (loader != null) { return loader.getResourceAsStream(name); } else { return ClassLoader.getSystemResourceAsStream(name); } } }); } /** * Given a filename, return an enumeration of URLs pointing to * all the occurrences of that filename in the classpath. *

* This is just like ClassLoader.getResources except that the * operation is done under an AccessController so that this method will * succeed when this jarfile is privileged but the caller is not. * This method must therefore remain private to avoid security issues. *

* If no instances are found, an Enumeration is returned whose * hasMoreElements method returns false (ie an "empty" enumeration). * If resources could not be listed for some reason, null is returned. */ private static Enumeration getResources(final ClassLoader loader, final String name) { PrivilegedAction action = new PrivilegedAction() { public Object run() { try { if (loader != null) { return loader.getResources(name); } else { return ClassLoader.getSystemResources(name); } } catch (IOException e) { if (isDiagnosticsEnabled()) { logDiagnostic("Exception while trying to find configuration file " + name + ":" + e.getMessage()); } return null; } catch (NoSuchMethodError e) { // we must be running on a 1.1 JVM which doesn't support // ClassLoader.getSystemResources; just return null in // this case. return null; } } }; Object result = AccessController.doPrivileged(action); return (Enumeration) result; } /** * Given a URL that refers to a .properties file, load that file. * This is done under an AccessController so that this method will * succeed when this jarfile is privileged but the caller is not. * This method must therefore remain private to avoid security issues. *

* {@code Null} is returned if the URL cannot be opened. */ private static Properties getProperties(final URL url) { PrivilegedAction action = new PrivilegedAction() { public Object run() { InputStream stream = null; try { // We must ensure that useCaches is set to false, as the // default behaviour of java is to cache file handles, and // this "locks" files, preventing hot-redeploy on windows. URLConnection connection = url.openConnection(); connection.setUseCaches(false); stream = connection.getInputStream(); if (stream != null) { Properties props = new Properties(); props.load(stream); stream.close(); stream = null; return props; } } catch (IOException e) { if (isDiagnosticsEnabled()) { logDiagnostic("Unable to read URL " + url); } } finally { if (stream != null) { try { stream.close(); } catch (IOException e) { // ignore exception; this should not happen if (isDiagnosticsEnabled()) { logDiagnostic("Unable to close stream for URL " + url); } } } } return null; } }; return (Properties) AccessController.doPrivileged(action); } /** * Locate a user-provided configuration file. *

* The classpath of the specified classLoader (usually the context classloader) * is searched for properties files of the specified name. If none is found, * null is returned. If more than one is found, then the file with the greatest * value for its PRIORITY property is returned. If multiple files have the * same PRIORITY value then the first in the classpath is returned. *

* This differs from the 1.0.x releases; those always use the first one found. * However as the priority is a new field, this change is backwards compatible. *

* The purpose of the priority field is to allow a webserver administrator to * override logging settings in all webapps by placing a commons-logging.properties * file in a shared classpath location with a priority > 0; this overrides any * commons-logging.properties files without priorities which are in the * webapps. Webapps can also use explicit priorities to override a configuration * file in the shared classpath if needed. */ private static final Properties getConfigurationFile(ClassLoader classLoader, String fileName) { Properties props = null; double priority = 0.0; URL propsUrl = null; try { Enumeration urls = getResources(classLoader, fileName); if (urls == null) { return null; } while (urls.hasMoreElements()) { URL url = (URL) urls.nextElement(); Properties newProps = getProperties(url); if (newProps != null) { if (props == null) { propsUrl = url; props = newProps; String priorityStr = props.getProperty(PRIORITY_KEY); priority = 0.0; if (priorityStr != null) { priority = Double.parseDouble(priorityStr); } if (isDiagnosticsEnabled()) { logDiagnostic("[LOOKUP] Properties file found at '" + url + "'" + " with priority " + priority); } } else { String newPriorityStr = newProps.getProperty(PRIORITY_KEY); double newPriority = 0.0; if (newPriorityStr != null) { newPriority = Double.parseDouble(newPriorityStr); } if (newPriority > priority) { if (isDiagnosticsEnabled()) { logDiagnostic("[LOOKUP] Properties file at '" + url + "'" + " with priority " + newPriority + " overrides file at '" + propsUrl + "'" + " with priority " + priority); } propsUrl = url; props = newProps; priority = newPriority; } else { if (isDiagnosticsEnabled()) { logDiagnostic("[LOOKUP] Properties file at '" + url + "'" + " with priority " + newPriority + " does not override file at '" + propsUrl + "'" + " with priority " + priority); } } } } } } catch (SecurityException e) { if (isDiagnosticsEnabled()) { logDiagnostic("SecurityException thrown while trying to find/read config files."); } } if (isDiagnosticsEnabled()) { if (props == null) { logDiagnostic("[LOOKUP] No properties file of name '" + fileName + "' found."); } else { logDiagnostic("[LOOKUP] Properties file of name '" + fileName + "' found at '" + propsUrl + '"'); } } return props; } /** * Read the specified system property, using an AccessController so that * the property can be read if JCL has been granted the appropriate * security rights even if the calling code has not. *

* Take care not to expose the value returned by this method to the * calling application in any way; otherwise the calling app can use that * info to access data that should not be available to it. */ private static String getSystemProperty(final String key, final String def) throws SecurityException { return (String) AccessController.doPrivileged( new PrivilegedAction() { public Object run() { return System.getProperty(key, def); } }); } /** * Determines whether the user wants internal diagnostic output. If so, * returns an appropriate writer object. Users can enable diagnostic * output by setting the system property named {@link #DIAGNOSTICS_DEST_PROPERTY} to * a filename, or the special values STDOUT or STDERR. */ private static PrintStream initDiagnostics() { String dest; try { dest = getSystemProperty(DIAGNOSTICS_DEST_PROPERTY, null); if (dest == null) { return null; } } catch (SecurityException ex) { // We must be running in some very secure environment. // We just have to assume output is not wanted.. return null; } if (dest.equals("STDOUT")) { return System.out; } else if (dest.equals("STDERR")) { return System.err; } else { try { // open the file in append mode FileOutputStream fos = new FileOutputStream(dest, true); return new PrintStream(fos); } catch (IOException ex) { // We should report this to the user - but how? return null; } } } /** * Indicates true if the user has enabled internal logging. *

* By the way, sorry for the incorrect grammar, but calling this method * areDiagnosticsEnabled just isn't java beans style. * * @return true if calls to logDiagnostic will have any effect. * @since 1.1 */ protected static boolean isDiagnosticsEnabled() { return diagnosticsStream != null; } /** * Write the specified message to the internal logging destination. *

* Note that this method is private; concrete subclasses of this class * should not call it because the diagnosticPrefix string this * method puts in front of all its messages is LogFactory@...., * while subclasses should put SomeSubClass@... *

* Subclasses should instead compute their own prefix, then call * logRawDiagnostic. Note that calling isDiagnosticsEnabled is * fine for subclasses. *

* Note that it is safe to call this method before initDiagnostics * is called; any output will just be ignored (as isDiagnosticsEnabled * will return false). * * @param msg is the diagnostic message to be output. */ private static final void logDiagnostic(String msg) { if (diagnosticsStream != null) { diagnosticsStream.print(diagnosticPrefix); diagnosticsStream.println(msg); diagnosticsStream.flush(); } } /** * Write the specified message to the internal logging destination. * * @param msg is the diagnostic message to be output. * @since 1.1 */ protected static final void logRawDiagnostic(String msg) { if (diagnosticsStream != null) { diagnosticsStream.println(msg); diagnosticsStream.flush(); } } /** * Generate useful diagnostics regarding the classloader tree for * the specified class. *

* As an example, if the specified class was loaded via a webapp's * classloader, then you may get the following output: *

     * Class com.acme.Foo was loaded via classloader 11111
     * ClassLoader tree: 11111 -> 22222 (SYSTEM) -> 33333 -> BOOT
     * 
*

* This method returns immediately if isDiagnosticsEnabled() * returns false. * * @param clazz is the class whose classloader + tree are to be * output. */ private static void logClassLoaderEnvironment(Class clazz) { if (!isDiagnosticsEnabled()) { return; } try { // Deliberately use System.getProperty here instead of getSystemProperty; if // the overall security policy for the calling application forbids access to // these variables then we do not want to output them to the diagnostic stream. logDiagnostic("[ENV] Extension directories (java.ext.dir): " + System.getProperty("java.ext.dir")); logDiagnostic("[ENV] Application classpath (java.class.path): " + System.getProperty("java.class.path")); } catch (SecurityException ex) { logDiagnostic("[ENV] Security setting prevent interrogation of system classpaths."); } String className = clazz.getName(); ClassLoader classLoader; try { classLoader = getClassLoader(clazz); } catch (SecurityException ex) { // not much useful diagnostics we can print here! logDiagnostic("[ENV] Security forbids determining the classloader for " + className); return; } logDiagnostic("[ENV] Class " + className + " was loaded via classloader " + objectId(classLoader)); logHierarchy("[ENV] Ancestry of classloader which loaded " + className + " is ", classLoader); } /** * Logs diagnostic messages about the given classloader * and it's hierarchy. The prefix is prepended to the message * and is intended to make it easier to understand the logs. * @param prefix * @param classLoader */ private static void logHierarchy(String prefix, ClassLoader classLoader) { if (!isDiagnosticsEnabled()) { return; } ClassLoader systemClassLoader; if (classLoader != null) { final String classLoaderString = classLoader.toString(); logDiagnostic(prefix + objectId(classLoader) + " == '" + classLoaderString + "'"); } try { systemClassLoader = ClassLoader.getSystemClassLoader(); } catch (SecurityException ex) { logDiagnostic(prefix + "Security forbids determining the system classloader."); return; } if (classLoader != null) { final StringBuffer buf = new StringBuffer(prefix + "ClassLoader tree:"); for(;;) { buf.append(objectId(classLoader)); if (classLoader == systemClassLoader) { buf.append(" (SYSTEM) "); } try { classLoader = classLoader.getParent(); } catch (SecurityException ex) { buf.append(" --> SECRET"); break; } buf.append(" --> "); if (classLoader == null) { buf.append("BOOT"); break; } } logDiagnostic(buf.toString()); } } /** * Returns a string that uniquely identifies the specified object, including * its class. *

* The returned string is of form "classname@hashcode", ie is the same as * the return value of the Object.toString() method, but works even when * the specified object's class has overidden the toString method. * * @param o may be null. * @return a string of form classname@hashcode, or "null" if param o is null. * @since 1.1 */ public static String objectId(Object o) { if (o == null) { return "null"; } else { return o.getClass().getName() + "@" + System.identityHashCode(o); } } // ---------------------------------------------------------------------- // Static initialiser block to perform initialisation at class load time. // // We can't do this in the class constructor, as there are many // static methods on this class that can be called before any // LogFactory instances are created, and they depend upon this // stuff having been set up. // // Note that this block must come after any variable declarations used // by any methods called from this block, as we want any static initialiser // associated with the variable to run first. If static initialisers for // variables run after this code, then (a) their value might be needed // by methods called from here, and (b) they might *override* any value // computed here! // // So the wisest thing to do is just to place this code at the very end // of the class file. // ---------------------------------------------------------------------- static { // note: it's safe to call methods before initDiagnostics (though // diagnostic output gets discarded). thisClassLoader = getClassLoader(LogFactory.class); // In order to avoid confusion where multiple instances of JCL are // being used via different classloaders within the same app, we // ensure each logged message has a prefix of form // [LogFactory from classloader OID] // // Note that this prefix should be kept consistent with that // in LogFactoryImpl. However here we don't need to output info // about the actual *instance* of LogFactory, as all methods that // output diagnostics from this class are static. String classLoaderName; try { ClassLoader classLoader = thisClassLoader; if (thisClassLoader == null) { classLoaderName = "BOOTLOADER"; } else { classLoaderName = objectId(classLoader); } } catch (SecurityException e) { classLoaderName = "UNKNOWN"; } diagnosticPrefix = "[LogFactory from " + classLoaderName + "] "; diagnosticsStream = initDiagnostics(); logClassLoaderEnvironment(LogFactory.class); factories = createFactoryStore(); if (isDiagnosticsEnabled()) { logDiagnostic("BOOTSTRAP COMPLETED"); } } } commons-logging-1.1.3-src/src/main/java/org/apache/commons/logging/package.html100664 24652 12145235706 25461 0ustartntn 0 0

Simple wrapper API around multiple logging APIs.

Overview

This package provides an API for logging in server-based applications that can be used around a variety of different logging implementations, including prebuilt support for the following:

  • Log4J (version 1.2 or later) from Apache's Logging project. Each named Log instance is connected to a corresponding Log4J Logger.
  • JDK Logging API, included in JDK 1.4 or later systems. Each named Log instance is connected to a corresponding java.util.logging.Logger instance.
  • LogKit from Apache's Avalon project. Each named Log instance is connected to a corresponding LogKit Logger.
  • NoOpLog implementation that simply swallows all log output, for all named Log instances.
  • SimpleLog implementation that writes all log output, for all named Log instances, to System.err.

Quick Start Guide

For those impatient to just get on with it, the following example illustrates the typical declaration and use of a logger that is named (by convention) after the calling class:

    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;

    public class Foo {

        private Log log = LogFactory.getLog(Foo.class);

        public void foo() {
            ...
            try {
                if (log.isDebugEnabled()) {
                    log.debug("About to do something to object " + name);
                }
                name.bar();
            } catch (IllegalStateException e) {
                log.error("Something bad happened to " + name, e);
            }
            ...
        }

Unless you configure things differently, all log output will be written to System.err. Therefore, you really will want to review the remainder of this page in order to understand how to configure logging for your application.

Configuring the Commons Logging Package

Choosing a LogFactory Implementation

From an application perspective, the first requirement is to retrieve an object reference to the LogFactory instance that will be used to create Log instances for this application. This is normally accomplished by calling the static getFactory() method. This method implements the following discovery algorithm to select the name of the LogFactory implementation class this application wants to use:

  • Check for a system property named org.apache.commons.logging.LogFactory.
  • Use the JDK 1.3 JAR Services Discovery mechanism (see http://java.sun.com/j2se/1.3/docs/guide/jar/jar.html for more information) to look for a resource named META-INF/services/org.apache.commons.logging.LogFactory whose first line is assumed to contain the desired class name.
  • Look for a properties file named commons-logging.properties visible in the application class path, with a property named org.apache.commons.logging.LogFactory defining the desired implementation class name.
  • Fall back to a default implementation, which is described further below.

If a commons-logging.properties file is found, all of the properties defined there are also used to set configuration attributes on the instantiated LogFactory instance.

Once an implementation class name is selected, the corresponding class is loaded from the current Thread context class loader (if there is one), or from the class loader that loaded the LogFactory class itself otherwise. This allows a copy of commons-logging.jar to be shared in a multiple class loader environment (such as a servlet container), but still allow each web application to provide its own LogFactory implementation, if it so desires. An instance of this class will then be created, and cached per class loader.

The Default LogFactory Implementation

The Logging Package APIs include a default LogFactory implementation class ( org.apache.commons.logging.impl.LogFactoryImpl) that is selected if no other implementation class name can be discovered. Its primary purpose is to create (as necessary) and return Log instances in response to calls to the getInstance() method. The default implementation uses the following rules:

  • At most one Log instance of the same name will be created. Subsequent getInstance() calls to the same LogFactory instance, with the same name or Class parameter, will return the same Log instance.
  • When a new Log instance must be created, the default LogFactory implementation uses the following discovery process:
    • Look for a configuration attribute of this factory named org.apache.commons.logging.Log (for backwards compatibility to pre-1.0 versions of this API, an attribute org.apache.commons.logging.log is also consulted).
    • Look for a system property named org.apache.commons.logging.Log (for backwards compatibility to pre-1.0 versions of this API, a system property org.apache.commons.logging.log is also consulted).
    • If the Log4J logging system is available in the application class path, use the corresponding wrapper class (Log4JLogger).
    • If the application is executing on a JDK 1.4 system, use the corresponding wrapper class (Jdk14Logger).
    • Fall back to the default simple logging implementation (SimpleLog).
  • Load the class of the specified name from the thread context class loader (if any), or from the class loader that loaded the LogFactory class otherwise.
  • Instantiate an instance of the selected Log implementation class, passing the specified name as the single argument to its constructor.

See the SimpleLog JavaDocs for detailed configuration information for this default implementation.

Configuring the Underlying Logging System

The basic principle is that the user is totally responsible for the configuration of the underlying logging system. Commons-logging should not change the existing configuration.

Each individual Log implementation may support its own configuration properties. These will be documented in the class descriptions for the corresponding implementation class.

Finally, some Log implementations (such as the one for Log4J) require an external configuration file for the entire logging environment. This file should be prepared in a manner that is specific to the actual logging technology being used.

Using the Logging Package APIs

Use of the Logging Package APIs, from the perspective of an application component, consists of the following steps:

  1. Acquire a reference to an instance of org.apache.commons.logging.Log, by calling the factory method LogFactory.getInstance(String name). Your application can contain references to multiple loggers that are used for different purposes. A typical scenario for a server application is to have each major component of the server use its own Log instance.
  2. Cause messages to be logged (if the corresponding detail level is enabled) by calling appropriate methods (trace(), debug(), info(), warn(), error, and fatal()).

For convenience, LogFactory also offers a static method getLog() that combines the typical two-step pattern:

  Log log = LogFactory.getFactory().getInstance(Foo.class);

into a single method call:

  Log log = LogFactory.getLog(Foo.class);

For example, you might use the following technique to initialize and use a Log instance in an application component:

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class MyComponent {

  protected Log log =
    LogFactory.getLog(MyComponent.class);

  // Called once at startup time
  public void start() {
    ...
    log.info("MyComponent started");
    ...
  }

  // Called once at shutdown time
  public void stop() {
    ...
    log.info("MyComponent stopped");
    ...
  }

  // Called repeatedly to process a particular argument value
  // which you want logged if debugging is enabled
  public void process(String value) {
    ...
    // Do the string concatenation only if logging is enabled
    if (log.isDebugEnabled())
      log.debug("MyComponent processing " + value);
    ...
  }

}
commons-logging-1.1.3-src/src/main/java/org/apache/commons/logging/LogSource.java100664 20066 12145235706 25740 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.logging; import java.lang.reflect.Constructor; import java.util.Hashtable; import org.apache.commons.logging.impl.NoOpLog; /** * Factory for creating {@link Log} instances. Applications should call * the makeNewLogInstance() method to instantiate new instances * of the configured {@link Log} implementation class. *

* By default, calling getInstance() will use the following * algorithm: *

    *
  • If Log4J is available, return an instance of * org.apache.commons.logging.impl.Log4JLogger.
  • *
  • If JDK 1.4 or later is available, return an instance of * org.apache.commons.logging.impl.Jdk14Logger.
  • *
  • Otherwise, return an instance of * org.apache.commons.logging.impl.NoOpLog.
  • *
*

* You can change the default behavior in one of two ways: *

    *
  • On the startup command line, set the system property * org.apache.commons.logging.log to the name of the * org.apache.commons.logging.Log implementation class * you want to use.
  • *
  • At runtime, call LogSource.setLogImplementation().
  • *
* * @deprecated Use {@link LogFactory} instead - The default factory * implementation performs exactly the same algorithm as this class did * * @version $Id: LogSource.java 1432675 2013-01-13 17:53:30Z tn $ */ public class LogSource { // ------------------------------------------------------- Class Attributes static protected Hashtable logs = new Hashtable(); /** Is log4j available (in the current classpath) */ static protected boolean log4jIsAvailable = false; /** Is JDK 1.4 logging available */ static protected boolean jdk14IsAvailable = false; /** Constructor for current log class */ static protected Constructor logImplctor = null; // ----------------------------------------------------- Class Initializers static { // Is Log4J Available? try { log4jIsAvailable = null != Class.forName("org.apache.log4j.Logger"); } catch (Throwable t) { log4jIsAvailable = false; } // Is JDK 1.4 Logging Available? try { jdk14IsAvailable = null != Class.forName("java.util.logging.Logger") && null != Class.forName("org.apache.commons.logging.impl.Jdk14Logger"); } catch (Throwable t) { jdk14IsAvailable = false; } // Set the default Log implementation String name = null; try { name = System.getProperty("org.apache.commons.logging.log"); if (name == null) { name = System.getProperty("org.apache.commons.logging.Log"); } } catch (Throwable t) { } if (name != null) { try { setLogImplementation(name); } catch (Throwable t) { try { setLogImplementation("org.apache.commons.logging.impl.NoOpLog"); } catch (Throwable u) { // ignored } } } else { try { if (log4jIsAvailable) { setLogImplementation("org.apache.commons.logging.impl.Log4JLogger"); } else if (jdk14IsAvailable) { setLogImplementation("org.apache.commons.logging.impl.Jdk14Logger"); } else { setLogImplementation("org.apache.commons.logging.impl.NoOpLog"); } } catch (Throwable t) { try { setLogImplementation("org.apache.commons.logging.impl.NoOpLog"); } catch (Throwable u) { // ignored } } } } // ------------------------------------------------------------ Constructor /** Don't allow others to create instances. */ private LogSource() { } // ---------------------------------------------------------- Class Methods /** * Set the log implementation/log implementation factory * by the name of the class. The given class must implement {@link Log}, * and provide a constructor that takes a single {@link String} argument * (containing the name of the log). */ static public void setLogImplementation(String classname) throws LinkageError, NoSuchMethodException, SecurityException, ClassNotFoundException { try { Class logclass = Class.forName(classname); Class[] argtypes = new Class[1]; argtypes[0] = "".getClass(); logImplctor = logclass.getConstructor(argtypes); } catch (Throwable t) { logImplctor = null; } } /** * Set the log implementation/log implementation factory by class. * The given class must implement {@link Log}, and provide a constructor * that takes a single {@link String} argument (containing the name of the log). */ static public void setLogImplementation(Class logclass) throws LinkageError, ExceptionInInitializerError, NoSuchMethodException, SecurityException { Class[] argtypes = new Class[1]; argtypes[0] = "".getClass(); logImplctor = logclass.getConstructor(argtypes); } /** Get a Log instance by class name. */ static public Log getInstance(String name) { Log log = (Log) logs.get(name); if (null == log) { log = makeNewLogInstance(name); logs.put(name, log); } return log; } /** Get a Log instance by class. */ static public Log getInstance(Class clazz) { return getInstance(clazz.getName()); } /** * Create a new {@link Log} implementation, based on the given name. *

* The specific {@link Log} implementation returned is determined by the * value of the org.apache.commons.logging.log property. The value * of org.apache.commons.logging.log may be set to the fully specified * name of a class that implements the {@link Log} interface. This class must * also have a public constructor that takes a single {@link String} argument * (containing the name of the {@link Log} to be constructed. *

* When org.apache.commons.logging.log is not set, or when no corresponding * class can be found, this method will return a Log4JLogger if the log4j Logger * class is available in the {@link LogSource}'s classpath, or a Jdk14Logger if we * are on a JDK 1.4 or later system, or NoOpLog if neither of the above conditions is true. * * @param name the log name (or category) */ static public Log makeNewLogInstance(String name) { Log log; try { Object[] args = { name }; log = (Log) logImplctor.newInstance(args); } catch (Throwable t) { log = null; } if (null == log) { log = new NoOpLog(name); } return log; } /** * Returns a {@link String} array containing the names of * all logs known to me. */ static public String[] getLogNames() { return (String[]) logs.keySet().toArray(new String[logs.size()]); } } commons-logging-1.1.3-src/src/main/java/org/apache/commons/logging/LogConfigurationException.java100664 5035 12145235706 31145 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.logging; /** * An exception that is thrown only if a suitable LogFactory * or Log instance cannot be created by the corresponding * factory methods. * * @version $Id: LogConfigurationException.java 1432663 2013-01-13 17:24:18Z tn $ */ public class LogConfigurationException extends RuntimeException { /** Serializable version identifier. */ private static final long serialVersionUID = 8486587136871052495L; /** * Construct a new exception with null as its detail message. */ public LogConfigurationException() { super(); } /** * Construct a new exception with the specified detail message. * * @param message The detail message */ public LogConfigurationException(String message) { super(message); } /** * Construct a new exception with the specified cause and a derived * detail message. * * @param cause The underlying cause */ public LogConfigurationException(Throwable cause) { this(cause == null ? null : cause.toString(), cause); } /** * Construct a new exception with the specified detail message and cause. * * @param message The detail message * @param cause The underlying cause */ public LogConfigurationException(String message, Throwable cause) { super(message + " (Caused by " + cause + ")"); this.cause = cause; // Two-argument version requires JDK 1.4 or later } /** * The underlying cause of this exception. */ protected Throwable cause = null; /** * Return the underlying cause of this exception (if any). */ public Throwable getCause() { return this.cause; } } commons-logging-1.1.3-src/src/main/java/org/apache/commons/logging/Log.java100664 14467 12145235706 24567 0ustartntn 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.logging; /** * A simple logging interface abstracting logging APIs. In order to be * instantiated successfully by {@link LogFactory}, classes that implement * this interface must have a constructor that takes a single String * parameter representing the "name" of this Log. *

* The six logging levels used by Log are (in order): *

    *
  1. trace (the least serious)
  2. *
  3. debug
  4. *
  5. info
  6. *
  7. warn
  8. *
  9. error
  10. *
  11. fatal (the most serious)
  12. *
* The mapping of these log levels to the concepts used by the underlying * logging system is implementation dependent. * The implementation should ensure, though, that this ordering behaves * as expected. *

* Performance is often a logging concern. * By examining the appropriate property, * a component can avoid expensive operations (producing information * to be logged). *

* For example, *

 *    if (log.isDebugEnabled()) {
 *        ... do something expensive ...
 *        log.debug(theResult);
 *    }
 * 
*

* Configuration of the underlying logging system will generally be done * external to the Logging APIs, through whatever mechanism is supported by * that system. * * @version $Id: Log.java 1432663 2013-01-13 17:24:18Z tn $ */ public interface Log { // ----------------------------------------------------- Logging Properties /** * Is debug logging currently enabled? *

* Call this method to prevent having to perform expensive operations * (for example, String concatenation) * when the log level is more than debug. * * @return true if debug is enabled in the underlying logger. */ public boolean isDebugEnabled(); /** * Is error logging currently enabled? *

* Call this method to prevent having to perform expensive operations * (for example, String concatenation) * when the log level is more than error. * * @return true if error is enabled in the underlying logger. */ public boolean isErrorEnabled(); /** * Is fatal logging currently enabled? *

* Call this method to prevent having to perform expensive operations * (for example, String concatenation) * when the log level is more than fatal. * * @return true if fatal is enabled in the underlying logger. */ public boolean isFatalEnabled(); /** * Is info logging currently enabled? *

* Call this method to prevent having to perform expensive operations * (for example, String concatenation) * when the log level is more than info. * * @return true if info is enabled in the underlying logger. */ public boolean isInfoEnabled(); /** * Is trace logging currently enabled? *

* Call this method to prevent having to perform expensive operations * (for example, String concatenation) * when the log level is more than trace. * * @return true if trace is enabled in the underlying logger. */ public boolean isTraceEnabled(); /** * Is warn logging currently enabled? *

* Call this method to prevent having to perform expensive operations * (for example, String concatenation) * when the log level is more than warn. * * @return true if warn is enabled in the underlying logger. */ public boolean isWarnEnabled(); // -------------------------------------------------------- Logging Methods /** * Log a message with trace log level. * * @param message log this message */ public void trace(Object message); /** * Log an error with trace log level. * * @param message log this message * @param t log this cause */ public void trace(Object message, Throwable t); /** * Log a message with debug log level. * * @param message log this message */ public void debug(Object message); /** * Log an error with debug log level. * * @param message log this message * @param t log this cause */ public void debug(Object message, Throwable t); /** * Log a message with info log level. * * @param message log this message */ public void info(Object message); /** * Log an error with info log level. * * @param message log this message * @param t log this cause */ public void info(Object message, Throwable t); /** * Log a message with warn log level. * * @param message log this message */ public void warn(Object message); /** * Log an error with warn log level. * * @param message log this message * @param t log this cause */ public void warn(Object message, Throwable t); /** * Log a message with error log level. * * @param message log this message */ public void error(Object message); /** * Log an error with error log level. * * @param message log this message * @param t log this cause */ public void error(Object message, Throwable t); /** * Log a message with fatal log level. * * @param message log this message */ public void fatal(Object message); /** * Log an error with fatal log level. * * @param message log this message * @param t log this cause */ public void fatal(Object message, Throwable t); } commons-logging-1.1.3-src/src/conf/MANIFEST.MF100664 2417 12145235706 16554 0ustartntn 0 0 Manifest-Version: 1.0 Export-Package: org.apache.commons.logging;version="1.1.3",org.apache. commons.logging.impl;version="1.1.3" Implementation-Title: Commons Logging Implementation-Vendor: The Apache Software Foundation Implementation-Vendor-Id: org.apache Specification-Title: Commons Logging Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt Bundle-SymbolicName: org.apache.commons.logging X-Compile-Target-JDK: 1.1 Implementation-Version: 1.1.3 Specification-Vendor: The Apache Software Foundation Bundle-Name: Commons Logging Created-By: Apache Maven Bundle Plugin X-Compile-Source-JDK: 1.2 Bundle-Vendor: The Apache Software Foundation Bundle-Version: 1.1.3 Bundle-ManifestVersion: 2 Bundle-Description: Commons Logging is a thin adapter allowing configu rable bridging to other, well known logging systems. Bundle-DocURL: http://commons.apache.org/proper/commons-logging/ Import-Package: javax.servlet;resolution:=optional;version="[2.1.0,3.0 .0)",org.apache.avalon.framework.logger;resolution:=optional;version= "[4.1.3,4.1.5]",org.apache.log;resolution:=optional;version="[1.0.1,1 .0.1]",org.apache.log4j;resolution:=optional;version="[1.2.15,2.0.0)" Include-Resource: META-INF/NOTICE.txt=NOTICE.txt,META-INF/LICENSE.txt= LICENSE.txt Specification-Version: 1.1.3 commons-logging-1.1.3-src/src/changes/release-notes.vm100664 6662 12145235706 20725 0ustartntn 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. Apache ${project.name} Version ${version} RELEASE NOTES The ${developmentTeam} is pleased to announce the release of Apache ${project.name} ${version} $introduction.replaceAll("(? Release Notes Use "org.apache.commons.logging" as bundle symbolic name. The jar manifest now contains proper OSGi-related metadata information. LogFactory and LogFactoryImpl will not swallow certain errors anymore (ThreadDeath and VirtualMachineError). Improved thread-safety for several log adapters, including AvalonLogger, SimpleLog, Log4JLogger, LogKitLogger. In case of a discovery failure now also the stacktrace of the cause will be added to the diagnostic message. Jdk14Logger now correctly uses the specified logger name. Change scope of Jdk14Logger.log(Level, String, Throwable) to protected, allowing subclasses to modify the logging output. Properly synchronize access to protected static field LogFactory.nullClassLoaderFactory. Prevent potential deadlock scenario in WeakHashtable. Potential missing privileged block for class loader. LogFactoryImpl.setAttribute - possible NPE. Log4JLogger uses deprecated static members of Priority such as INFO. Static analysis suggests a number of potential improvements. SimpleLog.log - unsafe update of shortLogName. LogFactory.diagnosticPrefix and diagnosticsStream could be final.