├── .github ├── dependabot.yml ├── release-drafter.yml └── workflows │ ├── maven.yml │ └── release-drafter.yml ├── .gitignore ├── LICENSE-Codehaus.txt ├── LICENSE.txt ├── README.md ├── pom.xml └── src ├── main ├── aspect │ └── org │ │ └── codehaus │ │ └── plexus │ │ └── classworlds │ │ └── event │ │ └── ListenerAspect.aj └── java │ └── org │ └── codehaus │ ├── classworlds │ ├── BytesURLConnection.java │ ├── BytesURLStreamHandler.java │ ├── ClassRealm.java │ ├── ClassRealmAdapter.java │ ├── ClassRealmReverseAdapter.java │ ├── ClassWorld.java │ ├── ClassWorldAdapter.java │ ├── ClassWorldException.java │ ├── ClassWorldReverseAdapter.java │ ├── ConfigurationException.java │ ├── Configurator.java │ ├── ConfiguratorAdapter.java │ ├── DefaultClassRealm.java │ ├── DuplicateRealmException.java │ ├── Launcher.java │ └── NoSuchRealmException.java │ └── plexus │ └── classworlds │ ├── ClassWorld.java │ ├── ClassWorldException.java │ ├── ClassWorldListener.java │ ├── UrlUtils.java │ ├── launcher │ ├── ConfigurationException.java │ ├── ConfigurationHandler.java │ ├── ConfigurationParser.java │ ├── Configurator.java │ └── Launcher.java │ ├── realm │ ├── ClassRealm.java │ ├── DuplicateRealmException.java │ ├── Entry.java │ ├── FilteredClassRealm.java │ └── NoSuchRealmException.java │ └── strategy │ ├── AbstractStrategy.java │ ├── OsgiBundleStrategy.java │ ├── ParentFirstStrategy.java │ ├── SelfFirstStrategy.java │ ├── Strategy.java │ └── StrategyFactory.java ├── site ├── site.xml └── xdoc │ ├── apiusage.xml │ ├── index.xml │ └── launcher.xml └── test ├── java └── org │ └── codehaus │ └── plexus │ └── classworlds │ ├── AbstractClassWorldsTestCase.java │ ├── ClassView.java │ ├── ClassWorldTest.java │ ├── TestUtil.java │ ├── UrlUtilsTest.java │ ├── launcher │ ├── ConfigurationParserTest.java │ ├── ConfiguratorTest.java │ └── LauncherTest.java │ ├── realm │ ├── ClassRealmImplTest.java │ ├── DefaultClassRealmTest.java │ ├── EntryTest.java │ └── FilteredClassRealmTest.java │ └── strategy │ └── StrategyTest.java └── test-data ├── a.jar ├── a.properties ├── b.jar ├── b_old.jar ├── c.jar ├── circular-0.1.jar ├── component0-1.0.jar ├── component1-1.0.jar ├── component2-1.0.jar ├── component3-1.0.jar ├── component4-1.0.jar ├── component5-1.0.jar ├── component5-2.0.jar ├── d.jar ├── deadlock.jar ├── dupe-main.conf ├── dupe-realm.conf ├── early-import.conf ├── from-from-0.0.1-from-load-import.jar ├── inheritance.conf ├── launch-noclass.conf ├── launch-nomethod.conf ├── nested.jar ├── nested.properties ├── optionally-existent.conf ├── optionally-nonexistent.conf ├── realm-syntax.conf ├── resources ├── classworlds.conf └── werkflow.jar ├── set-using-existent.conf ├── set-using-existent.properties ├── set-using-missing.conf ├── set-using-nonexistent.conf ├── unhandled.conf ├── valid-enh-launch-exitCode.conf ├── valid-enh-launch.conf ├── valid-from-from-from.conf ├── valid-launch-exitCode.conf ├── valid-launch.conf └── valid.conf /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "maven" 4 | directory: "/" 5 | schedule: 6 | interval: "daily" 7 | - package-ecosystem: "github-actions" 8 | directory: "/" 9 | schedule: 10 | interval: "daily" 11 | -------------------------------------------------------------------------------- /.github/release-drafter.yml: -------------------------------------------------------------------------------- 1 | _extends: .github 2 | tag-template: plexus-classworlds-$NEXT_MINOR_VERSION 3 | -------------------------------------------------------------------------------- /.github/workflows/maven.yml: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | name: GitHub CI 19 | 20 | on: [push, pull_request] 21 | 22 | jobs: 23 | build: 24 | name: Build it 25 | uses: codehaus-plexus/.github/.github/workflows/maven.yml@master 26 | 27 | deploy: 28 | name: Deploy 29 | needs: build 30 | uses: codehaus-plexus/.github/.github/workflows/maven-deploy.yml@master 31 | secrets: inherit 32 | -------------------------------------------------------------------------------- /.github/workflows/release-drafter.yml: -------------------------------------------------------------------------------- 1 | name: Release Drafter 2 | on: 3 | push: 4 | branches: 5 | - master 6 | jobs: 7 | update_release_draft: 8 | uses: codehaus-plexus/.github/.github/workflows/release-drafter.yml@master 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | .project 3 | .classpath 4 | .settings/ 5 | bin 6 | .idea 7 | *.iml 8 | .java-version 9 | -------------------------------------------------------------------------------- /LICENSE-Codehaus.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | /* 4 | $Id$ 5 | 6 | Copyright 2002 (C) The Codehaus. All Rights Reserved. 7 | 8 | Redistribution and use of this software and associated documentation 9 | ("Software"), with or without modification, are permitted provided 10 | that the following conditions are met: 11 | 12 | 1. Redistributions of source code must retain copyright 13 | statements and notices. Redistributions must also contain a 14 | copy of this document. 15 | 16 | 2. Redistributions in binary form must reproduce the 17 | above copyright notice, this list of conditions and the 18 | following disclaimer in the documentation and/or other 19 | materials provided with the distribution. 20 | 21 | 3. The name "classworlds" must not be used to endorse or promote 22 | products derived from this Software without prior written 23 | permission of The Codehaus. For written permission, please 24 | contact bob@codehaus.org. 25 | 26 | 4. Products derived from this Software may not be called "classworlds" 27 | nor may "classworlds" appear in their names without prior written 28 | permission of The Codehaus. "classworlds" is a registered 29 | trademark of The Codehaus. 30 | 31 | 5. Due credit should be given to The Codehaus. 32 | (http://classworlds.codehaus.org/). 33 | 34 | THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS 35 | ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT 36 | NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 37 | FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 38 | THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 39 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 40 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 41 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 42 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 43 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 44 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 45 | OF THE POSSIBILITY OF SUCH DAMAGE. 46 | 47 | */ 48 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Plexus-Classworlds 2 | ================== 3 | 4 | [![Apache License, Version 2.0, January 2004](https://img.shields.io/github/license/codehaus-plexus/plexus-classworlds.svg?label=License)](http://www.apache.org/licenses/) 5 | [![Maven Central](https://img.shields.io/maven-central/v/org.codehaus.plexus/plexus-classworlds.svg?label=Maven%20Central)](https://search.maven.org/artifact/org.codehaus.plexus/plexus-classworlds) 6 | [![Reproducible Builds](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/jvm-repo-rebuild/reproducible-central/master/content/org/codehaus/plexus/plexus-classworlds/badge.json)](https://github.com/jvm-repo-rebuild/reproducible-central/blob/master/content/org/codehaus/plexus/plexus-classworlds/README.md) 7 | ![Build Status](https://github.com/codehaus-plexus/plexus-classworlds/workflows/GitHub%20CI/badge.svg) 8 | 9 | Current master is now at https://github.com/codehaus-plexus/plexus-classworlds 10 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 18 | 19 | 4.0.0 20 | 21 | 22 | org.codehaus.plexus 23 | plexus 24 | 20 25 | 26 | 27 | plexus-classworlds 28 | 2.9.1-SNAPSHOT 29 | bundle 30 | 31 | Plexus Classworlds 32 | A class loader framework 33 | https://codehaus-plexus.github.io/plexus-classworlds/ 34 | 2002 35 | 36 | 37 | scm:git:git@github.com:codehaus-plexus/plexus-classworlds.git 38 | scm:git:git@github.com:codehaus-plexus/plexus-classworlds.git 39 | master 40 | https://github.com/codehaus-plexus/plexus-classworlds/tree/${project.scm.tag}/ 41 | 42 | 43 | github 44 | https://github.com/codehaus-plexus/plexus-classworlds/issues 45 | 46 | 47 | 48 | 49 | github:gh-pages 50 | ${project.scm.developerConnection} 51 | 52 | 53 | 54 | 55 | 2025-04-05T16:29:01Z 56 | 57 | 58 | 59 | 60 | org.junit.jupiter 61 | junit-jupiter-api 62 | test 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | org.apache.maven.plugins 71 | maven-dependency-plugin 72 | 3.8.1 73 | 74 | 75 | org.apache.maven.plugins 76 | maven-javadoc-plugin 77 | 78 | utf-8 79 | true 80 | 81 | 82 | 83 | org.apache.maven.plugins 84 | maven-scm-publish-plugin 85 | 86 | ${project.reporting.outputDirectory} 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | org.apache.maven.plugins 95 | maven-scm-publish-plugin 96 | 97 | 98 | scm-publish 99 | 100 | 101 | publish-scm 102 | 103 | site-deploy 104 | 105 | 106 | 107 | 108 | org.apache.felix 109 | maven-bundle-plugin 110 | 5.1.9 111 | true 112 | 113 | 114 | <_nouses>true 115 | org.codehaus.classworlds.*;org.codehaus.plexus.classworlds.* 116 | 117 | 118 | 119 | 120 | org.apache.maven.plugins 121 | maven-jar-plugin 122 | 123 | 124 | 125 | org.codehaus.plexus.classworlds.launcher.Launcher 126 | 127 | 128 | 129 | 130 | 131 | org.apache.maven.plugins 132 | maven-surefire-plugin 133 | 134 | true 135 | -ea:org.codehaus.classworlds:org.codehaus.plexus.classworlds 136 | 1 137 | 138 | 139 | 140 | org.apache.maven.plugins 141 | maven-compiler-plugin 142 | 143 | 144 | org/codehaus/plexus/classworlds/event/* 145 | 146 | 147 | 148 | 149 | org.apache.maven.plugins 150 | maven-dependency-plugin 151 | 152 | 153 | 154 | copy 155 | 156 | generate-test-resources 157 | 158 | 159 | 160 | org.apache.ant 161 | ant 162 | 1.10.14 163 | 164 | 165 | org.apache.logging.log4j 166 | log4j-api 167 | 2.23.1 168 | 169 | 170 | jakarta.xml.bind 171 | jakarta.xml.bind-api 172 | 4.0.2 173 | 174 | 175 | ${project.build.directory}/test-lib 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | org.apache.maven.plugins 187 | maven-project-info-reports-plugin 188 | 189 | 190 | 191 | summary 192 | index 193 | dependencies 194 | issue-management 195 | scm 196 | 197 | 198 | 199 | 200 | 201 | org.apache.maven.plugins 202 | maven-javadoc-plugin 203 | 204 | 205 | 206 | 207 | 208 | -------------------------------------------------------------------------------- /src/main/aspect/org/codehaus/plexus/classworlds/event/ListenerAspect.aj: -------------------------------------------------------------------------------- 1 | package org.codehaus.plexus.classworlds.event; 2 | 3 | import java.net.URL; 4 | 5 | import org.codehaus.plexus.classworlds.strategy.Strategy; 6 | 7 | /** 8 | * A simple aspect to hook event code in when compiling with debug enabled 9 | * 10 | * @uthor: Andrew Williams 11 | * @since: 1.2-alpha-15 12 | * @version: $Id$ 13 | */ 14 | aspect ListenerAspect 15 | { 16 | // TODO: here we want a proper listener registering system, not just a debugger 17 | private ClassEventDebug classDebugger = new ClassEventDebug(); 18 | private ResourceEventDebug resourceDebugger = new ResourceEventDebug(); 19 | 20 | pointcut loadClass( String name, Strategy strategy ): 21 | args( name ) && target( strategy ) && 22 | call( Class Strategy.loadClass( String ) ); 23 | 24 | before( String name, Strategy strategy ): 25 | loadClass( name, strategy ) 26 | { 27 | classDebugger.lookup( name, strategy ); 28 | } 29 | 30 | after( String name, Strategy strategy ) returning( Class result ): 31 | loadClass( name, strategy ) 32 | { 33 | classDebugger.found( name, strategy, result ); 34 | } 35 | 36 | after( String name, Strategy strategy ) throwing( Exception e ): 37 | loadClass( name, strategy ) 38 | { 39 | classDebugger.failed( name, strategy, e ); 40 | } 41 | 42 | pointcut getResource( String name, Strategy strategy ): 43 | args( name ) && target( strategy ) && 44 | call( URL Strategy.getResource( String ) ); 45 | 46 | before( String name, Strategy strategy ): 47 | getResource( name, strategy ) 48 | { 49 | resourceDebugger.lookup( name, strategy ); 50 | } 51 | 52 | after( String name, Strategy strategy ) returning( URL result ): 53 | getResource( name, strategy ) 54 | { 55 | if ( result == null ) 56 | { 57 | resourceDebugger.failed( name, strategy ); 58 | } 59 | else 60 | { 61 | resourceDebugger.found( name, strategy, result ); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/org/codehaus/classworlds/BytesURLConnection.java: -------------------------------------------------------------------------------- 1 | package org.codehaus.classworlds; 2 | 3 | /* 4 | * Copyright 2001-2010 Codehaus Foundation. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | import java.io.ByteArrayInputStream; 20 | import java.io.InputStream; 21 | import java.net.URL; 22 | import java.net.URLConnection; 23 | 24 | /** 25 | */ 26 | @Deprecated 27 | public class BytesURLConnection extends URLConnection { 28 | protected byte[] content; 29 | 30 | protected int offset; 31 | 32 | protected int length; 33 | 34 | public BytesURLConnection(URL url, byte[] content) { 35 | super(url); 36 | this.content = content; 37 | } 38 | 39 | public void connect() {} 40 | 41 | public InputStream getInputStream() { 42 | return new ByteArrayInputStream(content); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/org/codehaus/classworlds/BytesURLStreamHandler.java: -------------------------------------------------------------------------------- 1 | package org.codehaus.classworlds; 2 | 3 | /* 4 | * Copyright 2001-2010 Codehaus Foundation. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | import java.net.URL; 20 | import java.net.URLConnection; 21 | import java.net.URLStreamHandler; 22 | 23 | /** 24 | * @author Hani Suleiman (hani@formicary.net) 25 | * Date: Oct 20, 2003 26 | * Time: 12:45:18 AM 27 | */ 28 | @Deprecated 29 | public class BytesURLStreamHandler extends URLStreamHandler { 30 | byte[] content; 31 | 32 | int offset; 33 | 34 | int length; 35 | 36 | public BytesURLStreamHandler(byte[] content) { 37 | this.content = content; 38 | } 39 | 40 | public URLConnection openConnection(URL url) { 41 | return new BytesURLConnection(url, content); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/org/codehaus/classworlds/ClassRealm.java: -------------------------------------------------------------------------------- 1 | package org.codehaus.classworlds; 2 | 3 | /* 4 | 5 | Copyright 2002 (C) The Werken Company. All Rights Reserved. 6 | 7 | Redistribution and use of this software and associated documentation 8 | ("Software"), with or without modification, are permitted provided 9 | that the following conditions are met: 10 | 11 | 1. Redistributions of source code must retain copyright 12 | statements and notices. Redistributions must also contain a 13 | copy of this document. 14 | 15 | 2. Redistributions in binary form must reproduce the 16 | above copyright notice, this list of conditions and the 17 | following disclaimer in the documentation and/or other 18 | materials provided with the distribution. 19 | 20 | 3. The name "classworlds" must not be used to endorse or promote 21 | products derived from this Software without prior written 22 | permission of The Werken Company. For written permission, 23 | please contact bob@werken.com. 24 | 25 | 4. Products derived from this Software may not be called "classworlds" 26 | nor may "classworlds" appear in their names without prior written 27 | permission of The Werken Company. "classworlds" is a registered 28 | trademark of The Werken Company. 29 | 30 | 5. Due credit should be given to The Werken Company. 31 | (http://classworlds.werken.com/). 32 | 33 | THIS SOFTWARE IS PROVIDED BY THE WERKEN COMPANY AND CONTRIBUTORS 34 | ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT 35 | NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 36 | FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 37 | THE WERKEN COMPANY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 38 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 39 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 40 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 41 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 42 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 43 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 44 | OF THE POSSIBILITY OF SUCH DAMAGE. 45 | 46 | */ 47 | 48 | import java.io.IOException; 49 | import java.io.InputStream; 50 | import java.net.URL; 51 | import java.util.Enumeration; 52 | 53 | /** 54 | *

Autonomous sub-portion of a ClassWorld.

55 | * 56 | *

This class most closed maps to the ClassLoader 57 | * role from Java and in facts can provide a ClassLoader 58 | * view of itself using {@link #getClassLoader}.

59 | * 60 | * @author bob mcwhirter 61 | * @author Jason van Zyl 62 | */ 63 | @Deprecated 64 | public interface ClassRealm { 65 | String getId(); 66 | 67 | ClassWorld getWorld(); 68 | 69 | void importFrom(String realmId, String pkgName) throws NoSuchRealmException; 70 | 71 | void addConstituent(URL constituent); 72 | 73 | ClassRealm locateSourceRealm(String className); 74 | 75 | void setParent(ClassRealm classRealm); 76 | 77 | ClassRealm createChildRealm(String id) throws DuplicateRealmException; 78 | 79 | ClassLoader getClassLoader(); 80 | 81 | ClassRealm getParent(); 82 | 83 | URL[] getConstituents(); 84 | 85 | // ---------------------------------------------------------------------- 86 | // Classloading 87 | // ---------------------------------------------------------------------- 88 | 89 | Class loadClass(String name) throws ClassNotFoundException; 90 | 91 | // ---------------------------------------------------------------------- 92 | // Resource handling 93 | // ---------------------------------------------------------------------- 94 | 95 | URL getResource(String name); 96 | 97 | Enumeration findResources(String name) throws IOException; 98 | 99 | InputStream getResourceAsStream(String name); 100 | 101 | void display(); 102 | } 103 | -------------------------------------------------------------------------------- /src/main/java/org/codehaus/classworlds/ClassRealmAdapter.java: -------------------------------------------------------------------------------- 1 | package org.codehaus.classworlds; 2 | 3 | /* 4 | * Copyright 2001-2010 Codehaus Foundation. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | import java.io.IOException; 20 | import java.io.InputStream; 21 | import java.net.URL; 22 | import java.util.Enumeration; 23 | 24 | /** 25 | * An adapter for ClassRealms 26 | * 27 | * @author Andrew Williams 28 | */ 29 | @Deprecated 30 | public class ClassRealmAdapter implements ClassRealm { 31 | 32 | public static ClassRealmAdapter getInstance(org.codehaus.plexus.classworlds.realm.ClassRealm newRealm) { 33 | ClassRealmAdapter adapter = new ClassRealmAdapter(newRealm); 34 | 35 | return adapter; 36 | } 37 | 38 | private org.codehaus.plexus.classworlds.realm.ClassRealm realm; 39 | 40 | private ClassRealmAdapter(org.codehaus.plexus.classworlds.realm.ClassRealm newRealm) { 41 | this.realm = newRealm; 42 | } 43 | 44 | public String getId() { 45 | return realm.getId(); 46 | } 47 | 48 | public ClassWorld getWorld() { 49 | return ClassWorldAdapter.getInstance(realm.getWorld()); 50 | } 51 | 52 | public void importFrom(String realmId, String pkgName) throws NoSuchRealmException { 53 | try { 54 | realm.importFrom(realmId, pkgName); 55 | } catch (org.codehaus.plexus.classworlds.realm.NoSuchRealmException e) { 56 | throw new NoSuchRealmException(getWorld(), e.getId()); 57 | } 58 | } 59 | 60 | public void addConstituent(URL constituent) { 61 | realm.addURL(constituent); 62 | } 63 | 64 | public ClassRealm locateSourceRealm(String className) { 65 | ClassLoader importLoader = realm.getImportClassLoader(className); 66 | 67 | if (importLoader instanceof org.codehaus.plexus.classworlds.realm.ClassRealm) { 68 | return ClassRealmAdapter.getInstance((org.codehaus.plexus.classworlds.realm.ClassRealm) importLoader); 69 | } else { 70 | return null; 71 | } 72 | } 73 | 74 | public void setParent(ClassRealm classRealm) { 75 | if (classRealm != null) { 76 | realm.setParentRealm(ClassRealmReverseAdapter.getInstance(classRealm)); 77 | } 78 | } 79 | 80 | public ClassRealm createChildRealm(String id) throws DuplicateRealmException { 81 | try { 82 | return ClassRealmAdapter.getInstance(realm.createChildRealm(id)); 83 | } catch (org.codehaus.plexus.classworlds.realm.DuplicateRealmException e) { 84 | throw new DuplicateRealmException(getWorld(), e.getId()); 85 | } 86 | } 87 | 88 | public ClassLoader getClassLoader() { 89 | return realm; 90 | } 91 | 92 | public ClassRealm getParent() { 93 | return ClassRealmAdapter.getInstance(realm.getParentRealm()); 94 | } 95 | 96 | public ClassRealm getParentRealm() { 97 | return ClassRealmAdapter.getInstance(realm.getParentRealm()); 98 | } 99 | 100 | public URL[] getConstituents() { 101 | return realm.getURLs(); 102 | } 103 | 104 | public Class loadClass(String name) throws ClassNotFoundException { 105 | return realm.loadClass(name); 106 | } 107 | 108 | public URL getResource(String name) { 109 | return realm.getResource(trimLeadingSlash(name)); 110 | } 111 | 112 | public Enumeration findResources(String name) throws IOException { 113 | return realm.findResources(trimLeadingSlash(name)); 114 | } 115 | 116 | public InputStream getResourceAsStream(String name) { 117 | return realm.getResourceAsStream(trimLeadingSlash(name)); 118 | } 119 | 120 | public void display() { 121 | realm.display(); 122 | } 123 | 124 | public boolean equals(Object o) { 125 | if (!(o instanceof ClassRealm)) return false; 126 | 127 | return getId().equals(((ClassRealm) o).getId()); 128 | } 129 | 130 | /** 131 | * Provides backward-compat with the old classworlds which accepted resource names with leading slashes. 132 | */ 133 | private String trimLeadingSlash(String resource) { 134 | if (resource != null && resource.startsWith("/")) { 135 | return resource.substring(1); 136 | } else { 137 | return resource; 138 | } 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /src/main/java/org/codehaus/classworlds/ClassRealmReverseAdapter.java: -------------------------------------------------------------------------------- 1 | package org.codehaus.classworlds; 2 | 3 | /* 4 | * Copyright 2001-2010 Codehaus Foundation. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | import java.io.IOException; 20 | import java.io.InputStream; 21 | import java.net.URL; 22 | import java.util.Enumeration; 23 | 24 | /** 25 | * A reverse adapter for ClassRealms 26 | * 27 | * @author Andrew Williams 28 | */ 29 | @Deprecated 30 | public class ClassRealmReverseAdapter extends org.codehaus.plexus.classworlds.realm.ClassRealm { 31 | 32 | public static ClassRealmReverseAdapter getInstance(ClassRealm oldRealm) { 33 | ClassRealmReverseAdapter adapter = new ClassRealmReverseAdapter(oldRealm); 34 | 35 | return adapter; 36 | } 37 | 38 | private ClassRealm realm; 39 | 40 | private ClassRealmReverseAdapter(ClassRealm oldRealm) { 41 | super(ClassWorldReverseAdapter.getInstance(oldRealm.getWorld()), oldRealm.getId(), oldRealm.getClassLoader()); 42 | this.realm = oldRealm; 43 | } 44 | 45 | public String getId() { 46 | return realm.getId(); 47 | } 48 | 49 | public org.codehaus.plexus.classworlds.ClassWorld getWorld() { 50 | return ClassWorldReverseAdapter.getInstance(realm.getWorld()); 51 | } 52 | 53 | public void importFrom(String realmId, String pkgName) 54 | throws org.codehaus.plexus.classworlds.realm.NoSuchRealmException { 55 | try { 56 | realm.importFrom(realmId, pkgName); 57 | } catch (NoSuchRealmException e) { 58 | throw new org.codehaus.plexus.classworlds.realm.NoSuchRealmException(getWorld(), e.getId()); 59 | } 60 | } 61 | 62 | public void addURL(URL constituent) { 63 | realm.addConstituent(constituent); 64 | } 65 | 66 | public org.codehaus.plexus.classworlds.realm.ClassRealm locateSourceRealm(String className) { 67 | return getInstance(realm.locateSourceRealm(className)); 68 | } 69 | 70 | public void setParentRealm(org.codehaus.plexus.classworlds.realm.ClassRealm classRealm) { 71 | realm.setParent(ClassRealmAdapter.getInstance(classRealm)); 72 | } 73 | 74 | public org.codehaus.plexus.classworlds.realm.ClassRealm createChildRealm(String id) 75 | throws org.codehaus.plexus.classworlds.realm.DuplicateRealmException { 76 | try { 77 | return getInstance(realm.createChildRealm(id)); 78 | } catch (DuplicateRealmException e) { 79 | throw new org.codehaus.plexus.classworlds.realm.DuplicateRealmException(getWorld(), e.getId()); 80 | } 81 | } 82 | 83 | public ClassLoader getClassLoader() { 84 | return realm.getClassLoader(); 85 | } 86 | 87 | public org.codehaus.plexus.classworlds.realm.ClassRealm getParentRealm() { 88 | return getInstance(realm.getParent()); 89 | } 90 | 91 | public URL[] getURLs() { 92 | return realm.getConstituents(); 93 | } 94 | 95 | public Class loadClass(String name) throws ClassNotFoundException { 96 | return realm.loadClass(name); 97 | } 98 | 99 | public URL getResource(String name) { 100 | return realm.getResource(name); 101 | } 102 | 103 | public Enumeration findResources(String name) throws IOException { 104 | return realm.findResources(name); 105 | } 106 | 107 | public InputStream getResourceAsStream(String name) { 108 | return realm.getResourceAsStream(name); 109 | } 110 | 111 | public void display() { 112 | realm.display(); 113 | } 114 | 115 | public boolean equals(Object o) { 116 | if (!(o instanceof ClassRealm)) return false; 117 | 118 | return getId().equals(((ClassRealm) o).getId()); 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /src/main/java/org/codehaus/classworlds/ClassWorld.java: -------------------------------------------------------------------------------- 1 | package org.codehaus.classworlds; 2 | 3 | /* 4 | * Copyright 2001-2010 Codehaus Foundation. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | import java.util.Collection; 20 | 21 | /** 22 | * A compatibility wrapper for org.codehaus.plexus.classworlds.ClassWorld 23 | * provided for legacy code 24 | * 25 | * @author Andrew Williams 26 | */ 27 | @Deprecated 28 | public class ClassWorld { 29 | private ClassWorldAdapter adapter; 30 | 31 | public ClassWorld(String realmId, ClassLoader classLoader) { 32 | adapter = ClassWorldAdapter.getInstance(new org.codehaus.plexus.classworlds.ClassWorld(realmId, classLoader)); 33 | } 34 | 35 | public ClassWorld() { 36 | adapter = ClassWorldAdapter.getInstance(new org.codehaus.plexus.classworlds.ClassWorld()); 37 | } 38 | 39 | public ClassWorld(boolean ignore) { 40 | /* fake */ 41 | } 42 | 43 | public ClassRealm newRealm(String id) throws DuplicateRealmException { 44 | return adapter.newRealm(id); 45 | } 46 | 47 | public ClassRealm newRealm(String id, ClassLoader classLoader) throws DuplicateRealmException { 48 | return adapter.newRealm(id, classLoader); 49 | } 50 | 51 | public void disposeRealm(String id) throws NoSuchRealmException { 52 | adapter.disposeRealm(id); 53 | } 54 | 55 | public ClassRealm getRealm(String id) throws NoSuchRealmException { 56 | return adapter.getRealm(id); 57 | } 58 | 59 | public Collection getRealms() { 60 | return adapter.getRealms(); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/org/codehaus/classworlds/ClassWorldAdapter.java: -------------------------------------------------------------------------------- 1 | package org.codehaus.classworlds; 2 | 3 | /* 4 | * Copyright 2001-2010 Codehaus Foundation. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | import java.util.Collection; 20 | import java.util.Vector; 21 | 22 | /** 23 | * An adapter for ClassWorlds 24 | * 25 | * @author Andrew Williams 26 | */ 27 | @Deprecated 28 | public class ClassWorldAdapter extends ClassWorld { 29 | 30 | public static ClassWorldAdapter getInstance(org.codehaus.plexus.classworlds.ClassWorld newWorld) { 31 | return new ClassWorldAdapter(newWorld); 32 | } 33 | 34 | private org.codehaus.plexus.classworlds.ClassWorld world; 35 | 36 | private ClassWorldAdapter(org.codehaus.plexus.classworlds.ClassWorld newWorld) { 37 | super(false); 38 | this.world = newWorld; 39 | } 40 | 41 | public ClassRealm newRealm(String id) throws DuplicateRealmException { 42 | try { 43 | return ClassRealmAdapter.getInstance(world.newRealm(id)); 44 | } catch (org.codehaus.plexus.classworlds.realm.DuplicateRealmException e) { 45 | throw new DuplicateRealmException(this, e.getId()); 46 | } 47 | } 48 | 49 | public ClassRealm newRealm(String id, ClassLoader classLoader) throws DuplicateRealmException { 50 | try { 51 | return ClassRealmAdapter.getInstance(world.newRealm(id, classLoader)); 52 | } catch (org.codehaus.plexus.classworlds.realm.DuplicateRealmException e) { 53 | throw new DuplicateRealmException(this, e.getId()); 54 | } 55 | } 56 | 57 | public void disposeRealm(String id) throws NoSuchRealmException { 58 | try { 59 | world.disposeRealm(id); 60 | } catch (org.codehaus.plexus.classworlds.realm.NoSuchRealmException e) { 61 | throw new NoSuchRealmException(this, e.getId()); 62 | } 63 | } 64 | 65 | public ClassRealm getRealm(String id) throws NoSuchRealmException { 66 | try { 67 | return ClassRealmAdapter.getInstance(world.getRealm(id)); 68 | } catch (org.codehaus.plexus.classworlds.realm.NoSuchRealmException e) { 69 | throw new NoSuchRealmException(this, e.getId()); 70 | } 71 | } 72 | 73 | public Collection getRealms() { 74 | Collection realms = world.getRealms(); 75 | Vector ret = new Vector<>(); 76 | for (org.codehaus.plexus.classworlds.realm.ClassRealm classRealm : realms) { 77 | ret.add(ClassRealmAdapter.getInstance(classRealm)); 78 | } 79 | 80 | return ret; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/org/codehaus/classworlds/ClassWorldException.java: -------------------------------------------------------------------------------- 1 | package org.codehaus.classworlds; 2 | 3 | /* 4 | 5 | Copyright 2002 (C) The Werken Company. All Rights Reserved. 6 | 7 | Redistribution and use of this software and associated documentation 8 | ("Software"), with or without modification, are permitted provided 9 | that the following conditions are met: 10 | 11 | 1. Redistributions of source code must retain copyright 12 | statements and notices. Redistributions must also contain a 13 | copy of this document. 14 | 15 | 2. Redistributions in binary form must reproduce the 16 | above copyright notice, this list of conditions and the 17 | following disclaimer in the documentation and/or other 18 | materials provided with the distribution. 19 | 20 | 3. The name "classworlds" must not be used to endorse or promote 21 | products derived from this Software without prior written 22 | permission of The Werken Company. For written permission, 23 | please contact bob@werken.com. 24 | 25 | 4. Products derived from this Software may not be called "classworlds" 26 | nor may "classworlds" appear in their names without prior written 27 | permission of The Werken Company. "classworlds" is a registered 28 | trademark of The Werken Company. 29 | 30 | 5. Due credit should be given to The Werken Company. 31 | (http://classworlds.werken.com/). 32 | 33 | THIS SOFTWARE IS PROVIDED BY THE WERKEN COMPANY AND CONTRIBUTORS 34 | ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT 35 | NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 36 | FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 37 | THE WERKEN COMPANY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 38 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 39 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 40 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 41 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 42 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 43 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 44 | OF THE POSSIBILITY OF SUCH DAMAGE. 45 | 46 | */ 47 | 48 | /** 49 | * Base exception for ClassWorld errors. 50 | * 51 | * @author bob mcwhirter 52 | */ 53 | @Deprecated 54 | public class ClassWorldException extends Exception { 55 | // ------------------------------------------------------------ 56 | // Instance members 57 | // ------------------------------------------------------------ 58 | 59 | /** 60 | * The world. 61 | */ 62 | private ClassWorld world; 63 | 64 | // ------------------------------------------------------------ 65 | // Constructors 66 | // ------------------------------------------------------------ 67 | 68 | /** 69 | * Construct. 70 | * 71 | * @param world The world. 72 | */ 73 | public ClassWorldException(final ClassWorld world) { 74 | this.world = world; 75 | } 76 | 77 | /** 78 | * Construct. 79 | * 80 | * @param world The world. 81 | * @param msg The detail message. 82 | */ 83 | public ClassWorldException(final ClassWorld world, final String msg) { 84 | super(msg); 85 | this.world = world; 86 | } 87 | 88 | // ------------------------------------------------------------ 89 | // Instance methods 90 | // ------------------------------------------------------------ 91 | 92 | /** 93 | * Retrieve the world. 94 | * 95 | * @return The world. 96 | */ 97 | public ClassWorld getWorld() { 98 | return this.world; 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /src/main/java/org/codehaus/classworlds/ClassWorldReverseAdapter.java: -------------------------------------------------------------------------------- 1 | package org.codehaus.classworlds; 2 | 3 | /* 4 | * Copyright 2001-2010 Codehaus Foundation. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | import java.util.Collection; 20 | import java.util.HashMap; 21 | import java.util.Vector; 22 | 23 | /** 24 | * A reverse adapter for ClassWorlds 25 | * 26 | * @author Andrew Williams 27 | */ 28 | @Deprecated 29 | public class ClassWorldReverseAdapter extends org.codehaus.plexus.classworlds.ClassWorld { 30 | private static HashMap instances = new HashMap(); 31 | 32 | public static ClassWorldReverseAdapter getInstance(ClassWorld oldWorld) { 33 | if (instances.containsKey(oldWorld)) return (ClassWorldReverseAdapter) instances.get(oldWorld); 34 | 35 | ClassWorldReverseAdapter adapter = new ClassWorldReverseAdapter(oldWorld); 36 | instances.put(oldWorld, adapter); 37 | 38 | return adapter; 39 | } 40 | 41 | private ClassWorld world; 42 | 43 | private ClassWorldReverseAdapter(ClassWorld newWorld) { 44 | super(); 45 | this.world = newWorld; 46 | } 47 | 48 | public org.codehaus.plexus.classworlds.realm.ClassRealm newRealm(String id) 49 | throws org.codehaus.plexus.classworlds.realm.DuplicateRealmException { 50 | try { 51 | return ClassRealmReverseAdapter.getInstance(world.newRealm(id)); 52 | } catch (DuplicateRealmException e) { 53 | throw new org.codehaus.plexus.classworlds.realm.DuplicateRealmException(this, e.getId()); 54 | } 55 | } 56 | 57 | public org.codehaus.plexus.classworlds.realm.ClassRealm newRealm(String id, ClassLoader classLoader) 58 | throws org.codehaus.plexus.classworlds.realm.DuplicateRealmException { 59 | try { 60 | return ClassRealmReverseAdapter.getInstance(world.newRealm(id, classLoader)); 61 | } catch (DuplicateRealmException e) { 62 | throw new org.codehaus.plexus.classworlds.realm.DuplicateRealmException(this, e.getId()); 63 | } 64 | } 65 | 66 | public void disposeRealm(String id) throws org.codehaus.plexus.classworlds.realm.NoSuchRealmException { 67 | try { 68 | world.disposeRealm(id); 69 | } catch (NoSuchRealmException e) { 70 | throw new org.codehaus.plexus.classworlds.realm.NoSuchRealmException(this, e.getId()); 71 | } 72 | } 73 | 74 | public org.codehaus.plexus.classworlds.realm.ClassRealm getRealm(String id) 75 | throws org.codehaus.plexus.classworlds.realm.NoSuchRealmException { 76 | try { 77 | return ClassRealmReverseAdapter.getInstance(world.getRealm(id)); 78 | } catch (NoSuchRealmException e) { 79 | throw new org.codehaus.plexus.classworlds.realm.NoSuchRealmException(this, e.getId()); 80 | } 81 | } 82 | 83 | public Collection getRealms() { 84 | Collection realms = world.getRealms(); 85 | Vector ret = new Vector(); 86 | 87 | for (Object o : realms) { 88 | ClassRealm realm = (ClassRealm) o; 89 | ret.add(ClassRealmReverseAdapter.getInstance(realm)); 90 | } 91 | 92 | return ret; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/main/java/org/codehaus/classworlds/ConfigurationException.java: -------------------------------------------------------------------------------- 1 | package org.codehaus.classworlds; 2 | 3 | /* 4 | 5 | Copyright 2002 (C) The Werken Company. All Rights Reserved. 6 | 7 | Redistribution and use of this software and associated documentation 8 | ("Software"), with or without modification, are permitted provided 9 | that the following conditions are met: 10 | 11 | 1. Redistributions of source code must retain copyright 12 | statements and notices. Redistributions must also contain a 13 | copy of this document. 14 | 15 | 2. Redistributions in binary form must reproduce the 16 | above copyright notice, this list of conditions and the 17 | following disclaimer in the documentation and/or other 18 | materials provided with the distribution. 19 | 20 | 3. The name "classworlds" must not be used to endorse or promote 21 | products derived from this Software without prior written 22 | permission of The Werken Company. For written permission, 23 | please contact bob@werken.com. 24 | 25 | 4. Products derived from this Software may not be called "classworlds" 26 | nor may "classworlds" appear in their names without prior written 27 | permission of The Werken Company. "classworlds" is a registered 28 | trademark of The Werken Company. 29 | 30 | 5. Due credit should be given to The Werken Company. 31 | (http://classworlds.werken.com/). 32 | 33 | THIS SOFTWARE IS PROVIDED BY THE WERKEN COMPANY AND CONTRIBUTORS 34 | ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT 35 | NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 36 | FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 37 | THE WERKEN COMPANY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 38 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 39 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 40 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 41 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 42 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 43 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 44 | OF THE POSSIBILITY OF SUCH DAMAGE. 45 | 46 | */ 47 | 48 | /** 49 | * Indicates an error during Launcher configuration. 50 | * 51 | * @author bob mcwhirter 52 | */ 53 | @Deprecated 54 | public class ConfigurationException extends Exception { 55 | /** 56 | * Construct. 57 | * 58 | * @param msg The message. 59 | */ 60 | public ConfigurationException(String msg) { 61 | super(msg); 62 | } 63 | 64 | /** 65 | * Construct. 66 | * 67 | * @param msg The message. 68 | * @param lineNo The number of configuraton line where the problem occured. 69 | * @param line The configuration line where the problem occured. 70 | */ 71 | public ConfigurationException(String msg, int lineNo, String line) { 72 | super(msg + " (" + lineNo + "): " + line); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/org/codehaus/classworlds/Configurator.java: -------------------------------------------------------------------------------- 1 | package org.codehaus.classworlds; 2 | 3 | /* 4 | * Copyright 2001-2010 Codehaus Foundation. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | import java.io.FileNotFoundException; 20 | import java.io.IOException; 21 | import java.io.InputStream; 22 | import java.net.MalformedURLException; 23 | 24 | /** 25 | * A compatibility wrapper for org.codehaus.plexus.classworlds.launcher.Configurator 26 | * provided for legacy code 27 | * 28 | * @author Andrew Williams 29 | */ 30 | @Deprecated 31 | public class Configurator { 32 | private ConfiguratorAdapter config; 33 | 34 | /** Construct. 35 | * 36 | * @param launcher The launcher to configure. 37 | */ 38 | public Configurator(Launcher launcher) { 39 | config = ConfiguratorAdapter.getInstance( 40 | new org.codehaus.plexus.classworlds.launcher.Configurator(launcher), launcher); 41 | } 42 | 43 | /** Construct. 44 | * 45 | * @param world The classWorld to configure. 46 | */ 47 | public Configurator(ClassWorld world) { 48 | config = ConfiguratorAdapter.getInstance( 49 | new org.codehaus.plexus.classworlds.launcher.Configurator(ClassWorldReverseAdapter.getInstance(world)), 50 | world); 51 | } 52 | 53 | /** set world. 54 | * this setter is provided so you can use the same configurator to configure several "worlds" 55 | * 56 | * @param world The classWorld to configure. 57 | */ 58 | public void setClassWorld(ClassWorld world) { 59 | config.setClassWorld(world); 60 | } 61 | 62 | /** 63 | * Configure from a file. 64 | * 65 | * @param is The config input stream 66 | * @throws IOException If an error occurs reading the config file. 67 | * @throws MalformedURLException If the config file contains invalid URLs. 68 | * @throws ConfigurationException If the config file is corrupt. 69 | * @throws DuplicateRealmException If the config file defines two realms with the same id. 70 | * @throws NoSuchRealmException If the config file defines a main entry point in 71 | * a non-existent realm. 72 | */ 73 | public void configure(InputStream is) 74 | throws IOException, MalformedURLException, ConfigurationException, DuplicateRealmException, 75 | NoSuchRealmException { 76 | config.configureAdapter(is); 77 | } 78 | 79 | /** 80 | * Associate parent realms with their children. 81 | */ 82 | protected void associateRealms() { 83 | config.associateRealms(); 84 | } 85 | 86 | /** 87 | * Load a glob into the specified classloader. 88 | * 89 | * @param line The path configuration line. 90 | * @param realm The realm to populate 91 | * @throws MalformedURLException If the line does not represent 92 | * a valid path element. 93 | * @throws FileNotFoundException If the line does not represent 94 | * a valid path element in the filesystem. 95 | */ 96 | protected void loadGlob(String line, ClassRealm realm) throws MalformedURLException, FileNotFoundException { 97 | loadGlob(line, realm, false); 98 | } 99 | 100 | /** 101 | * Load a glob into the specified classloader. 102 | * 103 | * @param line The path configuration line. 104 | * @param realm The realm to populate 105 | * @param optionally Whether the path is optional or required 106 | * @throws MalformedURLException If the line does not represent 107 | * a valid path element. 108 | * @throws FileNotFoundException If the line does not represent 109 | * a valid path element in the filesystem. 110 | */ 111 | protected void loadGlob(String line, ClassRealm realm, boolean optionally) 112 | throws MalformedURLException, FileNotFoundException { 113 | config.loadGlob(line, realm, optionally); 114 | } 115 | 116 | /** 117 | * Filter a string for system properties. 118 | * 119 | * @param text The text to filter. 120 | * @return The filtered text. 121 | * @throws ConfigurationException If the property does not 122 | * exist or if there is a syntax error. 123 | */ 124 | protected String filter(String text) throws ConfigurationException { 125 | return config.filter(text); 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /src/main/java/org/codehaus/classworlds/ConfiguratorAdapter.java: -------------------------------------------------------------------------------- 1 | package org.codehaus.classworlds; 2 | 3 | /* 4 | * Copyright 2001-2010 Codehaus Foundation. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | import java.io.IOException; 20 | import java.io.InputStream; 21 | import java.net.MalformedURLException; 22 | 23 | /** 24 | */ 25 | @Deprecated 26 | public class ConfiguratorAdapter extends Configurator { 27 | 28 | public static ConfiguratorAdapter getInstance( 29 | org.codehaus.plexus.classworlds.launcher.Configurator newConfig, Launcher launcher) { 30 | ConfiguratorAdapter adapter = new ConfiguratorAdapter(newConfig, launcher); 31 | 32 | return adapter; 33 | } 34 | 35 | public static ConfiguratorAdapter getInstance( 36 | org.codehaus.plexus.classworlds.launcher.Configurator newConfig, ClassWorld world) { 37 | ConfiguratorAdapter adapter = new ConfiguratorAdapter(newConfig, world); 38 | 39 | return adapter; 40 | } 41 | 42 | private org.codehaus.plexus.classworlds.launcher.Configurator config; 43 | 44 | private ConfiguratorAdapter(org.codehaus.plexus.classworlds.launcher.Configurator config, Launcher launcher) { 45 | super(launcher); 46 | this.config = config; 47 | } 48 | 49 | private ConfiguratorAdapter(org.codehaus.plexus.classworlds.launcher.Configurator config, ClassWorld world) { 50 | super(world); 51 | this.config = config; 52 | } 53 | 54 | public void associateRealms() { 55 | config.associateRealms(); 56 | } 57 | 58 | public void configureAdapter(InputStream is) 59 | throws IOException, MalformedURLException, ConfigurationException, DuplicateRealmException, 60 | NoSuchRealmException { 61 | try { 62 | config.configure(is); 63 | } catch (org.codehaus.plexus.classworlds.launcher.ConfigurationException e) { 64 | throw new ConfigurationException(e.getMessage()); 65 | } catch (org.codehaus.plexus.classworlds.realm.DuplicateRealmException e) { 66 | throw new DuplicateRealmException(ClassWorldAdapter.getInstance(e.getWorld()), e.getId()); 67 | } catch (org.codehaus.plexus.classworlds.realm.NoSuchRealmException e) { 68 | throw new NoSuchRealmException(ClassWorldAdapter.getInstance(e.getWorld()), e.getId()); 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/org/codehaus/classworlds/DefaultClassRealm.java: -------------------------------------------------------------------------------- 1 | package org.codehaus.classworlds; 2 | 3 | /* 4 | * Copyright 2001-2010 Codehaus Foundation. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | /* 20 | * A compatibility wrapper for org.codehaus.plexus.classworlds.realm.ClassRealm 21 | * provided for legacy code 22 | * 23 | * @author Andrew Williams 24 | */ 25 | 26 | import java.io.File; 27 | import java.io.IOException; 28 | import java.io.InputStream; 29 | import java.net.URL; 30 | import java.util.Enumeration; 31 | 32 | @Deprecated 33 | public class DefaultClassRealm implements ClassRealm { 34 | private ClassRealmAdapter adapter; 35 | 36 | public DefaultClassRealm(ClassWorld world, String id) { 37 | this(world, id, null); 38 | } 39 | 40 | public DefaultClassRealm(ClassWorld world, String id, ClassLoader foreignClassLoader) { 41 | this.adapter = ClassRealmAdapter.getInstance(new org.codehaus.plexus.classworlds.realm.ClassRealm( 42 | ClassWorldReverseAdapter.getInstance(world), id, foreignClassLoader)); 43 | } 44 | 45 | public URL[] getConstituents() { 46 | return adapter.getConstituents(); 47 | } 48 | 49 | public ClassRealm getParent() { 50 | return adapter.getParentRealm(); 51 | } 52 | 53 | public void setParent(ClassRealm parent) { 54 | adapter.setParent(parent); 55 | } 56 | 57 | public String getId() { 58 | return adapter.getId(); 59 | } 60 | 61 | public ClassWorld getWorld() { 62 | return adapter.getWorld(); 63 | } 64 | 65 | public void importFrom(String realmId, String packageName) throws NoSuchRealmException { 66 | adapter.importFrom(realmId, packageName); 67 | } 68 | 69 | public void addConstituent(URL constituent) { 70 | adapter.addConstituent(constituent); 71 | } 72 | 73 | /** 74 | * Adds a byte[] class definition as a constituent for locating classes. 75 | * Currently uses BytesURLStreamHandler to hold a reference of the byte[] in memory. 76 | * This ensures we have a unifed URL resource model for all constituents. 77 | * The code to cache to disk is commented out - maybe a property to choose which method? 78 | * 79 | * @param constituent class name 80 | * @param b the class definition as a byte[] 81 | * @throws ClassNotFoundException when class couldn't be loaded 82 | */ 83 | public void addConstituent(String constituent, byte[] b) throws ClassNotFoundException { 84 | try { 85 | File path, file; 86 | if (constituent.lastIndexOf('.') != -1) { 87 | path = new File("byteclass/" 88 | + constituent 89 | .substring(0, constituent.lastIndexOf('.') + 1) 90 | .replace('.', File.separatorChar)); 91 | 92 | file = new File(path, constituent.substring(constituent.lastIndexOf('.') + 1) + ".class"); 93 | } else { 94 | path = new File("byteclass/"); 95 | 96 | file = new File(path, constituent + ".class"); 97 | } 98 | 99 | addConstituent(new URL(null, file.toURI().toURL().toExternalForm(), new BytesURLStreamHandler(b))); 100 | } catch (java.io.IOException e) { 101 | throw new ClassNotFoundException("Couldn't load byte stream.", e); 102 | } 103 | } 104 | 105 | public ClassRealm locateSourceRealm(String classname) { 106 | return adapter.locateSourceRealm(classname); 107 | } 108 | 109 | public ClassLoader getClassLoader() { 110 | return adapter.getClassLoader(); 111 | } 112 | 113 | public ClassRealm createChildRealm(String id) throws DuplicateRealmException { 114 | return adapter.createChildRealm(id); 115 | } 116 | 117 | // ---------------------------------------------------------------------- 118 | // ClassLoader API 119 | // ---------------------------------------------------------------------- 120 | 121 | public Class loadClass(String name) throws ClassNotFoundException { 122 | return adapter.loadClass(name); 123 | } 124 | 125 | public URL getResource(String name) { 126 | return adapter.getResource(name); 127 | } 128 | 129 | public InputStream getResourceAsStream(String name) { 130 | return adapter.getResourceAsStream(name); 131 | } 132 | 133 | public Enumeration findResources(String name) throws IOException { 134 | return adapter.findResources(name); 135 | } 136 | 137 | public void display() { 138 | adapter.display(); 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /src/main/java/org/codehaus/classworlds/DuplicateRealmException.java: -------------------------------------------------------------------------------- 1 | package org.codehaus.classworlds; 2 | 3 | /* 4 | 5 | Copyright 2002 (C) The Werken Company. All Rights Reserved. 6 | 7 | Redistribution and use of this software and associated documentation 8 | ("Software"), with or without modification, are permitted provided 9 | that the following conditions are met: 10 | 11 | 1. Redistributions of source code must retain copyright 12 | statements and notices. Redistributions must also contain a 13 | copy of this document. 14 | 15 | 2. Redistributions in binary form must reproduce the 16 | above copyright notice, this list of conditions and the 17 | following disclaimer in the documentation and/or other 18 | materials provided with the distribution. 19 | 20 | 3. The name "classworlds" must not be used to endorse or promote 21 | products derived from this Software without prior written 22 | permission of The Werken Company. For written permission, 23 | please contact bob@werken.com. 24 | 25 | 4. Products derived from this Software may not be called "classworlds" 26 | nor may "classworlds" appear in their names without prior written 27 | permission of The Werken Company. "classworlds" is a registered 28 | trademark of The Werken Company. 29 | 30 | 5. Due credit should be given to The Werken Company. 31 | (http://classworlds.werken.com/). 32 | 33 | THIS SOFTWARE IS PROVIDED BY THE WERKEN COMPANY AND CONTRIBUTORS 34 | ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT 35 | NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 36 | FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 37 | THE WERKEN COMPANY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 38 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 39 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 40 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 41 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 42 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 43 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 44 | OF THE POSSIBILITY OF SUCH DAMAGE. 45 | 46 | */ 47 | 48 | /** 49 | * Indicates an attempt to add a ClassRealm to a 50 | * ClassWorld with a duplicate id. 51 | * 52 | * @author bob mcwhirter 53 | */ 54 | @Deprecated 55 | public class DuplicateRealmException extends ClassWorldException { 56 | // ------------------------------------------------------------ 57 | // Instance members 58 | // ------------------------------------------------------------ 59 | 60 | /** 61 | * The realm id. 62 | */ 63 | private String id; 64 | 65 | // ------------------------------------------------------------ 66 | // Constructors 67 | // ------------------------------------------------------------ 68 | 69 | /** 70 | * Construct. 71 | * 72 | * @param world The world. 73 | * @param id The realm id. 74 | */ 75 | public DuplicateRealmException(ClassWorld world, String id) { 76 | super(world, id); 77 | this.id = id; 78 | } 79 | 80 | // ------------------------------------------------------------ 81 | // Instance methods 82 | // ------------------------------------------------------------ 83 | 84 | /** 85 | * Retrieve the duplicate realm id. 86 | * 87 | * @return The id. 88 | */ 89 | public String getId() { 90 | return this.id; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/main/java/org/codehaus/classworlds/Launcher.java: -------------------------------------------------------------------------------- 1 | package org.codehaus.classworlds; 2 | 3 | /* 4 | * Copyright 2001-2010 Codehaus Foundation. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | /** 20 | * A compatibility wrapper for org.codehaus.plexus.classworlds.launcher.Launcher 21 | * provided for legacy code 22 | * 23 | * @author Andrew Williams 24 | */ 25 | @Deprecated 26 | public class Launcher extends org.codehaus.plexus.classworlds.launcher.Launcher { 27 | public Launcher() {} 28 | 29 | // ------------------------------------------------------------ 30 | // Class methods 31 | // ------------------------------------------------------------ 32 | 33 | /** 34 | * Launch the launcher from the command line. 35 | * Will exit using System.exit with an exit code of 0 for success, 100 if there was an unknown exception, 36 | * or some other code for an application error. 37 | * 38 | * @param args The application command-line arguments. 39 | */ 40 | public static void main(String[] args) { 41 | org.codehaus.plexus.classworlds.launcher.Launcher.main(args); 42 | } 43 | 44 | /** 45 | * Launch the launcher. 46 | * 47 | * @param args The application command-line arguments. 48 | * @return an integer exit code 49 | * @throws Exception If an error occurs. 50 | */ 51 | public static int mainWithExitCode(String[] args) throws Exception { 52 | return org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(args); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/org/codehaus/classworlds/NoSuchRealmException.java: -------------------------------------------------------------------------------- 1 | package org.codehaus.classworlds; 2 | 3 | /* 4 | 5 | Copyright 2002 (C) The Werken Company. All Rights Reserved. 6 | 7 | Redistribution and use of this software and associated documentation 8 | ("Software"), with or without modification, are permitted provided 9 | that the following conditions are met: 10 | 11 | 1. Redistributions of source code must retain copyright 12 | statements and notices. Redistributions must also contain a 13 | copy of this document. 14 | 15 | 2. Redistributions in binary form must reproduce the 16 | above copyright notice, this list of conditions and the 17 | following disclaimer in the documentation and/or other 18 | materials provided with the distribution. 19 | 20 | 3. The name "classworlds" must not be used to endorse or promote 21 | products derived from this Software without prior written 22 | permission of The Werken Company. For written permission, 23 | please contact bob@werken.com. 24 | 25 | 4. Products derived from this Software may not be called "classworlds" 26 | nor may "classworlds" appear in their names without prior written 27 | permission of The Werken Company. "classworlds" is a registered 28 | trademark of The Werken Company. 29 | 30 | 5. Due credit should be given to The Werken Company. 31 | (http://classworlds.werken.com/). 32 | 33 | THIS SOFTWARE IS PROVIDED BY THE WERKEN COMPANY AND CONTRIBUTORS 34 | ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT 35 | NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 36 | FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 37 | THE WERKEN COMPANY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 38 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 39 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 40 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 41 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 42 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 43 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 44 | OF THE POSSIBILITY OF SUCH DAMAGE. 45 | 46 | */ 47 | 48 | /** 49 | * Indicates an attempt to retrieve a ClassRealm from a 50 | * ClassWorld with an invalid id. 51 | * 52 | * @author bob mcwhirter 53 | */ 54 | @Deprecated 55 | public class NoSuchRealmException extends ClassWorldException { 56 | // ------------------------------------------------------------ 57 | // Instance members 58 | // ------------------------------------------------------------ 59 | 60 | /** 61 | * The realm id. 62 | */ 63 | private String id; 64 | 65 | // ------------------------------------------------------------ 66 | // Constructors 67 | // ------------------------------------------------------------ 68 | 69 | /** 70 | * Construct. 71 | * 72 | * @param world The world. 73 | * @param id The realm id. 74 | */ 75 | public NoSuchRealmException(ClassWorld world, String id) { 76 | super(world, id); 77 | this.id = id; 78 | } 79 | 80 | // ------------------------------------------------------------ 81 | // Instance methods 82 | // ------------------------------------------------------------ 83 | 84 | /** 85 | * Retrieve the invalid realm id. 86 | * 87 | * @return The id. 88 | */ 89 | public String getId() { 90 | return this.id; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/main/java/org/codehaus/plexus/classworlds/ClassWorld.java: -------------------------------------------------------------------------------- 1 | package org.codehaus.plexus.classworlds; 2 | 3 | /* 4 | * Copyright 2001-2006 Codehaus Foundation. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | import java.io.Closeable; 20 | import java.io.IOException; 21 | import java.util.ArrayList; 22 | import java.util.Collection; 23 | import java.util.Collections; 24 | import java.util.LinkedHashMap; 25 | import java.util.List; 26 | import java.util.Map; 27 | import java.util.function.Predicate; 28 | 29 | import org.codehaus.plexus.classworlds.realm.ClassRealm; 30 | import org.codehaus.plexus.classworlds.realm.DuplicateRealmException; 31 | import org.codehaus.plexus.classworlds.realm.FilteredClassRealm; 32 | import org.codehaus.plexus.classworlds.realm.NoSuchRealmException; 33 | 34 | /** 35 | * A collection of ClassRealms, indexed by id. 36 | * 37 | * @author bob mcwhirter 38 | */ 39 | public class ClassWorld implements Closeable { 40 | private Map realms; 41 | 42 | private final List listeners = new ArrayList<>(); 43 | 44 | public ClassWorld(String realmId, ClassLoader classLoader) { 45 | this(); 46 | 47 | try { 48 | newRealm(realmId, classLoader); 49 | } catch (DuplicateRealmException e) { 50 | // Will never happen as we are just creating the world. 51 | } 52 | } 53 | 54 | public ClassWorld() { 55 | this.realms = new LinkedHashMap<>(); 56 | } 57 | 58 | public ClassRealm newRealm(String id) throws DuplicateRealmException { 59 | return newRealm(id, getClass().getClassLoader()); 60 | } 61 | 62 | public ClassRealm newRealm(String id, ClassLoader classLoader) throws DuplicateRealmException { 63 | return newRealm(id, classLoader, null); 64 | } 65 | 66 | /** 67 | * Adds a class realm with filtering. 68 | * Only resources/classes whose name matches a given predicate are exposed. 69 | * @param id The identifier for this realm, must not be null. 70 | * @param classLoader The base class loader for this realm, may be null to use the bootstrap class 71 | * loader. 72 | * @param filter a predicate to apply to each resource name to determine if it should be loaded through this class loader 73 | * @return the created class realm 74 | * @throws DuplicateRealmException in case a realm with the given id does already exist 75 | * @since 2.7.0 76 | * @see FilteredClassRealm 77 | */ 78 | public synchronized ClassRealm newRealm(String id, ClassLoader classLoader, Predicate filter) 79 | throws DuplicateRealmException { 80 | if (realms.containsKey(id)) { 81 | throw new DuplicateRealmException(this, id); 82 | } 83 | 84 | ClassRealm realm; 85 | 86 | if (filter == null) { 87 | realm = new ClassRealm(this, id, classLoader); 88 | } else { 89 | realm = new FilteredClassRealm(filter, this, id, classLoader); 90 | } 91 | realms.put(id, realm); 92 | 93 | for (ClassWorldListener listener : listeners) { 94 | listener.realmCreated(realm); 95 | } 96 | 97 | return realm; 98 | } 99 | 100 | /** 101 | * Closes all contained class realms. 102 | * @since 2.7.0 103 | */ 104 | @Override 105 | public synchronized void close() throws IOException { 106 | realms.values().stream().forEach(this::disposeRealm); 107 | realms.clear(); 108 | } 109 | 110 | public synchronized void disposeRealm(String id) throws NoSuchRealmException { 111 | ClassRealm realm = realms.remove(id); 112 | 113 | if (realm != null) { 114 | disposeRealm(realm); 115 | } else { 116 | throw new NoSuchRealmException(this, id); 117 | } 118 | } 119 | 120 | private void disposeRealm(ClassRealm realm) { 121 | try { 122 | realm.close(); 123 | } catch (IOException ignore) { 124 | } 125 | for (ClassWorldListener listener : listeners) { 126 | listener.realmDisposed(realm); 127 | } 128 | } 129 | 130 | public synchronized ClassRealm getRealm(String id) throws NoSuchRealmException { 131 | if (realms.containsKey(id)) { 132 | return realms.get(id); 133 | } 134 | 135 | throw new NoSuchRealmException(this, id); 136 | } 137 | 138 | public synchronized Collection getRealms() { 139 | return Collections.unmodifiableList(new ArrayList<>(realms.values())); 140 | } 141 | 142 | // from exports branch 143 | public synchronized ClassRealm getClassRealm(String id) { 144 | if (realms.containsKey(id)) { 145 | return realms.get(id); 146 | } 147 | 148 | return null; 149 | } 150 | 151 | public synchronized void addListener(ClassWorldListener listener) { 152 | // TODO ideally, use object identity, not equals 153 | if (!listeners.contains(listener)) { 154 | listeners.add(listener); 155 | } 156 | } 157 | 158 | public synchronized void removeListener(ClassWorldListener listener) { 159 | listeners.remove(listener); 160 | } 161 | } 162 | -------------------------------------------------------------------------------- /src/main/java/org/codehaus/plexus/classworlds/ClassWorldException.java: -------------------------------------------------------------------------------- 1 | package org.codehaus.plexus.classworlds; 2 | 3 | /* 4 | * Copyright 2001-2006 Codehaus Foundation. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | /** 20 | * Base exception for ClassWorld errors. 21 | * 22 | * @author bob mcwhirter 23 | */ 24 | public class ClassWorldException extends Exception { 25 | // ------------------------------------------------------------ 26 | // Instance members 27 | // ------------------------------------------------------------ 28 | 29 | /** 30 | * The world. 31 | */ 32 | private ClassWorld world; 33 | 34 | // ------------------------------------------------------------ 35 | // Constructors 36 | // ------------------------------------------------------------ 37 | 38 | /** 39 | * Construct. 40 | * 41 | * @param world The world. 42 | */ 43 | public ClassWorldException(final ClassWorld world) { 44 | this.world = world; 45 | } 46 | 47 | /** 48 | * Construct. 49 | * 50 | * @param world The world. 51 | * @param msg The detail message. 52 | */ 53 | public ClassWorldException(final ClassWorld world, final String msg) { 54 | super(msg); 55 | this.world = world; 56 | } 57 | 58 | // ------------------------------------------------------------ 59 | // Instance methods 60 | // ------------------------------------------------------------ 61 | 62 | /** 63 | * Retrieve the world. 64 | * 65 | * @return The world. 66 | */ 67 | public ClassWorld getWorld() { 68 | return this.world; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/org/codehaus/plexus/classworlds/ClassWorldListener.java: -------------------------------------------------------------------------------- 1 | package org.codehaus.plexus.classworlds; 2 | 3 | /* 4 | * Copyright 2001-2006 Codehaus Foundation. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | import org.codehaus.plexus.classworlds.realm.ClassRealm; 20 | 21 | public interface ClassWorldListener { 22 | void realmCreated(ClassRealm realm); 23 | 24 | void realmDisposed(ClassRealm realm); 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/org/codehaus/plexus/classworlds/UrlUtils.java: -------------------------------------------------------------------------------- 1 | package org.codehaus.plexus.classworlds; 2 | 3 | /* 4 | * Copyright 2001-2006 Codehaus Foundation. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | import java.net.URL; 20 | import java.net.URLClassLoader; 21 | import java.util.Arrays; 22 | import java.util.HashSet; 23 | import java.util.Set; 24 | 25 | /** 26 | * @author Jason van Zyl 27 | */ 28 | public class UrlUtils { 29 | public static String normalizeUrlPath(String name) { 30 | if (name.startsWith("/")) { 31 | name = name.substring(1); 32 | } 33 | 34 | // Looking for org/codehaus/werkflow/personality/basic/../common/core-idioms.xml 35 | // | i | 36 | // +-------+ remove 37 | // 38 | int i = name.indexOf("/.."); 39 | 40 | // Can't be at the beginning because we have no root to refer to so 41 | // we start at 1. 42 | if (i > 0) { 43 | int j = name.lastIndexOf("/", i - 1); 44 | 45 | if (j >= 0) { 46 | name = name.substring(0, j) + name.substring(i + 3); 47 | } 48 | } 49 | 50 | return name; 51 | } 52 | 53 | public static Set getURLs(URLClassLoader loader) { 54 | return new HashSet<>(Arrays.asList(loader.getURLs())); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/org/codehaus/plexus/classworlds/launcher/ConfigurationException.java: -------------------------------------------------------------------------------- 1 | package org.codehaus.plexus.classworlds.launcher; 2 | 3 | /* 4 | * Copyright 2001-2006 Codehaus Foundation. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | /** 20 | * Indicates an error during Launcher configuration. 21 | * 22 | * @author bob mcwhirter 23 | */ 24 | public class ConfigurationException extends Exception { 25 | /** 26 | * Construct. 27 | * 28 | * @param msg The message. 29 | */ 30 | public ConfigurationException(String msg) { 31 | super(msg); 32 | } 33 | 34 | /** 35 | * Construct. 36 | * 37 | * @param msg The message. 38 | * @param lineNo The number of configuraton line where the problem occured. 39 | * @param line The configuration line where the problem occured. 40 | */ 41 | public ConfigurationException(String msg, int lineNo, String line) { 42 | super(msg + " (" + lineNo + "): " + line); 43 | } 44 | 45 | protected ConfigurationException(Exception cause) { 46 | super(cause); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/org/codehaus/plexus/classworlds/launcher/ConfigurationHandler.java: -------------------------------------------------------------------------------- 1 | package org.codehaus.plexus.classworlds.launcher; 2 | 3 | /* 4 | * Copyright 2001-2006 Codehaus Foundation. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | import java.io.File; 20 | import java.net.URL; 21 | 22 | import org.codehaus.plexus.classworlds.realm.DuplicateRealmException; 23 | import org.codehaus.plexus.classworlds.realm.NoSuchRealmException; 24 | 25 | /** 26 | * Receive notification of the logical content of launcher configuration, independently from parsing. 27 | * 28 | * @author Igor Fedorenko 29 | */ 30 | public interface ConfigurationHandler { 31 | 32 | /** 33 | * Define the main class name 34 | * @param mainClassName the main class name 35 | * @param mainRealmName the main realm from which the main class is loaded 36 | */ 37 | void setAppMain(String mainClassName, String mainRealmName); 38 | 39 | /** 40 | * Define a new realm 41 | * @param realmName the new realm name 42 | * @throws DuplicateRealmException when realm with name already exists 43 | */ 44 | void addRealm(String realmName) throws DuplicateRealmException; 45 | 46 | /** 47 | * Add an import specification from a realm 48 | * @param realmName the realm name 49 | * @param importSpec the import specification 50 | * @throws NoSuchRealmException if realm doesn't exist 51 | */ 52 | void addImportFrom(String realmName, String importSpec) throws NoSuchRealmException; 53 | 54 | /** 55 | * Add a file to the realm 56 | * @param file the file to load content from 57 | */ 58 | void addLoadFile(File file); 59 | 60 | /** 61 | * Add an URL to the realm 62 | * @param url the url to load content from 63 | */ 64 | void addLoadURL(URL url); 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/org/codehaus/plexus/classworlds/launcher/Configurator.java: -------------------------------------------------------------------------------- 1 | package org.codehaus.plexus.classworlds.launcher; 2 | 3 | /* 4 | * Copyright 2001-2006 Codehaus Foundation. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | import java.io.File; 20 | import java.io.IOException; 21 | import java.io.InputStream; 22 | import java.net.MalformedURLException; 23 | import java.net.URL; 24 | import java.util.ArrayList; 25 | import java.util.HashMap; 26 | import java.util.List; 27 | import java.util.Map; 28 | 29 | import org.codehaus.plexus.classworlds.ClassWorld; 30 | import org.codehaus.plexus.classworlds.realm.ClassRealm; 31 | import org.codehaus.plexus.classworlds.realm.DuplicateRealmException; 32 | import org.codehaus.plexus.classworlds.realm.NoSuchRealmException; 33 | 34 | /** 35 | * Launcher configurator. 36 | * 37 | * @author bob mcwhirter 38 | * @author Jason van Zyl 39 | */ 40 | public class Configurator implements ConfigurationHandler { 41 | /** 42 | * The launcher to configure. 43 | */ 44 | private Launcher launcher; 45 | 46 | private ClassWorld world; 47 | 48 | /** 49 | * Processed Realms. 50 | */ 51 | private Map configuredRealms; 52 | 53 | /** 54 | * Current Realm. 55 | */ 56 | private ClassRealm curRealm; 57 | 58 | private ClassLoader foreignClassLoader = null; 59 | 60 | /** 61 | * Construct. 62 | * 63 | * @param launcher The launcher to configure. 64 | */ 65 | public Configurator(Launcher launcher) { 66 | this.launcher = launcher; 67 | 68 | configuredRealms = new HashMap<>(); 69 | 70 | if (launcher != null) { 71 | this.foreignClassLoader = launcher.getSystemClassLoader(); 72 | } 73 | } 74 | 75 | /** 76 | * Construct. 77 | * 78 | * @param world The classWorld to configure. 79 | */ 80 | public Configurator(ClassWorld world) { 81 | setClassWorld(world); 82 | } 83 | 84 | /** 85 | * set world. 86 | * this setter is provided so you can use the same configurator to configure several "worlds" 87 | * 88 | * @param world The classWorld to configure. 89 | */ 90 | public void setClassWorld(ClassWorld world) { 91 | this.world = world; 92 | 93 | configuredRealms = new HashMap<>(); 94 | } 95 | 96 | /** 97 | * Configure from a file. 98 | * 99 | * @param is The config input stream 100 | * @throws IOException If an error occurs reading the config file. 101 | * @throws MalformedURLException If the config file contains invalid URLs. 102 | * @throws ConfigurationException If the config file is corrupt. 103 | * @throws org.codehaus.plexus.classworlds.realm.DuplicateRealmException If the config file defines two realms with the same id. 104 | * @throws org.codehaus.plexus.classworlds.realm.NoSuchRealmException If the config file defines a main entry point in 105 | * a non-existent realm. 106 | */ 107 | public void configure(InputStream is) 108 | throws IOException, ConfigurationException, DuplicateRealmException, NoSuchRealmException { 109 | if (world == null) { 110 | world = new ClassWorld(); 111 | } 112 | 113 | curRealm = null; 114 | 115 | foreignClassLoader = null; 116 | 117 | if (this.launcher != null) { 118 | foreignClassLoader = this.launcher.getSystemClassLoader(); 119 | } 120 | 121 | ConfigurationParser parser = new ConfigurationParser(this, System.getProperties()); 122 | 123 | parser.parse(is); 124 | 125 | // Associate child realms to their parents. 126 | associateRealms(); 127 | 128 | if (this.launcher != null) { 129 | this.launcher.setWorld(world); 130 | } 131 | } 132 | 133 | // TODO return this to protected when the legacy wrappers can be removed. 134 | /** 135 | * Associate parent realms with their children. 136 | */ 137 | public void associateRealms() { 138 | List sortRealmNames = new ArrayList<>(configuredRealms.keySet()); 139 | 140 | // sort by name 141 | sortRealmNames.sort(String::compareTo); 142 | 143 | // So now we have something like the following for defined 144 | // realms: 145 | // 146 | // root 147 | // root.maven 148 | // root.maven.plugin 149 | // 150 | // Now if the name of a realm is a superset of an existing realm 151 | // the we want to make child/parent associations. 152 | 153 | for (String realmName : sortRealmNames) { 154 | int j = realmName.lastIndexOf('.'); 155 | 156 | if (j > 0) { 157 | String parentRealmName = realmName.substring(0, j); 158 | 159 | ClassRealm parentRealm = configuredRealms.get(parentRealmName); 160 | 161 | if (parentRealm != null) { 162 | ClassRealm realm = configuredRealms.get(realmName); 163 | 164 | realm.setParentRealm(parentRealm); 165 | } 166 | } 167 | } 168 | } 169 | 170 | public void addImportFrom(String relamName, String importSpec) throws NoSuchRealmException { 171 | curRealm.importFrom(relamName, importSpec); 172 | } 173 | 174 | public void addLoadFile(File file) { 175 | try { 176 | curRealm.addURL(file.toURI().toURL()); 177 | } catch (MalformedURLException e) { 178 | // can't really happen... or can it? 179 | } 180 | } 181 | 182 | public void addLoadURL(URL url) { 183 | curRealm.addURL(url); 184 | } 185 | 186 | public void addRealm(String realmName) throws DuplicateRealmException { 187 | curRealm = world.newRealm(realmName, foreignClassLoader); 188 | 189 | // Stash the configured realm for subsequent association processing. 190 | configuredRealms.put(realmName, curRealm); 191 | } 192 | 193 | public void setAppMain(String mainClassName, String mainRealmName) { 194 | if (this.launcher != null) { 195 | this.launcher.setAppMain(mainClassName, mainRealmName); 196 | } 197 | } 198 | } 199 | -------------------------------------------------------------------------------- /src/main/java/org/codehaus/plexus/classworlds/realm/DuplicateRealmException.java: -------------------------------------------------------------------------------- 1 | package org.codehaus.plexus.classworlds.realm; 2 | 3 | import org.codehaus.plexus.classworlds.ClassWorld; 4 | import org.codehaus.plexus.classworlds.ClassWorldException; 5 | 6 | /* 7 | * Copyright 2001-2006 Codehaus Foundation. 8 | * 9 | * Licensed under the Apache License, Version 2.0 (the "License"); 10 | * you may not use this file except in compliance with the License. 11 | * You may obtain a copy of the License at 12 | * 13 | * http://www.apache.org/licenses/LICENSE-2.0 14 | * 15 | * Unless required by applicable law or agreed to in writing, software 16 | * distributed under the License is distributed on an "AS IS" BASIS, 17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | * See the License for the specific language governing permissions and 19 | * limitations under the License. 20 | */ 21 | 22 | /** 23 | * Indicates an attempt to add a ClassRealm to a 24 | * ClassWorld with a duplicate id. 25 | * 26 | * @author bob mcwhirter 27 | */ 28 | public class DuplicateRealmException extends ClassWorldException { 29 | // ------------------------------------------------------------ 30 | // Instance members 31 | // ------------------------------------------------------------ 32 | 33 | /** 34 | * The realm id. 35 | */ 36 | private String id; 37 | 38 | // ------------------------------------------------------------ 39 | // Constructors 40 | // ------------------------------------------------------------ 41 | 42 | /** 43 | * Construct. 44 | * 45 | * @param world The world. 46 | * @param id The realm id. 47 | */ 48 | public DuplicateRealmException(ClassWorld world, String id) { 49 | super(world, id); 50 | this.id = id; 51 | } 52 | 53 | // ------------------------------------------------------------ 54 | // Instance methods 55 | // ------------------------------------------------------------ 56 | 57 | /** 58 | * Retrieve the duplicate realm id. 59 | * 60 | * @return The id. 61 | */ 62 | public String getId() { 63 | return this.id; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/org/codehaus/plexus/classworlds/realm/Entry.java: -------------------------------------------------------------------------------- 1 | package org.codehaus.plexus.classworlds.realm; 2 | 3 | /* 4 | * Copyright 2001-2006 Codehaus Foundation. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | /** 20 | * Import description entry. 21 | * 22 | * @author bob mcwhirter 23 | */ 24 | class Entry implements Comparable { 25 | 26 | final ClassLoader classLoader; 27 | 28 | final String pkgName; 29 | 30 | Entry(ClassLoader realm, String pkgName) { 31 | this.classLoader = realm; 32 | 33 | this.pkgName = pkgName; 34 | } 35 | 36 | // ------------------------------------------------------------ 37 | // Instance methods 38 | // ------------------------------------------------------------ 39 | 40 | /** 41 | * Retrieve the class loader. 42 | * 43 | * @return The class loader. 44 | */ 45 | ClassLoader getClassLoader() { 46 | return this.classLoader; 47 | } 48 | 49 | /** 50 | * Retrieve the package name. 51 | * 52 | * @return The package name. 53 | */ 54 | String getPackageName() { 55 | return this.pkgName; 56 | } 57 | 58 | /** 59 | * Determine if the class/resource name matches the package 60 | * described by this entry. 61 | * 62 | * @param name The class or resource name to test, must not be null. 63 | * @return true if this entry matches the 64 | * classname, otherwise false. 65 | */ 66 | boolean matches(String name) { 67 | String pkg = getPackageName(); 68 | 69 | if (pkg.endsWith(".*")) { 70 | String pkgName; 71 | 72 | if (name.indexOf('/') < 0) { 73 | // a binary class name, e.g. java.lang.Object 74 | 75 | int index = name.lastIndexOf('.'); 76 | pkgName = (index < 0) ? "" : name.substring(0, index); 77 | } else { 78 | // a resource name, e.g. java/lang/Object.class 79 | 80 | int index = name.lastIndexOf('/'); 81 | pkgName = (index < 0) ? "" : name.substring(0, index).replace('/', '.'); 82 | } 83 | 84 | return pkgName.length() == pkg.length() - 2 && pkg.regionMatches(0, pkgName, 0, pkgName.length()); 85 | } else if (pkg.length() > 0) { 86 | if (name.indexOf('/') < 0) { 87 | // a binary class name, e.g. java.lang.Object 88 | 89 | if (name.startsWith(pkg)) { 90 | if (name.length() == pkg.length()) { 91 | // exact match of class name 92 | return true; 93 | } else if (name.charAt(pkg.length()) == '.') { 94 | // prefix match of package name 95 | return true; 96 | } else if (name.charAt(pkg.length()) == '$') { 97 | // prefix match of enclosing type 98 | return true; 99 | } 100 | } 101 | } else { 102 | // a resource name, e.g. java/lang/Object.class 103 | 104 | if (name.equals(pkg)) { 105 | // exact match of resource name 106 | return true; 107 | } 108 | 109 | pkg = pkg.replace('.', '/'); 110 | 111 | if (name.startsWith(pkg) && name.length() > pkg.length()) { 112 | if (name.charAt(pkg.length()) == '/') { 113 | // prefix match of package directory 114 | return true; 115 | } else if (name.charAt(pkg.length()) == '$') { 116 | // prefix match of nested class file 117 | return true; 118 | } else if (name.length() == pkg.length() + 6 && name.endsWith(".class")) { 119 | // exact match of class file 120 | return true; 121 | } 122 | } 123 | } 124 | 125 | return false; 126 | } else { 127 | return true; 128 | } 129 | } 130 | 131 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 132 | // java.lang.Comparable 133 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 134 | 135 | /** 136 | * Compare this entry to another for relative ordering. 137 | *

138 | *

139 | * The natural ordering of Entry objects is reverse-alphabetical 140 | * based upon package name. 141 | *

142 | * 143 | * @param that The object to compare. 144 | * @return -1 if this object sorts before that object, 0 145 | * if they are equal, or 1 if this object sorts 146 | * after that object. 147 | */ 148 | public int compareTo(Entry that) { 149 | // We are reverse sorting this list, so that 150 | // we get longer matches first: 151 | // 152 | // com.werken.foo.bar 153 | // com.werken.foo 154 | // com.werken 155 | 156 | return -(getPackageName().compareTo(that.getPackageName())); 157 | } 158 | 159 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 160 | // java.lang.Object 161 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 162 | 163 | /** 164 | * Test this entry for equality to another. 165 | *

166 | *

167 | * Consistent with {@link #compareTo}, this method tests 168 | * for equality purely on the package name. 169 | *

170 | * 171 | * @param thatObj The object to compare 172 | * @return true if the two objects are 173 | * semantically equivalent, otherwise false. 174 | */ 175 | public boolean equals(Object thatObj) { 176 | Entry that = (Entry) thatObj; 177 | 178 | return getPackageName().equals(that.getPackageName()); 179 | } 180 | 181 | /** 182 | *

183 | * Consistent with {@link #equals}, this method creates a hashCode 184 | * based on the packagename. 185 | *

186 | */ 187 | public int hashCode() { 188 | return getPackageName().hashCode(); 189 | } 190 | 191 | public String toString() { 192 | return "Entry[import " + getPackageName() + " from realm " + getClassLoader() + "]"; 193 | } 194 | } 195 | -------------------------------------------------------------------------------- /src/main/java/org/codehaus/plexus/classworlds/realm/FilteredClassRealm.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | package org.codehaus.plexus.classworlds.realm; 20 | 21 | import java.io.IOException; 22 | import java.net.URL; 23 | import java.util.Collections; 24 | import java.util.Enumeration; 25 | import java.util.function.Predicate; 26 | 27 | import org.codehaus.plexus.classworlds.ClassWorld; 28 | 29 | /** 30 | * Similar to {@link ClassRealm} but only exposing some resources of the underlying URL. 31 | * Only supposed to be called from {@link ClassWorld}. 32 | */ 33 | public class FilteredClassRealm extends ClassRealm { 34 | private final Predicate filter; 35 | 36 | /** 37 | * Creates a new class realm. 38 | * 39 | * @param filter a predicate to apply to each resource name to determine if it should be loaded through this class loader 40 | * @param world The class world this realm belongs to, must not be null. 41 | * @param id The identifier for this realm, must not be null. 42 | * @param baseClassLoader The base class loader for this realm, may be null to use the bootstrap class 43 | * loader. 44 | */ 45 | public FilteredClassRealm(Predicate filter, ClassWorld world, String id, ClassLoader baseClassLoader) { 46 | super(world, id, baseClassLoader); 47 | this.filter = filter; 48 | } 49 | 50 | @Override 51 | protected Class findClassInternal(String name) throws ClassNotFoundException { 52 | String resourceName = name.replace('.', '/').concat(".class"); 53 | if (!filter.test(resourceName)) { 54 | throw new ClassNotFoundException(name); 55 | } 56 | return super.findClassInternal(name); 57 | } 58 | 59 | @Override 60 | public URL findResource(String name) { 61 | if (!filter.test(name)) { 62 | return null; 63 | } 64 | return super.findResource(name); 65 | } 66 | 67 | @Override 68 | public Enumeration findResources(String name) throws IOException { 69 | if (!filter.test(name)) { 70 | return Collections.emptyEnumeration(); 71 | } 72 | return super.findResources(name); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/org/codehaus/plexus/classworlds/realm/NoSuchRealmException.java: -------------------------------------------------------------------------------- 1 | package org.codehaus.plexus.classworlds.realm; 2 | 3 | import org.codehaus.plexus.classworlds.ClassWorld; 4 | import org.codehaus.plexus.classworlds.ClassWorldException; 5 | 6 | /* 7 | * Copyright 2001-2006 Codehaus Foundation. 8 | * 9 | * Licensed under the Apache License, Version 2.0 (the "License"); 10 | * you may not use this file except in compliance with the License. 11 | * You may obtain a copy of the License at 12 | * 13 | * http://www.apache.org/licenses/LICENSE-2.0 14 | * 15 | * Unless required by applicable law or agreed to in writing, software 16 | * distributed under the License is distributed on an "AS IS" BASIS, 17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | * See the License for the specific language governing permissions and 19 | * limitations under the License. 20 | */ 21 | 22 | /** 23 | * Indicates an attempt to retrieve a ClassRealm from a 24 | * ClassWorld with an invalid id. 25 | * 26 | * @author bob mcwhirter 27 | */ 28 | public class NoSuchRealmException extends ClassWorldException { 29 | // ------------------------------------------------------------ 30 | // Instance members 31 | // ------------------------------------------------------------ 32 | 33 | /** 34 | * The realm id. 35 | */ 36 | private String id; 37 | 38 | // ------------------------------------------------------------ 39 | // Constructors 40 | // ------------------------------------------------------------ 41 | 42 | /** 43 | * Construct. 44 | * 45 | * @param world The world. 46 | * @param id The realm id. 47 | */ 48 | public NoSuchRealmException(ClassWorld world, String id) { 49 | super(world, id); 50 | this.id = id; 51 | } 52 | 53 | // ------------------------------------------------------------ 54 | // Instance methods 55 | // ------------------------------------------------------------ 56 | 57 | /** 58 | * Retrieve the invalid realm id. 59 | * 60 | * @return The id. 61 | */ 62 | public String getId() { 63 | return this.id; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/org/codehaus/plexus/classworlds/strategy/AbstractStrategy.java: -------------------------------------------------------------------------------- 1 | package org.codehaus.plexus.classworlds.strategy; 2 | 3 | import java.net.URL; 4 | import java.util.Collection; 5 | import java.util.Collections; 6 | import java.util.Enumeration; 7 | import java.util.LinkedHashSet; 8 | 9 | import org.codehaus.plexus.classworlds.UrlUtils; 10 | import org.codehaus.plexus.classworlds.realm.ClassRealm; 11 | 12 | /* 13 | * Copyright 2001-2006 Codehaus Foundation. 14 | * 15 | * Licensed under the Apache License, Version 2.0 (the "License"); 16 | * you may not use this file except in compliance with the License. 17 | * You may obtain a copy of the License at 18 | * 19 | * http://www.apache.org/licenses/LICENSE-2.0 20 | * 21 | * Unless required by applicable law or agreed to in writing, software 22 | * distributed under the License is distributed on an "AS IS" BASIS, 23 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 24 | * See the License for the specific language governing permissions and 25 | * limitations under the License. 26 | */ 27 | 28 | /** 29 | * @author Jason van Zyl 30 | */ 31 | public abstract class AbstractStrategy implements Strategy { 32 | 33 | protected ClassRealm realm; 34 | 35 | public AbstractStrategy(ClassRealm realm) { 36 | this.realm = realm; 37 | } 38 | 39 | protected String getNormalizedResource(String name) { 40 | return UrlUtils.normalizeUrlPath(name); 41 | } 42 | 43 | protected Enumeration combineResources(Enumeration en1, Enumeration en2, Enumeration en3) { 44 | Collection urls = new LinkedHashSet<>(); 45 | 46 | addAll(urls, en1); 47 | addAll(urls, en2); 48 | addAll(urls, en3); 49 | 50 | return Collections.enumeration(urls); 51 | } 52 | 53 | private void addAll(Collection target, Enumeration en) { 54 | if (en != null) { 55 | while (en.hasMoreElements()) { 56 | target.add(en.nextElement()); 57 | } 58 | } 59 | } 60 | 61 | public ClassRealm getRealm() { 62 | return realm; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/org/codehaus/plexus/classworlds/strategy/OsgiBundleStrategy.java: -------------------------------------------------------------------------------- 1 | package org.codehaus.plexus.classworlds.strategy; 2 | 3 | /* 4 | * Copyright 2001-2010 Codehaus Foundation. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | import java.io.IOException; 20 | import java.net.URL; 21 | import java.util.Enumeration; 22 | 23 | import org.codehaus.plexus.classworlds.realm.ClassRealm; 24 | 25 | public class OsgiBundleStrategy extends AbstractStrategy { 26 | 27 | // java.* from parent 28 | // imported packages [Import-Package header with explicit constraints on the exporter] 29 | // requires bundle [Required-Bundle] 30 | // self [Bundle-Classpath header] 31 | // attached fragments 32 | // 33 | // We need to trya and be OSGi r4 compliant in the loading of all the bundles so that we can try to 34 | // load eclipse without requiring equinox. Or any other OSGi container for that matter. 35 | public OsgiBundleStrategy(ClassRealm realm) { 36 | super(realm); 37 | } 38 | 39 | public Class loadClass(String name) throws ClassNotFoundException { 40 | Class clazz = realm.loadClassFromImport(name); 41 | 42 | if (clazz == null) { 43 | clazz = realm.loadClassFromSelf(name); 44 | 45 | if (clazz == null) { 46 | clazz = realm.loadClassFromParent(name); 47 | 48 | if (clazz == null) { 49 | throw new ClassNotFoundException(name); 50 | } 51 | } 52 | } 53 | 54 | return clazz; 55 | } 56 | 57 | public URL getResource(String name) { 58 | URL resource = realm.loadResourceFromImport(name); 59 | 60 | if (resource == null) { 61 | resource = realm.loadResourceFromSelf(name); 62 | 63 | if (resource == null) { 64 | resource = realm.loadResourceFromParent(name); 65 | } 66 | } 67 | 68 | return resource; 69 | } 70 | 71 | public Enumeration getResources(String name) throws IOException { 72 | Enumeration imports = realm.loadResourcesFromImport(name); 73 | Enumeration self = realm.loadResourcesFromSelf(name); 74 | Enumeration parent = realm.loadResourcesFromParent(name); 75 | 76 | return combineResources(imports, self, parent); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/main/java/org/codehaus/plexus/classworlds/strategy/ParentFirstStrategy.java: -------------------------------------------------------------------------------- 1 | package org.codehaus.plexus.classworlds.strategy; 2 | 3 | /* 4 | * Copyright 2001-2006 Codehaus Foundation. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 7 | * in compliance with the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software distributed under the License 12 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 13 | * or implied. See the License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | import java.io.IOException; 18 | import java.net.URL; 19 | import java.util.Enumeration; 20 | 21 | import org.codehaus.plexus.classworlds.realm.ClassRealm; 22 | 23 | /** 24 | * @author Jason van Zyl 25 | */ 26 | public class ParentFirstStrategy extends AbstractStrategy { 27 | 28 | public ParentFirstStrategy(ClassRealm realm) { 29 | super(realm); 30 | } 31 | 32 | public Class loadClass(String name) throws ClassNotFoundException { 33 | Class clazz = realm.loadClassFromImport(name); 34 | 35 | if (clazz == null) { 36 | clazz = realm.loadClassFromParent(name); 37 | 38 | if (clazz == null) { 39 | clazz = realm.loadClassFromSelf(name); 40 | 41 | if (clazz == null) { 42 | throw new ClassNotFoundException(name); 43 | } 44 | } 45 | } 46 | 47 | return clazz; 48 | } 49 | 50 | public URL getResource(String name) { 51 | URL resource = realm.loadResourceFromImport(name); 52 | 53 | if (resource == null) { 54 | resource = realm.loadResourceFromParent(name); 55 | 56 | if (resource == null) { 57 | resource = realm.loadResourceFromSelf(name); 58 | } 59 | } 60 | 61 | return resource; 62 | } 63 | 64 | public Enumeration getResources(String name) throws IOException { 65 | Enumeration imports = realm.loadResourcesFromImport(name); 66 | Enumeration parent = realm.loadResourcesFromParent(name); 67 | Enumeration self = realm.loadResourcesFromSelf(name); 68 | 69 | return combineResources(imports, parent, self); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/org/codehaus/plexus/classworlds/strategy/SelfFirstStrategy.java: -------------------------------------------------------------------------------- 1 | package org.codehaus.plexus.classworlds.strategy; 2 | 3 | /* 4 | * Copyright 2001-2006 Codehaus Foundation. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 7 | * in compliance with the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software distributed under the License 12 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 13 | * or implied. See the License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | import java.io.IOException; 18 | import java.net.URL; 19 | import java.util.Enumeration; 20 | 21 | import org.codehaus.plexus.classworlds.realm.ClassRealm; 22 | 23 | /** 24 | * @author Jason van Zyl 25 | */ 26 | public class SelfFirstStrategy extends AbstractStrategy { 27 | 28 | public SelfFirstStrategy(ClassRealm realm) { 29 | super(realm); 30 | } 31 | 32 | public Class loadClass(String name) throws ClassNotFoundException { 33 | Class clazz = realm.loadClassFromImport(name); 34 | 35 | if (clazz == null) { 36 | clazz = realm.loadClassFromSelf(name); 37 | 38 | if (clazz == null) { 39 | clazz = realm.loadClassFromParent(name); 40 | 41 | if (clazz == null) { 42 | throw new ClassNotFoundException(name); 43 | } 44 | } 45 | } 46 | 47 | return clazz; 48 | } 49 | 50 | public URL getResource(String name) { 51 | URL resource = realm.loadResourceFromImport(name); 52 | 53 | if (resource == null) { 54 | resource = realm.loadResourceFromSelf(name); 55 | 56 | if (resource == null) { 57 | resource = realm.loadResourceFromParent(name); 58 | } 59 | } 60 | 61 | return resource; 62 | } 63 | 64 | public Enumeration getResources(String name) throws IOException { 65 | Enumeration imports = realm.loadResourcesFromImport(name); 66 | Enumeration self = realm.loadResourcesFromSelf(name); 67 | Enumeration parent = realm.loadResourcesFromParent(name); 68 | 69 | return combineResources(imports, self, parent); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/org/codehaus/plexus/classworlds/strategy/Strategy.java: -------------------------------------------------------------------------------- 1 | package org.codehaus.plexus.classworlds.strategy; 2 | 3 | /* 4 | * Copyright 2001-2006 Codehaus Foundation. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | import java.io.IOException; 20 | import java.net.URL; 21 | import java.util.Enumeration; 22 | 23 | import org.codehaus.plexus.classworlds.realm.ClassRealm; 24 | 25 | /** 26 | * A strategy is a class for defining how classes and resources are located 27 | * in classworlds. 28 | */ 29 | public interface Strategy { 30 | 31 | Class loadClass(String name) throws ClassNotFoundException; 32 | 33 | URL getResource(String name); 34 | 35 | Enumeration getResources(String name) throws IOException; 36 | 37 | ClassRealm getRealm(); 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/org/codehaus/plexus/classworlds/strategy/StrategyFactory.java: -------------------------------------------------------------------------------- 1 | package org.codehaus.plexus.classworlds.strategy; 2 | 3 | /* 4 | * Copyright 2001-2006 Codehaus Foundation. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | import org.codehaus.plexus.classworlds.realm.ClassRealm; 20 | 21 | /** 22 | * StrategyFactory loads a strategy, either default or from a given hint. 23 | */ 24 | public class StrategyFactory { 25 | 26 | public static Strategy getStrategy(ClassRealm realm) { 27 | return getStrategy(realm, "default"); 28 | } 29 | 30 | public static Strategy getStrategy(ClassRealm realm, String hint) { 31 | // TODO: Here we shall check hint to load non-default strategies 32 | 33 | return new SelfFirstStrategy(realm); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/site/site.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 21 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /src/site/xdoc/apiusage.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Classworlds API Usage 7 | bob mcwhirter 8 | 9 | 10 | 11 | 12 |
13 | 14 |

15 | The Java API can be used to create new realms and connect 16 | realms together through importation of specific packages. 17 |

18 | 19 |

20 | The core of the Classworlds infrastructure is 21 | the 22 | ClassWorld 23 | class. An application must create a ClassWorld instance. 24 | It is advisable to store the instance as a singleton or some other 25 | handy location. 26 |

27 | 28 | 31 | 32 |

33 | Once a ClassWorld is created, realms within it 34 | can be created. These realms effectively only allow loading 35 | of the core JVM classes initially. 36 |

37 | 38 | 43 | 44 |

45 | In order to make each ClassRealm useful, constituents 46 | in form of URLs must be added to it where each can provide certain classes. 47 | The URL must return either a JAR or a directory on the default file system. 48 |

49 | 50 | 54 | 55 |

56 | ClassRealms can optionally be filtered to further restrict which classes/resources 57 | are exposed. The filter is provided as additional argument to world.newRealm( "filteredcontainer", myPredicate ); 58 |

59 | 60 |

61 | Now, links between the various realms need to be created to allow 62 | classes loaded from one to be available to classes loaded in another. 63 |

64 | 65 | 69 | 70 |

71 | The container implementation can then be loaded from its realm 72 | and used. 73 |

74 | 75 | 81 | 82 |

83 | Ideally, the container itself would be responsible for creating 84 | a ClassRealm for each component that's loaded, and 85 | importing the component contract interfaces into the component's 86 | ClassRealm and using loadClass(..) 87 | to gain entry into the sandboxed component realm. 88 |

89 | 90 |
91 | 92 | 93 |
-------------------------------------------------------------------------------- /src/site/xdoc/index.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Plexus Classworlds 7 | bob mcwhirter 8 | 9 | 10 | 11 | 12 |
13 | 14 |

15 | Plexus Classworlds is a framework for container developers 16 | who require complex manipulation of Java's ClassLoaders. Java's 17 | native ClassLoader mechanisms and classes can cause 18 | much headache and confusion for certain types of application 19 | developers. Projects which involve dynamic loading of components 20 | or otherwise represent a 'container' can benefit from the classloading 21 | control provided by Classworlds. 22 |

23 | 24 |

25 | Plexus Classworlds provides a richer set of semantics for 26 | class loading than Java's normal mechanisms, while still being 27 | able to provide a ClassLoader interface to integrate 28 | seamlessly with the Java environment. 29 |

30 | 31 |

32 | The Classworlds model does away with the hierarchy 33 | normally associated with ClassLoaders. Instead, 34 | ClassWorld provides a 35 | pool of ClassRealms 36 | which can import arbitrary packages from other ClassRealms. 37 | Effectively, Classworlds turns the old-style 38 | hierarchy into a directed graph. 39 |

40 | 41 |

42 | In a application container environment, the container may 43 | have a realm capable of loading on the container/component 44 | contract interfaces and classes. Another realm is created 45 | for each component which imports the contract classes from 46 | the container realm. 47 |

48 | 49 |

50 | This model allows for fine-grained control of which 51 | classloader loads any particular class. This form of 52 | partial isolation can reduce the myriad strange errors 53 | that are produced by loading classes from multiple 54 | loaders. 55 |

56 | 57 |

58 | In addition, Plexus Classworlds provides a 59 | launcher 60 | to assist in the creation of classloaders and ClassRealms 61 | from a configuration file and the launching of the application's main 62 | method from the correct class loaded through the correct classloader. 63 |

64 | 65 |

66 | And for seamless transition from older Classworlds up to 1.1, 67 | Plexus Classworlds provides 68 | a compatibility layer. 69 |

70 |
71 | 72 | 73 |
74 | 75 | -------------------------------------------------------------------------------- /src/site/xdoc/launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | App Launching 7 | bob mcwhirter 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 |

17 | In order to reduce the number of classloading projects, 18 | Plexus Classworlds replaces forehead 19 | for application launching. 20 |

21 | 22 |

23 | The main problems to solve in application launching include 24 | locating all of application's JARs, configuring the initial 25 | classloaders, and invoking the main entry method. 26 |

27 | 28 |

29 | The launcher facilities 30 | of Classworlds simplify 31 | the process of locating application jars. A common idiom is 32 | to have a script which starts the JVM with only the 33 | plexus-classworlds.jar in the classpath and a system 34 | property to specify the location of a launcher configuration. 35 | Additionally, typically a property specifying the application installation 36 | location is passed on the command-line. 37 |

38 | 39 | 47 | 48 |
49 | 50 |
51 | 52 |
53 | 54 | 55 | 56 |

57 | The entry-point class and realm must be specified 58 | using the main is directive before 59 | specifying realm definitions. 60 |

61 | 62 | 65 | 66 |
67 | 68 | 69 | 70 |

71 | System properties can be set before and after the entry point, but before realms: 72 |

73 | 74 | [[using ]] [[default ]] 76 | ]]> 77 | 78 |
79 | 80 | 81 | 82 |

83 | At least one Classworlds realm must be defined 84 | within the configuration file. The syntax for starting a 85 | realm definition is [realm.name]. All lines 86 | following the realm header are considered directives for 87 | that realm. The realm definition continues either until 88 | another realm is defined or until the end of the file is 89 | reached. 90 |

91 | 92 | 103 | 104 |

105 | Within a realm definition, three directives are available: 106 | load, optionally and import. 107 |

108 | 109 |

110 | The load and optionally 111 | directives specify a class source to be used for loading 112 | classes in the realm: the only difference is that in case of absent source, 113 | load fails but optionally does not. 114 | Any loaded source that contain a star (*) in the file name is 115 | replaced by the list of files that match the filename prefix and suffix. 116 | System properties may be referred to using ${propname} notation. 117 | The load and optionally directives are equivalent to the 118 | addURL(..) method of ClassRealm. 119 |

120 | 121 | 127 | 128 |

129 | The import directive specifies that certain 130 | packages should be imported and loaded by way of another 131 | realm. The import directive is equivalent 132 | to the importFrom(..) method of 133 | ClassRealm. 134 |

135 | 136 | 144 | 145 |
146 | 147 | 148 | 149 |

150 | Classworlds can be used to invoke any existing 151 | application's main() method. Using the standard 152 | entry point does not allow for gaining access to the 153 | ClassWorld of the application, but not all 154 | applications will need it at run-time. 155 |

156 | 157 |

158 | For those applications that do require the ClassWorld 159 | instance, an alternative entry-point method signature can be 160 | provided. Simply add a ClassWorld parameter to 161 | the standard main parameter list. 162 |

163 | 164 | 173 | 174 |
175 | 176 |
177 | 178 | 179 | 180 |
-------------------------------------------------------------------------------- /src/test/java/org/codehaus/plexus/classworlds/AbstractClassWorldsTestCase.java: -------------------------------------------------------------------------------- 1 | package org.codehaus.plexus.classworlds; 2 | 3 | /* 4 | * Copyright 2001-2006 Codehaus Foundation. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | import java.net.URL; 20 | 21 | /** 22 | * @author Jason van Zyl 23 | */ 24 | public abstract class AbstractClassWorldsTestCase { 25 | protected URL getJarUrl(String jarName) { 26 | return TestUtil.getTestResourceUrl(jarName); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/test/java/org/codehaus/plexus/classworlds/ClassView.java: -------------------------------------------------------------------------------- 1 | package org.codehaus.plexus.classworlds; 2 | 3 | /* 4 | * Copyright 2001-2006 Codehaus Foundation. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | public class ClassView { 20 | /** 21 | * * Formats Class information for debug output purposes. 22 | * * 23 | * * @param clz the Class to print information for 24 | * * 25 | * * @return a String describing the Class in detail 26 | */ 27 | public static String toString(Class clz) { 28 | if (clz.isPrimitive()) { 29 | return clz.toString(); 30 | } else if (clz.isArray()) { 31 | return "Array of " + toString(clz.getComponentType()); 32 | } else if (clz.isInterface()) { 33 | return toInterfaceString(clz, ""); 34 | } else { 35 | return toClassString(clz, ""); 36 | } 37 | } 38 | 39 | /** 40 | * * Formats Class information for debug output purposes. 41 | * * 42 | * * @param clz the Class to print information for 43 | * * @param sIndent the indentation to precede each line of output 44 | * * 45 | * * @return a String describing the Class in detail 46 | */ 47 | private static String toClassString(Class clz, String sIndent) { 48 | StringBuilder sb = new StringBuilder(); 49 | sb.append(sIndent) 50 | .append("Class ") 51 | .append(clz.getName()) 52 | .append(" (") 53 | .append(toString(clz.getClassLoader())) 54 | .append(')'); 55 | 56 | sIndent += " "; 57 | 58 | Class[] aclz = clz.getInterfaces(); 59 | for (Class aClass : aclz) { 60 | sb.append('\n').append(toInterfaceString(aClass, sIndent)); 61 | } 62 | 63 | clz = clz.getSuperclass(); 64 | if (clz != null) { 65 | sb.append('\n').append(toClassString(clz, sIndent)); 66 | } 67 | 68 | return sb.toString(); 69 | } 70 | 71 | /** 72 | * * Formats interface information for debug output purposes. 73 | * * 74 | * * @param clz the interface Class to print information for 75 | * * @param sIndent the indentation to precede each line of output 76 | * * 77 | * * @return a String describing the interface Class in detail 78 | */ 79 | private static String toInterfaceString(Class clz, String sIndent) { 80 | StringBuilder sb = new StringBuilder(); 81 | sb.append(sIndent) 82 | .append("Interface ") 83 | .append(clz.getName()) 84 | .append(" (") 85 | .append(toString(clz.getClassLoader())) 86 | .append(')'); 87 | 88 | Class[] aclz = clz.getInterfaces(); 89 | for (Class aClass : aclz) { 90 | clz = aClass; 91 | 92 | sb.append('\n').append(toInterfaceString(clz, sIndent + " ")); 93 | } 94 | 95 | return sb.toString(); 96 | } 97 | 98 | /** 99 | * * Format a description for the specified ClassLoader object. 100 | * * 101 | * * @param loader the ClassLoader instance (or null) 102 | * * 103 | * * @return a String description of the ClassLoader 104 | */ 105 | private static String toString(ClassLoader loader) { 106 | if (loader == null) { 107 | return "System ClassLoader"; 108 | } 109 | 110 | return "ClassLoader class=" + loader.getClass().getName() + ", hashCode=" + loader.hashCode(); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/test/java/org/codehaus/plexus/classworlds/ClassWorldTest.java: -------------------------------------------------------------------------------- 1 | package org.codehaus.plexus.classworlds; 2 | 3 | /* 4 | * Copyright 2001-2006 Codehaus Foundation. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | import java.net.URL; 19 | import java.net.URLClassLoader; 20 | import java.util.Enumeration; 21 | 22 | import org.codehaus.plexus.classworlds.realm.ClassRealm; 23 | import org.codehaus.plexus.classworlds.realm.DuplicateRealmException; 24 | import org.codehaus.plexus.classworlds.realm.NoSuchRealmException; 25 | import org.junit.jupiter.api.AfterEach; 26 | import org.junit.jupiter.api.BeforeEach; 27 | import org.junit.jupiter.api.Test; 28 | 29 | import static org.junit.jupiter.api.Assertions.assertEquals; 30 | import static org.junit.jupiter.api.Assertions.assertNotNull; 31 | import static org.junit.jupiter.api.Assertions.assertSame; 32 | import static org.junit.jupiter.api.Assertions.assertTrue; 33 | import static org.junit.jupiter.api.Assertions.fail; 34 | 35 | class ClassWorldTest extends AbstractClassWorldsTestCase { 36 | private ClassWorld world; 37 | 38 | @BeforeEach 39 | public void setUp() { 40 | this.world = new ClassWorld(); 41 | } 42 | 43 | @AfterEach 44 | public void tearDown() { 45 | this.world = null; 46 | } 47 | 48 | @Test 49 | void testEmpty() { 50 | assertTrue(this.world.getRealms().isEmpty()); 51 | } 52 | 53 | @Test 54 | void testNewRealm() throws Exception { 55 | ClassRealm realm = this.world.newRealm("foo"); 56 | 57 | assertNotNull(realm); 58 | } 59 | 60 | @Test 61 | void testGetRealm() throws Exception { 62 | ClassRealm realm = this.world.newRealm("foo"); 63 | 64 | assertSame(realm, this.world.getRealm("foo")); 65 | } 66 | 67 | @Test 68 | void testNewRealm_Duplicate() { 69 | try { 70 | this.world.newRealm("foo"); 71 | this.world.newRealm("foo"); 72 | 73 | fail("throw DuplicateRealmException"); 74 | } catch (DuplicateRealmException e) { 75 | // expected and correct 76 | 77 | assertSame(this.world, e.getWorld()); 78 | 79 | assertEquals("foo", e.getId()); 80 | } 81 | } 82 | 83 | @Test 84 | void testGetRealm_NoSuch() { 85 | try { 86 | this.world.getRealm("foo"); 87 | fail("throw NoSuchRealmException"); 88 | } catch (NoSuchRealmException e) { 89 | // expected and correct 90 | 91 | assertSame(this.world, e.getWorld()); 92 | 93 | assertEquals("foo", e.getId()); 94 | } 95 | } 96 | 97 | @Test 98 | void testGetRealms() throws Exception { 99 | assertTrue(this.world.getRealms().isEmpty()); 100 | 101 | ClassRealm foo = this.world.newRealm("foo"); 102 | 103 | assertEquals(1, this.world.getRealms().size()); 104 | 105 | assertTrue(this.world.getRealms().contains(foo)); 106 | 107 | ClassRealm bar = this.world.newRealm("bar"); 108 | 109 | assertEquals(2, this.world.getRealms().size()); 110 | 111 | assertTrue(this.world.getRealms().contains(bar)); 112 | } 113 | 114 | @Test 115 | void testPLX334() throws Exception { 116 | ClassLoader loader = new URLClassLoader(new URL[] {getJarUrl("component1-1.0.jar")}); 117 | world.newRealm("netbeans", loader); 118 | ClassRealm plexus = world.newRealm("plexus"); 119 | plexus.importFrom("netbeans", "META-INF/plexus"); 120 | plexus.importFrom("netbeans", "org.codehaus.plexus"); 121 | Enumeration e = plexus.getResources("META-INF/plexus/components.xml"); 122 | assertNotNull(e); 123 | int resourceCount = 0; 124 | for (Enumeration resources = e; resources.hasMoreElements(); ) { 125 | URL obj = resources.nextElement(); 126 | assertTrue(obj.getPath().contains("/component1-1.0.jar!/META-INF/plexus/components.xml")); 127 | resourceCount++; 128 | } 129 | // assertEquals( 2, resourceCount ); 130 | // for some reason surefire-plugin 2.3 returned 2 items there: 131 | // for example: 132 | // jar:file:/home/mkleint/.m2/repository/org/codehaus/plexus/plexus-archiver/1.0-alpha-7/plexus-archiver-1.0-alpha-7.jar!/META-INF/plexus/components.xml 133 | // jar:file:/home/mkleint/src/plexus-trunk/plexus-classworlds/src/test-jars/component1-1.0.jar!/META-INF/plexus/components.xml 134 | // However only 1 is correct, which is actually returned by the 2.4 surefire-plugin 135 | 136 | assertEquals(1, resourceCount); 137 | Class c = plexus.loadClass("org.codehaus.plexus.Component1"); 138 | assertNotNull(c); 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /src/test/java/org/codehaus/plexus/classworlds/TestUtil.java: -------------------------------------------------------------------------------- 1 | package org.codehaus.plexus.classworlds; 2 | 3 | /* 4 | * Copyright 2001-2006 Codehaus Foundation. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | import java.io.File; 20 | import java.net.MalformedURLException; 21 | import java.net.URL; 22 | 23 | /** 24 | * @author Ben Walding 25 | */ 26 | public class TestUtil { 27 | 28 | public static URL getTestResourceUrl(String resourceName) { 29 | File baseDir = new File(getBasedir()); 30 | 31 | File testDir = new File(baseDir, "src/test/test-data"); 32 | 33 | File resourceFile = new File(testDir, resourceName); 34 | 35 | try { 36 | return resourceFile.toURI().toURL(); 37 | } catch (MalformedURLException e) { 38 | throw new RuntimeException(e); 39 | } 40 | } 41 | 42 | public static String getBasedir() { 43 | String basedir = System.getProperty("basedir"); 44 | 45 | /* do our best if we are not running from surefire */ 46 | if (basedir == null || basedir.length() <= 0) { 47 | basedir = (new File("")).getAbsolutePath(); 48 | } 49 | 50 | return basedir; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/test/java/org/codehaus/plexus/classworlds/UrlUtilsTest.java: -------------------------------------------------------------------------------- 1 | package org.codehaus.plexus.classworlds; 2 | 3 | /* 4 | * Copyright 2001-2006 Codehaus Foundation. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | import org.junit.jupiter.api.Test; 20 | 21 | import static org.junit.jupiter.api.Assertions.assertEquals; 22 | 23 | class UrlUtilsTest { 24 | 25 | @Test 26 | public void testNormalizeUrlPath() { 27 | assertEquals("org/codehaus/Test.class", UrlUtils.normalizeUrlPath("org/codehaus/Test.class")); 28 | assertEquals("org/Test.class", UrlUtils.normalizeUrlPath("org/codehaus/../Test.class")); 29 | assertEquals("../../some.jar/org/Test.class", UrlUtils.normalizeUrlPath("../../some.jar/org/Test.class")); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/test/java/org/codehaus/plexus/classworlds/launcher/ConfigurationParserTest.java: -------------------------------------------------------------------------------- 1 | package org.codehaus.plexus.classworlds.launcher; 2 | 3 | import org.codehaus.plexus.classworlds.AbstractClassWorldsTestCase; 4 | import org.junit.jupiter.api.Test; 5 | 6 | import static org.junit.jupiter.api.Assertions.assertEquals; 7 | import static org.junit.jupiter.api.Assertions.assertTrue; 8 | import static org.junit.jupiter.api.Assertions.fail; 9 | 10 | class ConfigurationParserTest extends AbstractClassWorldsTestCase { 11 | 12 | ConfigurationParser configurator = new ConfigurationParser(null, System.getProperties()); 13 | 14 | @Test 15 | void testFilter_Unterminated() { 16 | try { 17 | this.configurator.filter("${cheese"); 18 | fail("throw ConfigurationException"); 19 | } catch (ConfigurationException e) { 20 | // expected and correct 21 | assertTrue(e.getMessage().startsWith("Unterminated")); 22 | } 23 | } 24 | 25 | @Test 26 | void testFilter_Solitary() throws Exception { 27 | System.setProperty("classworlds.test.prop", "test prop value"); 28 | 29 | String result = this.configurator.filter("${classworlds.test.prop}"); 30 | 31 | assertEquals("test prop value", result); 32 | } 33 | 34 | @Test 35 | void testFilter_AtStart() throws Exception { 36 | System.setProperty("classworlds.test.prop", "test prop value"); 37 | 38 | String result = this.configurator.filter("${classworlds.test.prop}cheese"); 39 | 40 | assertEquals("test prop valuecheese", result); 41 | } 42 | 43 | @Test 44 | void testFilter_AtEnd() throws Exception { 45 | System.setProperty("classworlds.test.prop", "test prop value"); 46 | 47 | String result = this.configurator.filter("cheese${classworlds.test.prop}"); 48 | 49 | assertEquals("cheesetest prop value", result); 50 | } 51 | 52 | @Test 53 | void testFilter_Multiple() throws Exception { 54 | System.setProperty("classworlds.test.prop.one", "test prop value one"); 55 | 56 | System.setProperty("classworlds.test.prop.two", "test prop value two"); 57 | 58 | String result = 59 | this.configurator.filter("I like ${classworlds.test.prop.one} and ${classworlds.test.prop.two} a lot"); 60 | 61 | assertEquals("I like test prop value one and test prop value two a lot", result); 62 | } 63 | 64 | @Test 65 | void testFilter_NonExistent() { 66 | try { 67 | this.configurator.filter("${gollygeewillikers}"); 68 | fail("throw ConfigurationException"); 69 | } catch (ConfigurationException e) { 70 | // expected and correct 71 | assertTrue(e.getMessage().startsWith("No such property")); 72 | } 73 | } 74 | 75 | @Test 76 | void testFilter_InMiddle() throws Exception { 77 | System.setProperty("classworlds.test.prop", "test prop value"); 78 | 79 | String result = this.configurator.filter("cheese${classworlds.test.prop}toast"); 80 | 81 | assertEquals("cheesetest prop valuetoast", result); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/test/java/org/codehaus/plexus/classworlds/launcher/ConfiguratorTest.java: -------------------------------------------------------------------------------- 1 | package org.codehaus.plexus.classworlds.launcher; 2 | 3 | /* 4 | * Copyright 2001-2006 Codehaus Foundation. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | import java.io.File; 19 | import java.io.FileInputStream; 20 | import java.io.FileNotFoundException; 21 | import java.net.URL; 22 | import java.util.Collection; 23 | 24 | import org.codehaus.plexus.classworlds.AbstractClassWorldsTestCase; 25 | import org.codehaus.plexus.classworlds.ClassWorld; 26 | import org.codehaus.plexus.classworlds.TestUtil; 27 | import org.codehaus.plexus.classworlds.realm.ClassRealm; 28 | import org.codehaus.plexus.classworlds.realm.DuplicateRealmException; 29 | import org.junit.jupiter.api.AfterEach; 30 | import org.junit.jupiter.api.BeforeEach; 31 | import org.junit.jupiter.api.Test; 32 | 33 | import static org.junit.jupiter.api.Assertions.assertEquals; 34 | import static org.junit.jupiter.api.Assertions.assertNotNull; 35 | import static org.junit.jupiter.api.Assertions.assertNull; 36 | import static org.junit.jupiter.api.Assertions.assertSame; 37 | import static org.junit.jupiter.api.Assertions.assertTrue; 38 | import static org.junit.jupiter.api.Assertions.fail; 39 | 40 | class ConfiguratorTest extends AbstractClassWorldsTestCase { 41 | private Launcher launcher; 42 | private Configurator configurator; 43 | 44 | @BeforeEach 45 | public void setUp() { 46 | this.launcher = new Launcher(); 47 | this.configurator = new Configurator(this.launcher); 48 | } 49 | 50 | @AfterEach 51 | public void tearDown() { 52 | this.launcher = null; 53 | this.configurator = null; 54 | System.getProperties().remove("set.using.existent"); 55 | System.getProperties().remove("set.using.default"); 56 | System.getProperties().remove("set.using.nonexistent"); 57 | System.getProperties().remove("set.using.nonexistent.default"); 58 | System.getProperties().remove("set.using.missing"); 59 | System.getProperties().remove("set.using.filtered.default"); 60 | } 61 | 62 | @Test 63 | void testConfigure_Nonexistent() throws Exception { 64 | try { 65 | this.configurator.configure(getConfigPath("notfound.conf")); 66 | fail("throw FileNotFoundException"); 67 | } catch (FileNotFoundException e) { 68 | // expected and correct 69 | } 70 | } 71 | 72 | @Test 73 | void testConfigure_DuplicateMain() throws Exception { 74 | try { 75 | this.configurator.configure(getConfigPath("dupe-main.conf")); 76 | fail("throw ConfigurationException"); 77 | } catch (ConfigurationException e) { 78 | // expected and correct 79 | assertTrue(e.getMessage().startsWith("Duplicate main")); 80 | } 81 | } 82 | 83 | @Test 84 | void testConfigure_DuplicateRealm() throws Exception { 85 | try { 86 | this.configurator.configure(getConfigPath("dupe-realm.conf")); 87 | fail("throw DuplicateRealmException"); 88 | } catch (DuplicateRealmException e) { 89 | // expected and correct 90 | assertEquals("dupe.realm", e.getId()); 91 | } 92 | } 93 | 94 | @Test 95 | void testConfigure_EarlyImport() throws Exception { 96 | try { 97 | this.configurator.configure(getConfigPath("early-import.conf")); 98 | fail("throw ConfigurationException"); 99 | } catch (ConfigurationException e) { 100 | // expected and correct 101 | assertTrue(e.getMessage().startsWith("Unhandled import")); 102 | } 103 | } 104 | 105 | @Test 106 | void testConfigure_RealmSyntax() throws Exception { 107 | try { 108 | this.configurator.configure(getConfigPath("realm-syntax.conf")); 109 | fail("throw ConfigurationException"); 110 | } catch (ConfigurationException e) { 111 | // expected and correct 112 | assertTrue(e.getMessage().startsWith("Invalid realm")); 113 | } 114 | } 115 | 116 | @Test 117 | void testConfigure_Valid() throws Exception { 118 | this.configurator.configure(getConfigPath("valid.conf")); 119 | 120 | assertEquals("org.apache.maven.app.App", this.launcher.getMainClassName()); 121 | 122 | assertEquals("maven", this.launcher.getMainRealmName()); 123 | 124 | ClassWorld world = this.launcher.getWorld(); 125 | 126 | Collection realms = world.getRealms(); 127 | 128 | assertEquals(4, realms.size()); 129 | 130 | assertNotNull(world.getRealm("ant")); 131 | assertNotNull(world.getRealm("maven")); 132 | assertNotNull(world.getRealm("xml")); 133 | 134 | ClassRealm antRealm = world.getRealm("ant"); 135 | ClassRealm mavenRealm = world.getRealm("maven"); 136 | ClassRealm xmlRealm = world.getRealm("xml"); 137 | ClassRealm globRealm = world.getRealm("glob"); 138 | 139 | assertSame(null, antRealm.getImportClassLoader("org.apache.tools.Ant")); 140 | 141 | // Ant has dependency to xerces:xercesImpl (test) 142 | assertSame(null, antRealm.getImportClassLoader("org.xml.sax.SAXException")); 143 | 144 | assertSame(xmlRealm, antRealm.getImportClassLoader("jakarta.xml.bind.JAXBException")); 145 | 146 | assertSame(null, mavenRealm.getImportClassLoader("org.apache.maven.app.App")); 147 | 148 | assertSame(xmlRealm, mavenRealm.getImportClassLoader("jakarta.xml.bind.JAXBException")); 149 | 150 | URL[] urls = globRealm.getURLs(); 151 | 152 | String basedir = TestUtil.getBasedir(); 153 | assertArrayContains( 154 | urls, new File(basedir, "src/test/test-data/nested.jar").toURI().toURL()); 155 | assertArrayContains( 156 | urls, new File(basedir, "src/test/test-data/a.jar").toURI().toURL()); 157 | assertArrayContains( 158 | urls, new File(basedir, "src/test/test-data/b.jar").toURI().toURL()); 159 | assertArrayContains( 160 | urls, new File(basedir, "src/test/test-data/c.jar").toURI().toURL()); 161 | } 162 | 163 | @Test 164 | void testConfigure_Optionally_NonExistent() throws Exception { 165 | this.configurator.configure(getConfigPath("optionally-nonexistent.conf")); 166 | 167 | assertEquals("org.apache.maven.app.App", this.launcher.getMainClassName()); 168 | 169 | assertEquals("opt", this.launcher.getMainRealmName()); 170 | 171 | ClassWorld world = this.launcher.getWorld(); 172 | 173 | Collection realms = world.getRealms(); 174 | 175 | assertEquals(1, realms.size()); 176 | 177 | assertNotNull(world.getRealm("opt")); 178 | 179 | ClassRealm optRealm = world.getRealm("opt"); 180 | 181 | URL[] urls = optRealm.getURLs(); 182 | 183 | assertEquals(0, urls.length, "no urls"); 184 | } 185 | 186 | @Test 187 | void testConfigure_Optionally_Existent() throws Exception { 188 | this.configurator.configure(getConfigPath("optionally-existent.conf")); 189 | 190 | assertEquals("org.apache.maven.app.App", this.launcher.getMainClassName()); 191 | 192 | assertEquals("opt", this.launcher.getMainRealmName()); 193 | 194 | ClassWorld world = this.launcher.getWorld(); 195 | 196 | Collection realms = world.getRealms(); 197 | 198 | assertEquals(1, realms.size()); 199 | 200 | assertNotNull(world.getRealm("opt")); 201 | 202 | ClassRealm optRealm = world.getRealm("opt"); 203 | 204 | URL[] urls = optRealm.getURLs(); 205 | 206 | assertEquals(1, urls.length, "one url"); 207 | 208 | assertSame(null, optRealm.getImportClassLoader("jakarta.xml.bind.JAXBException")); 209 | } 210 | 211 | @Test 212 | void testConfigure_Unhandled() throws Exception { 213 | try { 214 | this.configurator.configure(getConfigPath("unhandled.conf")); 215 | fail("throw ConfigurationException"); 216 | } catch (ConfigurationException e) { 217 | // expected and correct 218 | assertTrue(e.getMessage().startsWith("Unhandled configuration")); 219 | } 220 | } 221 | 222 | @Test 223 | void testSet_Using_Existent() throws Exception { 224 | assertNull(System.getProperty("set.using.existent")); 225 | 226 | this.configurator.configure(getConfigPath("set-using-existent.conf")); 227 | 228 | assertEquals("testSet_Using_Existent", System.getProperty("set.using.existent")); 229 | } 230 | 231 | @Test 232 | void testSet_Using_NonExistent() throws Exception { 233 | assertNull(System.getProperty("set.using.nonexistent")); 234 | 235 | this.configurator.configure(getConfigPath("set-using-nonexistent.conf")); 236 | 237 | assertNull(System.getProperty("set.using.nonexistent")); 238 | } 239 | 240 | @Test 241 | void testSet_Using_NonExistent_Default() throws Exception { 242 | assertNull(System.getProperty("set.using.nonexistent.default")); 243 | 244 | this.configurator.configure(getConfigPath("set-using-nonexistent.conf")); 245 | 246 | assertEquals("testSet_Using_NonExistent_Default", System.getProperty("set.using.nonexistent.default")); 247 | } 248 | 249 | @Test 250 | void testSet_Using_NonExistent_Override() throws Exception { 251 | assertNull(System.getProperty("set.using.default")); 252 | System.setProperty("set.using.default", "testSet_Using_NonExistent_Override"); 253 | 254 | this.configurator.configure(getConfigPath("set-using-nonexistent.conf")); 255 | 256 | assertEquals("testSet_Using_NonExistent_Override", System.getProperty("set.using.default")); 257 | } 258 | 259 | @Test 260 | void testSet_Using_Existent_Override() throws Exception { 261 | assertNull(System.getProperty("set.using.existent")); 262 | System.setProperty("set.using.existent", "testSet_Using_Existent_Override"); 263 | 264 | this.configurator.configure(getConfigPath("set-using-existent.conf")); 265 | 266 | assertEquals("testSet_Using_Existent_Override", System.getProperty("set.using.existent")); 267 | } 268 | 269 | @Test 270 | void testSet_Using_Existent_Default() throws Exception { 271 | assertNull(System.getProperty("set.using.default")); 272 | 273 | this.configurator.configure(getConfigPath("set-using-existent.conf")); 274 | 275 | assertEquals("testSet_Using_Existent_Default", System.getProperty("set.using.default")); 276 | } 277 | 278 | @Test 279 | void testSet_Using_Missing_Default() throws Exception { 280 | assertNull(System.getProperty("set.using.missing")); 281 | 282 | this.configurator.configure(getConfigPath("set-using-missing.conf")); 283 | 284 | assertEquals("testSet_Using_Missing_Default", System.getProperty("set.using.missing")); 285 | } 286 | 287 | @Test 288 | void testSet_Using_Missing_Override() throws Exception { 289 | assertNull(System.getProperty("set.using.missing")); 290 | System.setProperty("set.using.missing", "testSet_Using_Missing_Override"); 291 | 292 | this.configurator.configure(getConfigPath("set-using-missing.conf")); 293 | 294 | assertEquals("testSet_Using_Missing_Override", System.getProperty("set.using.missing")); 295 | } 296 | 297 | @Test 298 | void testSet_Using_Filtered_Default() throws Exception { 299 | assertNull(System.getProperty("set.using.filtered.default")); 300 | 301 | this.configurator.configure(getConfigPath("set-using-missing.conf")); 302 | 303 | assertEquals(System.getProperty("user.home") + "/m2", System.getProperty("set.using.filtered.default")); 304 | } 305 | 306 | @Test 307 | void testFromFromFrom() throws Exception { 308 | this.configurator.configure(getConfigPath("valid-from-from-from.conf")); 309 | 310 | assertEquals("com.from.from.from.Main", this.launcher.getMainClassName()); 311 | 312 | assertEquals("from", this.launcher.getMainRealmName()); 313 | 314 | ClassWorld world = this.launcher.getWorld(); 315 | 316 | { 317 | ClassRealm realm = world.getRealm("ant"); 318 | Collection importRealms = realm.getImportRealms(); 319 | assertEquals(1, importRealms.size()); 320 | assertEquals("from", importRealms.stream().findFirst().get().getId()); 321 | } 322 | { 323 | ClassRealm realm = world.getRealm("maven"); 324 | Collection importRealms = realm.getImportRealms(); 325 | assertEquals(1, importRealms.size()); 326 | assertEquals("from", importRealms.stream().findFirst().get().getId()); 327 | } 328 | { 329 | ClassRealm realm = world.getRealm("glob"); 330 | Collection importRealms = realm.getImportRealms(); 331 | assertEquals(0, importRealms.size()); 332 | } 333 | { 334 | ClassRealm realm = world.getRealm("from"); 335 | Collection importRealms = realm.getImportRealms(); 336 | assertEquals(0, importRealms.size()); 337 | } 338 | } 339 | 340 | private FileInputStream getConfigPath(String name) throws Exception { 341 | return new FileInputStream(new File(new File(TestUtil.getBasedir(), "src/test/test-data"), name)); 342 | } 343 | 344 | private void assertArrayContains(URL[] array, URL url) { 345 | for (URL value : array) { 346 | if (url.equals(value)) { 347 | return; 348 | } 349 | } 350 | fail("URL (" + url + ") not found in array of URLs"); 351 | } 352 | } 353 | -------------------------------------------------------------------------------- /src/test/java/org/codehaus/plexus/classworlds/launcher/LauncherTest.java: -------------------------------------------------------------------------------- 1 | package org.codehaus.plexus.classworlds.launcher; 2 | 3 | /* 4 | * Copyright 2001-2006 Codehaus Foundation. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | import java.io.File; 19 | import java.io.FileInputStream; 20 | 21 | import org.codehaus.plexus.classworlds.AbstractClassWorldsTestCase; 22 | import org.codehaus.plexus.classworlds.TestUtil; 23 | import org.junit.jupiter.api.AfterEach; 24 | import org.junit.jupiter.api.BeforeEach; 25 | import org.junit.jupiter.api.Test; 26 | 27 | import static org.junit.jupiter.api.Assertions.assertEquals; 28 | import static org.junit.jupiter.api.Assertions.assertNotNull; 29 | import static org.junit.jupiter.api.Assertions.fail; 30 | 31 | class LauncherTest extends AbstractClassWorldsTestCase { 32 | private Launcher launcher; 33 | 34 | @BeforeEach 35 | public void setUp() { 36 | System.setProperty("java.protocol.handler.pkgs", "org.codehaus.classworlds.protocol"); 37 | 38 | this.launcher = new Launcher(); 39 | 40 | this.launcher.setSystemClassLoader(Thread.currentThread().getContextClassLoader()); 41 | } 42 | 43 | @AfterEach 44 | public void tearDown() { 45 | this.launcher = null; 46 | } 47 | 48 | @Test 49 | void testConfigure_Valid() throws Exception { 50 | launcher.configure(getConfigPath("valid-launch.conf")); 51 | 52 | Class mainClass = launcher.getMainClass(); 53 | 54 | assertNotNull(mainClass); 55 | 56 | assertEquals("a.A", mainClass.getName()); 57 | 58 | assertEquals("app", launcher.getMainRealm().getId()); 59 | } 60 | 61 | @Test 62 | void testLaunch_ValidStandard() throws Exception { 63 | launcher.configure(getConfigPath("valid-launch.conf")); 64 | 65 | launcher.launch(new String[] {}); 66 | } 67 | 68 | @Test 69 | void testLaunch_ValidStandardExitCode() throws Exception { 70 | launcher.configure(getConfigPath("valid-launch-exitCode.conf")); 71 | 72 | launcher.launch(new String[] {}); 73 | 74 | assertEquals(15, launcher.getExitCode(), "check exit code"); 75 | } 76 | 77 | @Test 78 | void testLaunch_ValidEnhanced() throws Exception { 79 | launcher.configure(getConfigPath("valid-enh-launch.conf")); 80 | 81 | launcher.launch(new String[] {}); 82 | } 83 | 84 | @Test 85 | void testLaunch_ValidEnhancedExitCode() throws Exception { 86 | launcher.configure(getConfigPath("valid-enh-launch-exitCode.conf")); 87 | 88 | launcher.launch(new String[] {}); 89 | 90 | assertEquals(45, launcher.getExitCode(), "check exit code"); 91 | } 92 | 93 | @Test 94 | void testLaunch_NoSuchMethod() throws Exception { 95 | launcher.configure(getConfigPath("launch-nomethod.conf")); 96 | 97 | try { 98 | launcher.launch(new String[] {}); 99 | fail("should have thrown NoSuchMethodException"); 100 | } catch (NoSuchMethodException e) { 101 | // expected and correct 102 | } 103 | } 104 | 105 | @Test 106 | void testLaunch_ClassNotFound() throws Exception { 107 | launcher.configure(getConfigPath("launch-noclass.conf")); 108 | 109 | try { 110 | launcher.launch(new String[] {}); 111 | fail("throw ClassNotFoundException"); 112 | } catch (ClassNotFoundException e) { 113 | // expected and correct 114 | } 115 | } 116 | 117 | private FileInputStream getConfigPath(String name) throws Exception { 118 | String basedir = TestUtil.getBasedir(); 119 | 120 | return new FileInputStream(new File(new File(basedir, "src/test/test-data"), name)); 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /src/test/java/org/codehaus/plexus/classworlds/realm/DefaultClassRealmTest.java: -------------------------------------------------------------------------------- 1 | package org.codehaus.plexus.classworlds.realm; 2 | 3 | /* 4 | * Copyright 2001-2006 Codehaus Foundation. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | import java.net.URL; 20 | import java.net.URLClassLoader; 21 | import java.util.Collections; 22 | import java.util.concurrent.CountDownLatch; 23 | 24 | import org.codehaus.classworlds.ClassRealmAdapter; 25 | import org.codehaus.plexus.classworlds.AbstractClassWorldsTestCase; 26 | import org.codehaus.plexus.classworlds.ClassWorld; 27 | import org.junit.jupiter.api.Test; 28 | 29 | import static org.junit.jupiter.api.Assertions.assertEquals; 30 | import static org.junit.jupiter.api.Assertions.assertFalse; 31 | import static org.junit.jupiter.api.Assertions.assertNotNull; 32 | import static org.junit.jupiter.api.Assertions.assertNull; 33 | import static org.junit.jupiter.api.Assertions.assertSame; 34 | import static org.junit.jupiter.api.Assertions.assertTrue; 35 | import static org.junit.jupiter.api.Assertions.fail; 36 | 37 | class DefaultClassRealmTest extends AbstractClassWorldsTestCase { 38 | // ---------------------------------------------------------------------- 39 | // Class testing 40 | // ---------------------------------------------------------------------- 41 | 42 | @Test 43 | void testLoadClassFromRealm() throws Exception { 44 | ClassRealm mainRealm = new ClassRealm(new ClassWorld(), "main", null); 45 | 46 | mainRealm.addURL(getJarUrl("component0-1.0.jar")); 47 | 48 | loadClass(mainRealm, "org.codehaus.plexus.Component0"); 49 | } 50 | 51 | @Test 52 | void testLoadClassFromChildRealmWhereClassIsLocatedInParentRealm() throws Exception { 53 | ClassRealm mainRealm = new ClassRealm(new ClassWorld(), "main", null); 54 | 55 | mainRealm.addURL(getJarUrl("component0-1.0.jar")); 56 | 57 | ClassRealm childRealm = mainRealm.createChildRealm("child"); 58 | 59 | loadClass(childRealm, "org.codehaus.plexus.Component0"); 60 | } 61 | 62 | @Test 63 | void testLoadClassFromChildRealmWhereClassIsLocatedInGrantParentRealm() throws Exception { 64 | ClassRealm mainRealm = new ClassRealm(new ClassWorld(), "main", null); 65 | 66 | mainRealm.addURL(getJarUrl("component0-1.0.jar")); 67 | 68 | ClassRealm childRealm = mainRealm.createChildRealm("child"); 69 | 70 | ClassRealm grandchildRealm = childRealm.createChildRealm("grandchild"); 71 | 72 | loadClass(grandchildRealm, "org.codehaus.plexus.Component0"); 73 | } 74 | 75 | @Test 76 | void testLoadClassFromChildRealmWhereClassIsLocatedInBothChildRealmAndParentRealm() throws Exception { 77 | ClassRealm mainRealm = new ClassRealm(new ClassWorld(), "parent", null); 78 | 79 | mainRealm.addURL(getJarUrl("component5-1.0.jar")); 80 | 81 | ClassRealm childRealm = mainRealm.createChildRealm("child"); 82 | 83 | childRealm.addURL(getJarUrl("component5-2.0.jar")); 84 | 85 | Class cls = loadClass(childRealm, "test.Component5"); 86 | 87 | assertSame(childRealm, cls.getClassLoader()); 88 | assertEquals(1, cls.getMethods().length); 89 | assertEquals("printNew", cls.getMethods()[0].getName()); 90 | } 91 | 92 | @Test 93 | void testLoadNonExistentClass() { 94 | ClassRealm mainRealm = new ClassRealm(new ClassWorld(), "main", null); 95 | 96 | mainRealm.addURL(getJarUrl("component0-1.0.jar")); 97 | 98 | try { 99 | mainRealm.loadClass("org.foo.bar.NonExistentClass"); 100 | 101 | fail("A ClassNotFoundException should have been thrown!"); 102 | } catch (ClassNotFoundException e) { 103 | // expected 104 | } 105 | } 106 | 107 | @Test 108 | void testImport() throws Exception { 109 | ClassWorld world = new ClassWorld(); 110 | 111 | ClassRealm r0 = world.newRealm("r0"); 112 | 113 | ClassRealm r1 = world.newRealm("r1"); 114 | 115 | r0.addURL(getJarUrl("component0-1.0.jar")); 116 | 117 | r1.importFrom("r0", "org.codehaus.plexus"); 118 | 119 | loadClass(r1, "org.codehaus.plexus.Component0"); 120 | } 121 | 122 | @Test 123 | void testParentImport() throws Exception { 124 | ClassWorld world = new ClassWorld(); 125 | 126 | ClassRealm parent = world.newRealm("parent"); 127 | 128 | ClassRealm child = world.newRealm("child"); 129 | 130 | parent.addURL(getJarUrl("component0-1.0.jar")); 131 | 132 | child.setParentRealm(parent); 133 | 134 | Class type = loadClass(child, "org.codehaus.plexus.Component0"); 135 | 136 | child.importFromParent("non-existing"); 137 | 138 | assertSame(null, loadClassOrNull(child, "org.codehaus.plexus.Component0")); 139 | 140 | child.importFromParent("org.codehaus.plexus"); 141 | 142 | assertSame(type, loadClass(child, "org.codehaus.plexus.Component0")); 143 | } 144 | 145 | @Test 146 | void testLoadClassFromBaseClassLoaderBeforeSelf() throws Exception { 147 | ClassWorld world = new ClassWorld(); 148 | 149 | ClassRealm base = world.newRealm("base"); 150 | 151 | base.addURL(getJarUrl("a.jar")); 152 | 153 | ClassRealm child = world.newRealm("child", base); 154 | 155 | child.addURL(getJarUrl("a.jar")); 156 | 157 | Class baseClass = loadClass(base, "a.A"); 158 | Class childClass = loadClass(child, "a.A"); 159 | 160 | assertSame(base, baseClass.getClassLoader()); 161 | assertSame(base, childClass.getClassLoader()); 162 | assertSame(baseClass, childClass); 163 | } 164 | 165 | @Test 166 | void testLoadClassFromRealmWithCircularClassReferences() throws Exception { 167 | ClassRealm mainRealm = new ClassRealm(new ClassWorld(), "main", null); 168 | 169 | mainRealm.addURL(getJarUrl("circular-0.1.jar")); 170 | 171 | /* 172 | * This was reported to fail with a ClassCircularityError in IBM JDK 1.5.0-SR2, 1.5.0-SR7 and 1.6.0-SR2. It 173 | * works in IBM JDK 1.5.0-SR10 and 1.6.0-SR6. 174 | */ 175 | loadClass(mainRealm, "A$C"); 176 | } 177 | 178 | // ---------------------------------------------------------------------- 179 | // Resource testing 180 | // ---------------------------------------------------------------------- 181 | 182 | @Test 183 | void testResource() throws Exception { 184 | ClassRealm mainRealm = new ClassRealm(new ClassWorld(), "main", null); 185 | 186 | mainRealm.addURL(getJarUrl("component0-1.0.jar")); 187 | 188 | getResource(mainRealm, "META-INF/plexus/components.xml"); 189 | } 190 | 191 | @Test 192 | void testMalformedResource() throws Exception { 193 | URL jarUrl = getJarUrl("component0-1.0.jar"); 194 | 195 | ClassRealm mainRealm = new ClassRealm(new ClassWorld(), "main", null); 196 | 197 | mainRealm.addURL(jarUrl); 198 | 199 | ClassLoader officialClassLoader = new URLClassLoader(new URL[] {jarUrl}); 200 | 201 | String resource = "META-INF/plexus/components.xml"; 202 | 203 | assertNotNull(mainRealm.getResource(resource)); 204 | assertNotNull(officialClassLoader.getResource(resource)); 205 | 206 | /* 207 | * NOTE: Resource names with a leading slash are invalid when passed to a class loader and must not be found! 208 | * One can use a leading slash in Class.getResource() but not in ClassLoader.getResource(). 209 | */ 210 | 211 | assertSame(null, mainRealm.getResource("/" + resource)); 212 | assertSame(null, officialClassLoader.getResource("/" + resource)); 213 | 214 | /* 215 | * For backward-compat, legacy class realms have to support leading slashes. 216 | */ 217 | 218 | org.codehaus.classworlds.ClassRealm legacyRealm = ClassRealmAdapter.getInstance(mainRealm); 219 | assertNotNull(legacyRealm.getResource("/" + resource)); 220 | assertNotNull(legacyRealm.getResourceAsStream("/" + resource)); 221 | assertTrue(legacyRealm.findResources("/" + resource).hasMoreElements()); 222 | } 223 | 224 | @Test 225 | void testFindResourceOnlyScansSelf() throws Exception { 226 | ClassRealm mainRealm = new ClassRealm(new ClassWorld(), "main", null); 227 | 228 | mainRealm.addURL(getJarUrl("a.jar")); 229 | 230 | ClassRealm childRealm = mainRealm.createChildRealm("child"); 231 | 232 | childRealm.addURL(getJarUrl("b.jar")); 233 | 234 | assertNotNull(childRealm.getResource("a.properties")); 235 | assertNotNull(childRealm.getResource("b.properties")); 236 | 237 | assertNull(childRealm.findResource("a.properties")); 238 | 239 | assertNotNull(childRealm.findResource("b.properties")); 240 | } 241 | 242 | @Test 243 | void testFindResourcesOnlyScansSelf() throws Exception { 244 | ClassRealm mainRealm = new ClassRealm(new ClassWorld(), "main", null); 245 | 246 | mainRealm.addURL(getJarUrl("a.jar")); 247 | 248 | ClassRealm childRealm = mainRealm.createChildRealm("child"); 249 | 250 | childRealm.addURL(getJarUrl("b.jar")); 251 | 252 | assertTrue(childRealm.getResources("a.properties").hasMoreElements()); 253 | assertTrue(childRealm.getResources("b.properties").hasMoreElements()); 254 | 255 | assertFalse(childRealm.findResources("a.properties").hasMoreElements()); 256 | 257 | assertTrue(childRealm.findResources("b.properties").hasMoreElements()); 258 | } 259 | 260 | /** Should never deadlock. Ever */ 261 | @Test 262 | void testParallelDeadlockClassRealm() throws InterruptedException { 263 | for (int i = 0; i < 100; i++) { 264 | doOneDeadlockAttempt(); 265 | } 266 | } 267 | 268 | private void doOneDeadlockAttempt() throws InterruptedException { 269 | // Deadlock sample graciously ripped from http://docs.oracle.com/javase/7/docs/technotes/guides/lang/cl-mt.html 270 | final ClassRealm cl1 = new ClassRealm(new ClassWorld(), "cl1", null); 271 | final ClassRealm cl2 = new ClassRealm(new ClassWorld(), "cl2", cl1); 272 | cl1.setParentRealm(cl2); 273 | cl1.addURL(getJarUrl("deadlock.jar")); 274 | cl2.addURL(getJarUrl("deadlock.jar")); 275 | final CountDownLatch latch = new CountDownLatch(1); 276 | 277 | Runnable r1 = () -> { 278 | try { 279 | latch.await(); 280 | cl1.loadClass("deadlock.A"); 281 | } catch (ClassNotFoundException | InterruptedException e) { 282 | throw new RuntimeException(e); 283 | } 284 | }; 285 | 286 | Runnable r2 = () -> { 287 | try { 288 | latch.await(); 289 | cl1.loadClass("deadlock.C"); 290 | } catch (ClassNotFoundException | InterruptedException e) { 291 | throw new RuntimeException(e); 292 | } 293 | }; 294 | 295 | Thread thread = new Thread(r1); 296 | thread.start(); 297 | Thread thread1 = new Thread(r2); 298 | thread1.start(); 299 | latch.countDown(); 300 | thread.join(); 301 | thread1.join(); 302 | } 303 | 304 | // ---------------------------------------------------------------------- 305 | // 306 | // ---------------------------------------------------------------------- 307 | 308 | private Class loadClassOrNull(ClassRealm realm, String name) { 309 | try { 310 | return loadClass(realm, name); 311 | } catch (ClassNotFoundException e) { 312 | return null; 313 | } 314 | } 315 | 316 | private Class loadClass(ClassRealm realm, String name) throws ClassNotFoundException { 317 | Class cls = realm.loadClass(name); 318 | 319 | /* 320 | * NOTE: Load the class both directly from the realm and indirectly from an (ordinary) child class loader which 321 | * uses the specified class realm for parent delegation. The child class loader itself has no additional class 322 | * path entries but relies entirely on the provided class realm. Hence, the created child class loader should in 323 | * theory be able to load exactly the same classes/resources as the underlying class realm. In practice, it will 324 | * test that class realms properly integrate into the standard Java class loader hierarchy. 325 | */ 326 | ClassLoader childLoader = new URLClassLoader(new URL[0], realm); 327 | assertEquals(cls, childLoader.loadClass(name)); 328 | 329 | return cls; 330 | } 331 | 332 | private void getResource(ClassRealm realm, String name) throws Exception { 333 | ClassLoader childLoader = new URLClassLoader(new URL[0], realm); 334 | assertNotNull(realm.getResource(name)); 335 | assertEquals(realm.getResource(name), childLoader.getResource(name)); 336 | assertEquals(Collections.list(realm.getResources(name)), Collections.list(childLoader.getResources(name))); 337 | } 338 | } 339 | -------------------------------------------------------------------------------- /src/test/java/org/codehaus/plexus/classworlds/realm/EntryTest.java: -------------------------------------------------------------------------------- 1 | package org.codehaus.plexus.classworlds.realm; 2 | 3 | /* 4 | * Copyright 2001-2006 Codehaus Foundation. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | import org.codehaus.plexus.classworlds.AbstractClassWorldsTestCase; 19 | import org.codehaus.plexus.classworlds.ClassWorld; 20 | import org.junit.jupiter.api.Test; 21 | 22 | import static org.junit.jupiter.api.Assertions.assertEquals; 23 | import static org.junit.jupiter.api.Assertions.assertFalse; 24 | import static org.junit.jupiter.api.Assertions.assertTrue; 25 | 26 | /** 27 | * @author Ben Walding 28 | */ 29 | class EntryTest extends AbstractClassWorldsTestCase { 30 | 31 | @Test 32 | void testCompareTo() throws Exception { 33 | ClassWorld cw = new ClassWorld(); 34 | ClassRealm r = cw.newRealm("test1"); 35 | 36 | Entry entry1 = new Entry(r, "org.test"); 37 | Entry entry2 = new Entry(r, "org.test.impl"); 38 | 39 | assertTrue(entry1.compareTo(entry2) > 0, "org.test > org.test.impl"); 40 | } 41 | 42 | /** 43 | * Tests the equality is realm independant 44 | */ 45 | @Test 46 | void testEquals() throws DuplicateRealmException { 47 | ClassWorld cw = new ClassWorld(); 48 | ClassRealm r1 = cw.newRealm("test1"); 49 | ClassRealm r2 = cw.newRealm("test2"); 50 | 51 | Entry entry1 = new Entry(r1, "org.test"); 52 | Entry entry2 = new Entry(r2, "org.test"); 53 | 54 | assertEquals(entry1, entry2, "entry1 == entry2"); 55 | assertEquals(entry1.hashCode(), entry2.hashCode(), "entry1.hashCode() == entry2.hashCode()"); 56 | } 57 | 58 | @Test 59 | void testMatchesClassByPackageImport() throws Exception { 60 | ClassWorld cw = new ClassWorld(); 61 | ClassRealm r = cw.newRealm("test1"); 62 | 63 | Entry entry = new Entry(r, "org.test"); 64 | 65 | assertTrue(entry.matches("org.test.MyClass")); 66 | assertTrue(entry.matches("org.test.MyClass$NestedClass")); 67 | assertTrue(entry.matches("org.test.MyClassUtils")); 68 | assertTrue(entry.matches("org.test.impl.MyClass")); 69 | assertFalse(entry.matches("org.tests.AnotherClass")); 70 | } 71 | 72 | @Test 73 | void testMatchesClassByClassImport() throws Exception { 74 | ClassWorld cw = new ClassWorld(); 75 | ClassRealm r = cw.newRealm("test1"); 76 | 77 | Entry entry = new Entry(r, "org.test.MyClass"); 78 | 79 | assertTrue(entry.matches("org.test.MyClass")); 80 | assertTrue(entry.matches("org.test.MyClass$NestedClass")); 81 | assertFalse(entry.matches("org.test.MyClassUtils")); 82 | assertFalse(entry.matches("org.test.AnotherClass")); 83 | } 84 | 85 | @Test 86 | void testMatchesResourceByPackageImport() throws Exception { 87 | ClassWorld cw = new ClassWorld(); 88 | ClassRealm r = cw.newRealm("test1"); 89 | 90 | Entry entry = new Entry(r, "org.test"); 91 | 92 | assertTrue(entry.matches("org/test/MyClass.class")); 93 | assertTrue(entry.matches("org/test/MyClass$NestedClass.class")); 94 | assertTrue(entry.matches("org/test/MyClasses.properties")); 95 | assertTrue(entry.matches("org/test/impl/MyClass.class")); 96 | assertFalse(entry.matches("org/tests/AnotherClass.class")); 97 | } 98 | 99 | @Test 100 | void testMatchesResourceByClassImport() throws Exception { 101 | ClassWorld cw = new ClassWorld(); 102 | ClassRealm r = cw.newRealm("test1"); 103 | 104 | Entry entry = new Entry(r, "org.test.MyClass"); 105 | 106 | assertTrue(entry.matches("org/test/MyClass.class")); 107 | assertTrue(entry.matches("org/test/MyClass$NestedClass.class")); 108 | assertFalse(entry.matches("org/test/MyClass.properties")); 109 | assertFalse(entry.matches("org/test/AnotherClass")); 110 | } 111 | 112 | @Test 113 | void testMatchesAllImport() throws Exception { 114 | ClassWorld cw = new ClassWorld(); 115 | ClassRealm r = cw.newRealm("test1"); 116 | 117 | Entry entry = new Entry(r, ""); 118 | 119 | assertTrue(entry.matches("org.test.MyClass")); 120 | assertTrue(entry.matches("org.test.MyClass$NestedClass")); 121 | assertTrue(entry.matches("org/test/MyClass.class")); 122 | assertTrue(entry.matches("org/test/MyClass.properties")); 123 | } 124 | 125 | @Test 126 | void testMatchesResourceByResourceImport() throws Exception { 127 | ClassWorld cw = new ClassWorld(); 128 | ClassRealm r = cw.newRealm("test1"); 129 | 130 | Entry entry1 = new Entry(r, "some.properties"); 131 | 132 | assertTrue(entry1.matches("some.properties")); 133 | assertFalse(entry1.matches("other.properties")); 134 | 135 | Entry entry2 = new Entry(r, "org/test/some.properties"); 136 | 137 | assertTrue(entry2.matches("org/test/some.properties")); 138 | assertFalse(entry2.matches("org/test/other.properties")); 139 | } 140 | 141 | @Test 142 | void testMatchesClassByExactPackageImport() throws Exception { 143 | ClassWorld cw = new ClassWorld(); 144 | ClassRealm r = cw.newRealm("test1"); 145 | 146 | Entry entry = new Entry(r, "org.test.*"); 147 | 148 | assertTrue(entry.matches("org.test.MyClass")); 149 | assertTrue(entry.matches("org.test.MyClass$NestedClass")); 150 | assertTrue(entry.matches("org.test.MyClassUtils")); 151 | assertFalse(entry.matches("org.test.impl.MyClass")); 152 | assertFalse(entry.matches("org.tests.AnotherClass")); 153 | } 154 | 155 | @Test 156 | void testMatchesResourceByExactPackageImport() throws Exception { 157 | ClassWorld cw = new ClassWorld(); 158 | ClassRealm r = cw.newRealm("test1"); 159 | 160 | Entry entry = new Entry(r, "org.test.*"); 161 | 162 | assertTrue(entry.matches("org/test/MyClass.class")); 163 | assertTrue(entry.matches("org/test/MyClass$NestedClass.class")); 164 | assertTrue(entry.matches("org/test/MyClasses.properties")); 165 | assertFalse(entry.matches("org/test/impl/MyClass.class")); 166 | assertFalse(entry.matches("org/tests/AnotherClass.class")); 167 | } 168 | } 169 | -------------------------------------------------------------------------------- /src/test/java/org/codehaus/plexus/classworlds/realm/FilteredClassRealmTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | package org.codehaus.plexus.classworlds.realm; 20 | 21 | import java.io.IOException; 22 | import java.util.HashSet; 23 | import java.util.Set; 24 | import java.util.function.Predicate; 25 | 26 | import org.codehaus.plexus.classworlds.AbstractClassWorldsTestCase; 27 | import org.codehaus.plexus.classworlds.ClassWorld; 28 | import org.junit.jupiter.api.BeforeEach; 29 | import org.junit.jupiter.api.Test; 30 | 31 | import static org.junit.jupiter.api.Assertions.assertFalse; 32 | import static org.junit.jupiter.api.Assertions.assertNotNull; 33 | import static org.junit.jupiter.api.Assertions.assertNull; 34 | import static org.junit.jupiter.api.Assertions.assertThrows; 35 | import static org.junit.jupiter.api.Assertions.assertTrue; 36 | 37 | class FilteredClassRealmTest extends AbstractClassWorldsTestCase { 38 | private ClassWorld world; 39 | private ClassRealm realmA; 40 | 41 | @BeforeEach 42 | public void setUp() throws DuplicateRealmException { 43 | this.world = new ClassWorld(); 44 | // only allow loading resources whose names start with "a." 45 | Set allowedResourcePrefixes = new HashSet<>(); 46 | allowedResourcePrefixes.add("a."); 47 | allowedResourcePrefixes.add("a/Aa"); 48 | realmA = this.world.newRealm("realmA", getClass().getClassLoader(), s -> allowedResourcePrefixes.stream() 49 | .anyMatch(s::startsWith)); 50 | } 51 | 52 | @Test 53 | void testLoadResources() throws Exception { 54 | realmA.addURL(getJarUrl("a.jar")); 55 | assertNull(realmA.getResource("common.properties")); 56 | assertFalse(realmA.getResources("common.properties").hasMoreElements()); 57 | 58 | assertNotNull(realmA.getResource("a.properties")); 59 | assertTrue(realmA.getResources("a.properties").hasMoreElements()); 60 | } 61 | 62 | @Test 63 | void testLoadClass() throws ClassNotFoundException { 64 | assertThrows(ClassNotFoundException.class, () -> realmA.loadClass("a.Aa")); 65 | realmA.addURL(getJarUrl("a.jar")); 66 | 67 | assertNotNull(realmA.loadClass("a.Aa")); 68 | assertThrows(ClassNotFoundException.class, () -> realmA.loadClass("a.A")); 69 | 70 | assertNotNull(realmA.loadClass("a.Aa")); 71 | assertThrows(ClassNotFoundException.class, () -> realmA.loadClass("a.A")); 72 | } 73 | 74 | @Test 75 | void testLoadClassWithModule() throws IOException { 76 | try (ExtendedFilteredClassRealm realmA = new ExtendedFilteredClassRealm(world, s -> s.startsWith("a/Aa"))) { 77 | realmA.addURL(getJarUrl("a.jar")); 78 | assertNotNull(realmA.simulateLoadClassFromModule("a.Aa")); 79 | assertNull(realmA.simulateLoadClassFromModule("a.A")); 80 | } 81 | } 82 | 83 | /** 84 | * Simulates new {@code java.lang.ClassLoader#findClass(String,String)} introduced with Java 9. 85 | * It is reversed in terms of inheritance but enables to simulate the same behavior in these tests. 86 | * @see ClassLoader#findClass(String,String) 87 | * @see ClassRealmImplTest.ExtendedClassRealm 88 | */ 89 | static class ExtendedFilteredClassRealm extends FilteredClassRealm { 90 | 91 | public ExtendedFilteredClassRealm(final ClassWorld world, Predicate filter) { 92 | super(filter, world, "java9", Thread.currentThread().getContextClassLoader()); 93 | } 94 | 95 | public Class simulateLoadClassFromModule(final String name) { 96 | synchronized (getClassLoadingLock(name)) { 97 | Class c = findLoadedClass(name); 98 | if (c == null) { 99 | c = findClass(null, name); 100 | } 101 | return c; 102 | } 103 | } 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /src/test/java/org/codehaus/plexus/classworlds/strategy/StrategyTest.java: -------------------------------------------------------------------------------- 1 | package org.codehaus.plexus.classworlds.strategy; 2 | 3 | /* 4 | * Copyright 2001-2006 Codehaus Foundation. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | import java.io.InputStream; 19 | import java.net.URL; 20 | import java.util.Enumeration; 21 | 22 | import org.codehaus.plexus.classworlds.AbstractClassWorldsTestCase; 23 | import org.codehaus.plexus.classworlds.ClassWorld; 24 | import org.codehaus.plexus.classworlds.realm.ClassRealm; 25 | import org.junit.jupiter.api.BeforeEach; 26 | import org.junit.jupiter.api.Test; 27 | 28 | import static org.junit.jupiter.api.Assertions.assertEquals; 29 | import static org.junit.jupiter.api.Assertions.assertNotNull; 30 | import static org.junit.jupiter.api.Assertions.assertTrue; 31 | import static org.junit.jupiter.api.Assertions.fail; 32 | import static org.junit.jupiter.api.Assumptions.assumeTrue; 33 | 34 | // jars within jars 35 | // hierarchy vs graph 36 | 37 | class StrategyTest extends AbstractClassWorldsTestCase { 38 | private ClassRealm realm; 39 | 40 | private Strategy strategy; 41 | 42 | @BeforeEach 43 | public void setUp() throws Exception { 44 | this.realm = new ClassWorld().newRealm("realm"); 45 | this.strategy = this.realm.getStrategy(); 46 | realm.addURL(getJarUrl("component0-1.0.jar")); 47 | } 48 | 49 | @Test 50 | void testLoadingOfApplicationClass() throws Exception { 51 | assertNotNull(strategy.loadClass("org.codehaus.plexus.Component0")); 52 | } 53 | 54 | @Test 55 | void testLoadingOfApplicationClassThenDoingItAgain() throws Exception { 56 | Class c = strategy.loadClass("org.codehaus.plexus.Component0"); 57 | 58 | assertNotNull(c); 59 | 60 | c = strategy.loadClass("org.codehaus.plexus.Component0"); 61 | 62 | assertNotNull(c); 63 | } 64 | 65 | @Test 66 | void testLoadingOfSystemClass() throws Exception { 67 | assertNotNull(strategy.getRealm().loadClass("java.lang.Object")); 68 | } 69 | 70 | @Test 71 | void testLoadingOfNonExistentClass() { 72 | try { 73 | strategy.loadClass("org.codehaus.plexus.NonExistentComponent"); 74 | 75 | fail("Should have thrown a ClassNotFoundException!"); 76 | } catch (ClassNotFoundException e) { 77 | // do nothing 78 | } 79 | } 80 | 81 | @Test 82 | void testGetApplicationResource() throws Exception { 83 | URL resource = strategy.getResource("META-INF/plexus/components.xml"); 84 | 85 | assertNotNull(resource); 86 | 87 | String content = getContent(resource.openStream()); 88 | 89 | assertTrue(content.startsWith("")); 90 | } 91 | 92 | @Test 93 | void testGetSystemResource() { 94 | assumeTrue( 95 | getJavaVersion() < 9.0, 96 | "Due to strong encapsulation you cannot get the java/lang/Object.class as resource since Java 9"); 97 | 98 | URL resource = strategy.getRealm().getResource("java/lang/Object.class"); 99 | 100 | assertNotNull(resource); 101 | } 102 | 103 | @Test 104 | void testFindResources() throws Exception { 105 | realm.addURL(getJarUrl("component1-1.0.jar")); 106 | 107 | Enumeration e = strategy.getResources("META-INF/plexus/components.xml"); 108 | assertNotNull(e); 109 | 110 | int resourceCount = 0; 111 | while (e.hasMoreElements()) { 112 | e.nextElement(); 113 | resourceCount++; 114 | } 115 | assertEquals(2, resourceCount); 116 | } 117 | 118 | protected String getContent(InputStream in) throws Exception { 119 | byte[] buffer = new byte[1024]; 120 | 121 | int read; 122 | 123 | StringBuilder content = new StringBuilder(); 124 | 125 | while ((read = in.read(buffer, 0, 1024)) >= 0) { 126 | content.append(new String(buffer, 0, read)); 127 | } 128 | 129 | return content.toString(); 130 | } 131 | 132 | private double getJavaVersion() { 133 | return Double.parseDouble(System.getProperty("java.specification.version")); 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /src/test/test-data/a.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codehaus-plexus/plexus-classworlds/f2e1d80c5547f807bcd6529e767db811a838d89b/src/test/test-data/a.jar -------------------------------------------------------------------------------- /src/test/test-data/a.properties: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # 3 | # Copyright 2001-2006 The Codehaus Foundation. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | a properties 19 | -------------------------------------------------------------------------------- /src/test/test-data/b.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codehaus-plexus/plexus-classworlds/f2e1d80c5547f807bcd6529e767db811a838d89b/src/test/test-data/b.jar -------------------------------------------------------------------------------- /src/test/test-data/b_old.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codehaus-plexus/plexus-classworlds/f2e1d80c5547f807bcd6529e767db811a838d89b/src/test/test-data/b_old.jar -------------------------------------------------------------------------------- /src/test/test-data/c.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codehaus-plexus/plexus-classworlds/f2e1d80c5547f807bcd6529e767db811a838d89b/src/test/test-data/c.jar -------------------------------------------------------------------------------- /src/test/test-data/circular-0.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codehaus-plexus/plexus-classworlds/f2e1d80c5547f807bcd6529e767db811a838d89b/src/test/test-data/circular-0.1.jar -------------------------------------------------------------------------------- /src/test/test-data/component0-1.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codehaus-plexus/plexus-classworlds/f2e1d80c5547f807bcd6529e767db811a838d89b/src/test/test-data/component0-1.0.jar -------------------------------------------------------------------------------- /src/test/test-data/component1-1.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codehaus-plexus/plexus-classworlds/f2e1d80c5547f807bcd6529e767db811a838d89b/src/test/test-data/component1-1.0.jar -------------------------------------------------------------------------------- /src/test/test-data/component2-1.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codehaus-plexus/plexus-classworlds/f2e1d80c5547f807bcd6529e767db811a838d89b/src/test/test-data/component2-1.0.jar -------------------------------------------------------------------------------- /src/test/test-data/component3-1.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codehaus-plexus/plexus-classworlds/f2e1d80c5547f807bcd6529e767db811a838d89b/src/test/test-data/component3-1.0.jar -------------------------------------------------------------------------------- /src/test/test-data/component4-1.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codehaus-plexus/plexus-classworlds/f2e1d80c5547f807bcd6529e767db811a838d89b/src/test/test-data/component4-1.0.jar -------------------------------------------------------------------------------- /src/test/test-data/component5-1.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codehaus-plexus/plexus-classworlds/f2e1d80c5547f807bcd6529e767db811a838d89b/src/test/test-data/component5-1.0.jar -------------------------------------------------------------------------------- /src/test/test-data/component5-2.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codehaus-plexus/plexus-classworlds/f2e1d80c5547f807bcd6529e767db811a838d89b/src/test/test-data/component5-2.0.jar -------------------------------------------------------------------------------- /src/test/test-data/d.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codehaus-plexus/plexus-classworlds/f2e1d80c5547f807bcd6529e767db811a838d89b/src/test/test-data/d.jar -------------------------------------------------------------------------------- /src/test/test-data/deadlock.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codehaus-plexus/plexus-classworlds/f2e1d80c5547f807bcd6529e767db811a838d89b/src/test/test-data/deadlock.jar -------------------------------------------------------------------------------- /src/test/test-data/dupe-main.conf: -------------------------------------------------------------------------------- 1 | 2 | main is com.werken.Foo from foo 3 | main is com.werken.Bar from bar 4 | -------------------------------------------------------------------------------- /src/test/test-data/dupe-realm.conf: -------------------------------------------------------------------------------- 1 | 2 | [cheese] 3 | 4 | [dupe.realm] 5 | 6 | [potatoes] 7 | 8 | [dupe.realm] 9 | 10 | -------------------------------------------------------------------------------- /src/test/test-data/early-import.conf: -------------------------------------------------------------------------------- 1 | 2 | import org.xml.sax from root 3 | -------------------------------------------------------------------------------- /src/test/test-data/from-from-0.0.1-from-load-import.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codehaus-plexus/plexus-classworlds/f2e1d80c5547f807bcd6529e767db811a838d89b/src/test/test-data/from-from-0.0.1-from-load-import.jar -------------------------------------------------------------------------------- /src/test/test-data/inheritance.conf: -------------------------------------------------------------------------------- 1 | # ------------------------------------------------------------ 2 | # Define the main entry-point 3 | # ------------------------------------------------------------ 4 | 5 | main is org.apache.maven.app.App from root.maven 6 | 7 | # ------------------------------------------------------------ 8 | # Start defining realms 9 | # ------------------------------------------------------------ 10 | 11 | [root] 12 | load ${basedir}/src/test/test-data/a.jar 13 | 14 | [root.maven] 15 | load ${basedir}/src/test/test-data/b.jar 16 | 17 | [root.maven.plugin] 18 | load ${basedir}/src/test/test-data/c.jar 19 | -------------------------------------------------------------------------------- /src/test/test-data/launch-noclass.conf: -------------------------------------------------------------------------------- 1 | 2 | main is b.Goober from app 3 | 4 | [app] 5 | load ${basedir}/src/test/test-data/a.jar 6 | load ${basedir}/src/test/test-data/b.jar 7 | -------------------------------------------------------------------------------- /src/test/test-data/launch-nomethod.conf: -------------------------------------------------------------------------------- 1 | 2 | main is c.C from app 3 | 4 | [app] 5 | load ${basedir}/src/test/test-data/a.jar 6 | load ${basedir}/src/test/test-data/b.jar 7 | load ${basedir}/src/test/test-data/c.jar 8 | -------------------------------------------------------------------------------- /src/test/test-data/nested.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codehaus-plexus/plexus-classworlds/f2e1d80c5547f807bcd6529e767db811a838d89b/src/test/test-data/nested.jar -------------------------------------------------------------------------------- /src/test/test-data/nested.properties: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # 3 | # Copyright 2001-2006 The Codehaus Foundation. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | nested.properties 19 | -------------------------------------------------------------------------------- /src/test/test-data/optionally-existent.conf: -------------------------------------------------------------------------------- 1 | 2 | # ------------------------------------------------------------ 3 | # Define the main entry-point 4 | # ------------------------------------------------------------ 5 | 6 | main is org.apache.maven.app.App from opt 7 | 8 | # ------------------------------------------------------------ 9 | # Start defining realms 10 | # ------------------------------------------------------------ 11 | 12 | [opt] 13 | optionally ${basedir}/target/test-lib/jakarta.xml.bind-api-4.0.2.jar 14 | 15 | -------------------------------------------------------------------------------- /src/test/test-data/optionally-nonexistent.conf: -------------------------------------------------------------------------------- 1 | 2 | # ------------------------------------------------------------ 3 | # Define the main entry-point 4 | # ------------------------------------------------------------ 5 | 6 | main is org.apache.maven.app.App from opt 7 | 8 | # ------------------------------------------------------------ 9 | # Start defining realms 10 | # ------------------------------------------------------------ 11 | 12 | [opt] 13 | optionally /non/existant/path/*.jar 14 | -------------------------------------------------------------------------------- /src/test/test-data/realm-syntax.conf: -------------------------------------------------------------------------------- 1 | 2 | [foo 3 | ] 4 | -------------------------------------------------------------------------------- /src/test/test-data/resources/classworlds.conf: -------------------------------------------------------------------------------- 1 | # ------------------------------------------------------------ 2 | # Define the main entry-point 3 | # ------------------------------------------------------------ 4 | 5 | main is foo from root 6 | 7 | # ------------------------------------------------------------ 8 | # Start defining realms 9 | # ------------------------------------------------------------ 10 | 11 | [root] 12 | load ${basedir}/src/test/test-data/resources/werkflow.jar 13 | -------------------------------------------------------------------------------- /src/test/test-data/resources/werkflow.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codehaus-plexus/plexus-classworlds/f2e1d80c5547f807bcd6529e767db811a838d89b/src/test/test-data/resources/werkflow.jar -------------------------------------------------------------------------------- /src/test/test-data/set-using-existent.conf: -------------------------------------------------------------------------------- 1 | 2 | # ------------------------------------------------------------ 3 | # Define the main entry-point 4 | # ------------------------------------------------------------ 5 | 6 | main is org.apache.maven.app.App from opt 7 | 8 | # ------------------------------------------------------------ 9 | # Set properties 10 | # ------------------------------------------------------------ 11 | set set.using.existent using ${basedir}/src/test/test-data/set-using-existent.properties 12 | set set.using.default using ${basedir}/src/test/test-data/set-using-existent.properties default testSet_Using_Existent_Default 13 | 14 | # ------------------------------------------------------------ 15 | # Start defining realms 16 | # ------------------------------------------------------------ 17 | 18 | [opt] 19 | 20 | -------------------------------------------------------------------------------- /src/test/test-data/set-using-existent.properties: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # 3 | # Copyright 2001-2006 The Codehaus Foundation. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | set.using.existent=testSet_Using_Existent 19 | 20 | -------------------------------------------------------------------------------- /src/test/test-data/set-using-missing.conf: -------------------------------------------------------------------------------- 1 | 2 | # ------------------------------------------------------------ 3 | # Define the main entry-point 4 | # ------------------------------------------------------------ 5 | 6 | main is org.apache.maven.app.App from opt 7 | 8 | # ------------------------------------------------------------ 9 | # Set properties 10 | # ------------------------------------------------------------ 11 | set set.using.missing default testSet_Using_Missing_Default 12 | set set.using.filtered.default default ${user.home}/m2 13 | 14 | # ------------------------------------------------------------ 15 | # Start defining realms 16 | # ------------------------------------------------------------ 17 | 18 | [opt] 19 | 20 | -------------------------------------------------------------------------------- /src/test/test-data/set-using-nonexistent.conf: -------------------------------------------------------------------------------- 1 | 2 | # ------------------------------------------------------------ 3 | # Define the main entry-point 4 | # ------------------------------------------------------------ 5 | 6 | main is org.apache.maven.app.App from opt 7 | 8 | # ------------------------------------------------------------ 9 | # Set properties 10 | # ------------------------------------------------------------ 11 | set set.using.nonexistent using ${basedir}/src/test/test-data/set-using-nonexistent.properties 12 | set set.using.nonexistent.default using ${basedir}/src/test/test-data/set-using-nonexistent.properties default testSet_Using_NonExistent_Default 13 | 14 | # ------------------------------------------------------------ 15 | # Start defining realms 16 | # ------------------------------------------------------------ 17 | 18 | [opt] 19 | 20 | -------------------------------------------------------------------------------- /src/test/test-data/unhandled.conf: -------------------------------------------------------------------------------- 1 | 2 | foo 3 | -------------------------------------------------------------------------------- /src/test/test-data/valid-enh-launch-exitCode.conf: -------------------------------------------------------------------------------- 1 | 2 | main is b.Bb from app 3 | 4 | [app] 5 | load ${basedir}/src/test/test-data/a.jar 6 | load ${basedir}/src/test/test-data/b.jar 7 | -------------------------------------------------------------------------------- /src/test/test-data/valid-enh-launch.conf: -------------------------------------------------------------------------------- 1 | 2 | main is b.B from app 3 | 4 | [app] 5 | load ${basedir}/src/test/test-data/a.jar 6 | load ${basedir}/src/test/test-data/b.jar 7 | -------------------------------------------------------------------------------- /src/test/test-data/valid-from-from-from.conf: -------------------------------------------------------------------------------- 1 | 2 | # ------------------------------------------------------------ 3 | # Define the main entry-point 4 | # ------------------------------------------------------------ 5 | 6 | main is com.from.from.from.Main from from 7 | 8 | # ------------------------------------------------------------ 9 | # Start defining realms 10 | # ------------------------------------------------------------ 11 | 12 | [from] 13 | load ${basedir}/src/test/test-data/from-from-0.0.1-from-load-import.jar 14 | 15 | [ant] 16 | import com.from.from.from from from 17 | load ${basedir}/target/test-lib/ant-1.10.14.jar 18 | 19 | [maven] 20 | import com.from.from.from from from 21 | load ${basedir}/target/test-lib/log4j-api-2.23.1.jar 22 | 23 | [glob] 24 | load ${basedir}/src/test/test-data/*.jar 25 | -------------------------------------------------------------------------------- /src/test/test-data/valid-launch-exitCode.conf: -------------------------------------------------------------------------------- 1 | 2 | main is a.Aa from app 3 | 4 | [app] 5 | load ${basedir}/src/test/test-data/a.jar 6 | -------------------------------------------------------------------------------- /src/test/test-data/valid-launch.conf: -------------------------------------------------------------------------------- 1 | 2 | main is a.A from app 3 | 4 | [app] 5 | load ${basedir}/src/test/test-data/a.jar 6 | -------------------------------------------------------------------------------- /src/test/test-data/valid.conf: -------------------------------------------------------------------------------- 1 | 2 | # ------------------------------------------------------------ 3 | # Define the main entry-point 4 | # ------------------------------------------------------------ 5 | 6 | main is org.apache.maven.app.App from maven 7 | 8 | # ------------------------------------------------------------ 9 | # Start defining realms 10 | # ------------------------------------------------------------ 11 | 12 | [xml] 13 | load ${basedir}/target/test-lib/jakarta.xml.bind-api-4.0.2.jar 14 | 15 | [ant] 16 | import jakarta.xml.bind from xml 17 | load ${basedir}/target/test-lib/ant-1.10.14.jar 18 | 19 | [maven] 20 | import jakarta.xml.bind from xml 21 | load ${basedir}/target/test-lib/log4j-api-2.23.1.jar 22 | 23 | [glob] 24 | load ${basedir}/src/test/test-data/*.jar 25 | --------------------------------------------------------------------------------