Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 95 additions & 0 deletions COMPATIBILITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# Legacy `org.codehaus.classworlds` Compatibility Layer

## Summary

The `org.codehaus.classworlds` package is the original Classworlds 1.x API (pre-2010). It has been
deprecated since 2014 (version 2.5.2) in favour of `org.codehaus.plexus.classworlds`. It cannot
be removed without coordinating with the Eclipse Sisu and Apache Maven teams.

## Why it cannot simply be deleted

In April 2026, PR #141 removed this package after 12 years of deprecation, expecting that all
consumers had migrated. The change was reverted within days (commit 223416e) because:

**`org.eclipse.sisu:org.eclipse.sisu.plexus` (the DI framework used by Maven 3+) contains compiled
bytecode that directly references classes in this package.**

Inspecting `org.eclipse.sisu.plexus-1.0.0.jar`:

```
org.codehaus.plexus.component.configurator.converters.special.ClassRealmConverter
references:
org/codehaus/classworlds/ClassRealm
org/codehaus/classworlds/ClassRealmAdapter
org/codehaus/classworlds/ClassRealmReverseAdapter
```

`ClassRealmConverter` is a core Sisu component that handles injection of `ClassRealm` instances
into Plexus components. Without these three classes on the classpath at runtime, any Maven 3+
build or any application embedding Sisu fails with `ClassNotFoundException` or
`NoClassDefFoundError` before it can do any useful work.

This is a **binary dependency on a released artifact**, not a source-level dependency. The fix
cannot be on the plexus-classworlds side alone.

## What is in the compatibility layer

```
org.codehaus.classworlds
├── ClassRealm (interface) <- referenced by Sisu
├── ClassRealmAdapter (wraps new → old) <- referenced by Sisu
├── ClassRealmReverseAdapter (wraps old → new) <- referenced by Sisu
├── ClassWorld (interface)
├── ClassWorldAdapter (wraps new → old)
├── ClassWorldReverseAdapter (wraps old → new)
├── DefaultClassRealm (adapter impl)
├── ClassWorldException
├── DuplicateRealmException
├── NoSuchRealmException
├── ConfigurationException
├── Configurator
├── ConfiguratorAdapter
├── Launcher
├── BytesURLConnection
└── BytesURLStreamHandler
```

The adapter classes use the standard Adapter pattern to bridge between the old interface and the
modern `org.codehaus.plexus.classworlds.realm.ClassRealm` implementation.

## Rules for working with this package

Do not remove classes or change any public API in `org.codehaus.classworlds`.

Do not add new API to this package. Any new features belong in `org.codehaus.plexus.classworlds`.

Before any release that touches this package, verify with the Sisu test suite:

```bash
mvn clean install # build plexus-classworlds locally
cd /path/to/sisu.plexus
mvn clean test -Dplexus-classworlds.version=<snapshot>
```

## Removing this package in the future

Removal requires the following preconditions to all be true:

1. A release of `org.eclipse.sisu:org.eclipse.sisu.plexus` ships that no longer references
`org.codehaus.classworlds.*` in its bytecode.
2. That Sisu release has been adopted by a stable Apache Maven release.
3. The Maven release is widely deployed (typically means it shipped in at least two Maven minor
versions and toolchains like Maven Wrapper have picked it up).

Until those conditions are met, this package stays.

When those conditions are met, the removal should be done in a **major version** of
plexus-classworlds with a clear upgrade notice in the release notes.

## References

- Original PR that removed the package: https://github.com/codehaus-plexus/plexus-classworlds/pull/141
- Original removal issue: https://github.com/codehaus-plexus/plexus-classworlds/issues/130
- Revert commit: 223416e
- Eclipse Sisu: https://github.com/eclipse/sisu.plexus

17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,20 @@ Plexus-Classworlds
![Build Status](https://github.com/codehaus-plexus/plexus-classworlds/workflows/GitHub%20CI/badge.svg)

Current master is now at https://github.com/codehaus-plexus/plexus-classworlds

Backward Compatibility
----------------------

This project maintains a legacy compatibility layer in the `org.codehaus.classworlds` package.
This package **cannot be removed** without coordinating with the Eclipse Sisu and Apache Maven teams.

The compiled bytecode of `org.eclipse.sisu:org.eclipse.sisu.plexus` directly references
`org.codehaus.classworlds.ClassRealm`, `ClassRealmAdapter`, and `ClassRealmReverseAdapter`.
Removing this package causes `ClassNotFoundException` at runtime for any application using Sisu
(which includes all Maven 3+ builds).

PR #141 removed this package and had to be reverted immediately (see commit 223416e).

New code should use the `org.codehaus.plexus.classworlds` package.
See [COMPATIBILITY.md](COMPATIBILITY.md) for the full picture, including what Sisu references
and what is required before any future removal can be considered.
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@
<configuration>
<instructions>
<_nouses>true</_nouses>
<Export-Package>org.codehaus.plexus.classworlds.*</Export-Package>
<Export-Package>org.codehaus.classworlds.*</Export-Package>
</instructions>
</configuration>
</plugin>
Expand All @@ -127,7 +127,7 @@
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<redirectTestOutputToFile>true</redirectTestOutputToFile>
<argLine>-ea:org.codehaus.plexus.classworlds @{argLine}</argLine>
<argLine>-ea:org.codehaus.classworlds:org.codehaus.plexus.classworlds @{argLine}</argLine>
Comment thread
slachiewicz marked this conversation as resolved.
<forkCount>1</forkCount>
</configuration>
</plugin>
Expand Down
50 changes: 50 additions & 0 deletions src/main/java/org/codehaus/classworlds/BytesURLConnection.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package org.codehaus.classworlds;

/*
* Copyright 2001-2010 Codehaus Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;

/**
* URLConnection implementation for byte arrays.
*
* <p><b>Note:</b> This is a legacy class provided for backward compatibility with Maven 2.
* New code should avoid using this internal implementation detail.</p>
*
* @deprecated This is a legacy internal class.
*/
@Deprecated
public class BytesURLConnection extends URLConnection {
protected final byte[] content;

protected int offset;

protected int length;

public BytesURLConnection(URL url, byte[] content) {
super(url);
this.content = content;
}

public void connect() {}

public InputStream getInputStream() {
return new ByteArrayInputStream(content);
}
}
47 changes: 47 additions & 0 deletions src/main/java/org/codehaus/classworlds/BytesURLStreamHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package org.codehaus.classworlds;

/*
* Copyright 2001-2010 Codehaus Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import java.net.URL;
import java.net.URLConnection;
import java.net.URLStreamHandler;

/**
* URLStreamHandler implementation for byte arrays.
*
* <p><b>Note:</b> This is a legacy class provided for backward compatibility with Maven 2.
* New code should avoid using this internal implementation detail.</p>
*
* @author Hani Suleiman (hani@formicary.net) Date: Oct 20, 2003 12:45:18 AM
* @deprecated This is a legacy internal class.
*/
@Deprecated
public class BytesURLStreamHandler extends URLStreamHandler {
final byte[] content;

int offset;

int length;

public BytesURLStreamHandler(byte[] content) {
this.content = content;
}

public URLConnection openConnection(URL url) {
return new BytesURLConnection(url, content);
}
}
110 changes: 110 additions & 0 deletions src/main/java/org/codehaus/classworlds/ClassRealm.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package org.codehaus.classworlds;

/*

Copyright 2002 (C) The Werken Company. All Rights Reserved.

Redistribution and use of this software and associated documentation
("Software"), with or without modification, are permitted provided
that the following conditions are met:

1. Redistributions of source code must retain copyright
statements and notices. Redistributions must also contain a
copy of this document.

2. Redistributions in binary form must reproduce the
above copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.

3. The name "classworlds" must not be used to endorse or promote
products derived from this Software without prior written
permission of The Werken Company. For written permission,
please contact bob@werken.com.

4. Products derived from this Software may not be called "classworlds"
nor may "classworlds" appear in their names without prior written
permission of The Werken Company. "classworlds" is a registered
trademark of The Werken Company.

5. Due credit should be given to The Werken Company.
(http://classworlds.werken.com/).

THIS SOFTWARE IS PROVIDED BY THE WERKEN COMPANY AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
THE WERKEN COMPANY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
OF THE POSSIBILITY OF SUCH DAMAGE.

*/

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Enumeration;

/**
* <p>Autonomous sub-portion of a <code>ClassWorld</code>.</p>
*
* <p>This class most closed maps to the <code>ClassLoader</code>
* role from Java and in facts can provide a <code>ClassLoader</code>
* view of itself using {@link #getClassLoader}.</p>
*
* <p>This is a legacy interface from Classworlds 1.x, preserved for binary compatibility.
* The compiled bytecode of {@code org.eclipse.sisu:org.eclipse.sisu.plexus} references this
* interface directly. Removing it breaks all Maven 3+ builds.
* New code should use {@link org.codehaus.plexus.classworlds.realm.ClassRealm}.</p>
*
* @author <a href="mailto:bob@eng.werken.com">bob mcwhirter</a>
* @author <a href="mailto:jason@zenplex.com">Jason van Zyl</a>
* @deprecated Use {@link org.codehaus.plexus.classworlds.realm.ClassRealm} for new code.
* This interface must remain on the classpath for Sisu compatibility.
*/
@SuppressWarnings("rawtypes")
@Deprecated
public interface ClassRealm {
String getId();

ClassWorld getWorld();

void importFrom(String realmId, String pkgName) throws NoSuchRealmException;

void addConstituent(URL constituent);

ClassRealm locateSourceRealm(String className);

void setParent(ClassRealm classRealm);

ClassRealm createChildRealm(String id) throws DuplicateRealmException;

ClassLoader getClassLoader();

ClassRealm getParent();

URL[] getConstituents();

// ----------------------------------------------------------------------
// Classloading
// ----------------------------------------------------------------------

Class loadClass(String name) throws ClassNotFoundException;

// ----------------------------------------------------------------------
// Resource handling
// ----------------------------------------------------------------------

URL getResource(String name);

Enumeration findResources(String name) throws IOException;

InputStream getResourceAsStream(String name);

void display();
}
Loading
Loading