Skip to content

OSGI Rest Resource fails upon Redeploy with message: IllegalArgumentException: object is not an instance of declaring class #31348

Open
@fabrizzio-dotCMS

Description

@fabrizzio-dotCMS

Parent Issue

#31185

Problem Statement

ClassLoader Conflict When Redeploying an OSGi Plugin that contains a Rest Resource that operates in Jersey

I was able to patch Jersey’s ServiceLocator so that we can stop and restart a resource loaded from an OSGi plugin without issues. However, I am now facing a new problem when undeploying and redeploying a JAR.

Root Cause:

2025-02-10 17:42:30 ... 78 more
2025-02-10 17:42:30 Caused by: java.lang.IllegalArgumentException: object is not an instance of declaring class
2025-02-10 17:42:30 at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.checkReceiver(DirectMethodHandleAccessor.java:197) ~[?:?]
2025-02-10 17:42:30 at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:99) ~[?:?]

This exception originates from JDK code and occurs because the resource method is being called via reflection. The validation logic in checkReceiver(Object o) ensures that the class of the object on which the method is invoked is assignable from the declaring class:

private void checkReceiver(Object o) {
    // NOTE: will throw NullPointerException, as specified, if o is null
    if (!declaringClass.isAssignableFrom(o.getClass())) {
        throw new IllegalArgumentException("object is not an instance of declaring class");
    }
}

Upon debugging, I confirmed that the class names are identical, but the issue occurs because the class loaders are different after redeployment. This is expected behavior in OSGi, where each bundle may have its own ClassLoader, leading to type mismatches when invoking methods reflectively.

Possible Solutions

To resolve this, we need to:

  1. Ensure the resource class and its dependencies are loaded using the same ClassLoader before invocation.
  2. Free the previous ClassLoader when the OSGi bundle is undeployed, ensuring that stale class definitions do not persist across deployments.
  3. You can simply reload the declaring class using the same ClassLoader as the object being passed, or find a way to isolate the Jersey resource instantiation.

Steps to Reproduce

  1. Deploy an OSGi bundle containing a Jersey resource.
  2. Successfully stop and restart the resource dynamically.
  3. Undeploy the OSGi bundle.
  4. Redeploy the OSGi bundle.
  5. Upon invoking a resource method, an exception is thrown:

Acceptance Criteria

We should be able to install un-install and continue to use the plugins with no problem

dotCMS Version

current trunk

Proposed Objective

Technical User Experience

Proposed Priority

Priority 2 - Important

External Links... Slack Conversations, Support Tickets, Figma Designs, etc.

https://dotcms.freshdesk.com/a/tickets/30903

No response

Assumptions & Initiation Needs

No response

Quality Assurance Notes & Workarounds

No response

Sub-Tasks & Estimates

No response

Metadata

Metadata

Type

No type

Projects

Status

In Progress

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions