Petals ESB Container

In Java 11, AppClassLoader is no more a URLClassLoader

Details

  • Type: Task Task
  • Status: Resolved Resolved
  • Priority: Critical Critical
  • Resolution: Fixed
  • Affects Version/s: 5.2.0
  • Fix Version/s: 5.3.0
  • Component/s: Classloader
  • Security Level: Public
  • Description:
    Hide

    According to the following Java 11 migration guide: https://nipafx.dev/java-11-migration-guide/

    Java 9 and the module system improved the platform's class loading strategy, which is implemented in a new type and in Java 11 the application class loader is of that type. That means it is not a URLClassLoader, anymore, so the occasional (URLClassLoader) getClass().getClassLoader() or (URLClassLoader) ClassLoader.getSystemClassLoader() sequences will no longer execute. This is another typical example where Java 11 is backwards compatible in the strict sense (because that it's a URLCassLoader was never specified) but which can nonetheless cause migration challenges.

    Symptoms

    This one is very obvious. You'll get a ClassCastException complaining that the new AppClassLoader is no URLClassLoader:

    Exception in thread "main" java.lang.ClassCastException:
    	java.base/jdk.internal.loader.ClassLoaders$AppClassLoader
    	cannot be cast to java.base/java.net.URLClassLoader
    		at monitor.Main.logClassPathContent(Main.java:46)
    		at monitor.Main.main(Main.java:28)

    Fixes

    The class loader was probably cast to access methods specific to URLClassLoader. If so, you might have to face some serious changes.

    If you want to access the class path content, check the system property java.class.path and parse it:

    String pathSeparator = System
    	.getProperty("path.separator");
    String[] classPathEntries = System
    	.getProperty("java.class.path")
    	.split(pathSeparator);

    If you've used the URLClassLoader to dynamically load user provided code (for example as part of a plugin infrastructure) by appending to the class path, then you have to find a new way to do that as it can not be done with Java 11. You should instead consider creating a new class loader for that. This has the added advantage that you'll be able to get rid of the new classes as they are not loaded into the application class loader. You should also read up on layers - they give you a clean abstraction for loading an entirely new module graph.

    Beyond that, your chances to do a migration with only small changes are slim. The only supported (and hence accessible) super types of the new AppClassLoader are SecureClassLoader and ClassLoader and only few methods were added here in 9. Still, have a look, they might do what you're looking for.

    Consequently all common dependencies available in the entry 'Class-Path' of the JAR 'petals-bootstrap-launcher' are no more available for CXF Dynamic client used by the Petals SE Flowable through the Flowable's module 'flowable-cxf', specially JAXB dependencies (see PETALSDISTRIB-474).

    Show
    According to the following Java 11 migration guide: https://nipafx.dev/java-11-migration-guide/
    Java 9 and the module system improved the platform's class loading strategy, which is implemented in a new type and in Java 11 the application class loader is of that type. That means it is not a URLClassLoader, anymore, so the occasional (URLClassLoader) getClass().getClassLoader() or (URLClassLoader) ClassLoader.getSystemClassLoader() sequences will no longer execute. This is another typical example where Java 11 is backwards compatible in the strict sense (because that it's a URLCassLoader was never specified) but which can nonetheless cause migration challenges. Symptoms This one is very obvious. You'll get a ClassCastException complaining that the new AppClassLoader is no URLClassLoader:
    Exception in thread "main" java.lang.ClassCastException:
    	java.base/jdk.internal.loader.ClassLoaders$AppClassLoader
    	cannot be cast to java.base/java.net.URLClassLoader
    		at monitor.Main.logClassPathContent(Main.java:46)
    		at monitor.Main.main(Main.java:28)
    Fixes The class loader was probably cast to access methods specific to URLClassLoader. If so, you might have to face some serious changes. If you want to access the class path content, check the system property java.class.path and parse it:
    String pathSeparator = System
    	.getProperty("path.separator");
    String[] classPathEntries = System
    	.getProperty("java.class.path")
    	.split(pathSeparator);
    If you've used the URLClassLoader to dynamically load user provided code (for example as part of a plugin infrastructure) by appending to the class path, then you have to find a new way to do that as it can not be done with Java 11. You should instead consider creating a new class loader for that. This has the added advantage that you'll be able to get rid of the new classes as they are not loaded into the application class loader. You should also read up on layers - they give you a clean abstraction for loading an entirely new module graph. Beyond that, your chances to do a migration with only small changes are slim. The only supported (and hence accessible) super types of the new AppClassLoader are SecureClassLoader and ClassLoader and only few methods were added here in 9. Still, have a look, they might do what you're looking for.
    Consequently all common dependencies available in the entry 'Class-Path' of the JAR 'petals-bootstrap-launcher' are no more available for CXF Dynamic client used by the Petals SE Flowable through the Flowable's module 'flowable-cxf', specially JAXB dependencies (see PETALSDISTRIB-474).
  • Environment:
    -

Issue Links

Activity

Christophe DENEUX made changes - Thu, 29 Apr 2021 - 15:50:18 +0200
Field Original Value New Value
Priority Critical [ 2 ]
Description According to the following Java 11 migration guide: https://nipafx.dev/java-11-migration-guide/

{quote}Java 9 and the module system improved the platform's class loading strategy, which is implemented in a new type and in Java 11 the application class loader is of that type. That means it is not a {{URLClassLoader}}, anymore, so the occasional {{(URLClassLoader) getClass().getClassLoader()}} or {{(URLClassLoader) ClassLoader.getSystemClassLoader()}} sequences will no longer execute. This is another typical example where Java 11 is backwards compatible in the strict sense (because that it's a {{URLCassLoader}} was never specified) but which can nonetheless cause migration challenges.

*Symptoms*

This one is very obvious. You'll get a {{ClassCastException}} complaining that the new {{AppClassLoader}} is no {{URLClassLoader}}:
{code}
Exception in thread "main" java.lang.ClassCastException:
java.base/jdk.internal.loader.ClassLoaders$AppClassLoader
cannot be cast to java.base/java.net.URLClassLoader
at monitor.Main.logClassPathContent(Main.java:46)
at monitor.Main.main(Main.java:28)
{code}

*Fixes*

The class loader was probably cast to access methods specific to {{URLClassLoader}}. If so, you might have to face some serious changes.

If you want to access the class path content, check the system property {{java.class.path}} and parse it:
{code}
String pathSeparator = System
.getProperty("path.separator");
String[] classPathEntries = System
.getProperty("java.class.path")
.split(pathSeparator);
{code}
If you've used the {{URLClassLoader}} to dynamically load user provided code (for example as part of a plugin infrastructure) by appending to the class path, then you have to find a new way to do that as it can not be done with Java 11. You should instead consider creating a new class loader for that. This has the added advantage that you'll be able to get rid of the new classes as they are not loaded into the application class loader. You should also read up on layers - they give you a clean abstraction for loading an entirely new module graph.

Beyond that, your chances to do a migration with only small changes are slim. The only supported (and hence accessible) super types of the new {{AppClassLoader}} are {{SecureClassLoader}} and {{ClassLoader}} and only few methods were added here in 9. Still, have a look, they might do what you're looking for.
{quote}
According to the following Java 11 migration guide: https://nipafx.dev/java-11-migration-guide/

{quote}Java 9 and the module system improved the platform's class loading strategy, which is implemented in a new type and in Java 11 the application class loader is of that type. That means it is not a {{URLClassLoader}}, anymore, so the occasional {{(URLClassLoader) getClass().getClassLoader()}} or {{(URLClassLoader) ClassLoader.getSystemClassLoader()}} sequences will no longer execute. This is another typical example where Java 11 is backwards compatible in the strict sense (because that it's a {{URLCassLoader}} was never specified) but which can nonetheless cause migration challenges.

*Symptoms*

This one is very obvious. You'll get a {{ClassCastException}} complaining that the new {{AppClassLoader}} is no {{URLClassLoader}}:
{code}
Exception in thread "main" java.lang.ClassCastException:
java.base/jdk.internal.loader.ClassLoaders$AppClassLoader
cannot be cast to java.base/java.net.URLClassLoader
at monitor.Main.logClassPathContent(Main.java:46)
at monitor.Main.main(Main.java:28)
{code}

*Fixes*

The class loader was probably cast to access methods specific to {{URLClassLoader}}. If so, you might have to face some serious changes.

If you want to access the class path content, check the system property {{java.class.path}} and parse it:
{code}
String pathSeparator = System
.getProperty("path.separator");
String[] classPathEntries = System
.getProperty("java.class.path")
.split(pathSeparator);
{code}
If you've used the {{URLClassLoader}} to dynamically load user provided code (for example as part of a plugin infrastructure) by appending to the class path, then you have to find a new way to do that as it can not be done with Java 11. You should instead consider creating a new class loader for that. This has the added advantage that you'll be able to get rid of the new classes as they are not loaded into the application class loader. You should also read up on layers - they give you a clean abstraction for loading an entirely new module graph.

Beyond that, your chances to do a migration with only small changes are slim. The only supported (and hence accessible) super types of the new {{AppClassLoader}} are {{SecureClassLoader}} and {{ClassLoader}} and only few methods were added here in 9. Still, have a look, they might do what you're looking for.
{quote}

Consequently all common dependencies available in the entry 'Class-Path' of the JAR '{{petals-bootstrap-launcher}} are no more available for CXF Dynamic client used by the Petals SE Flowable through the Flowable's module '{{flowable-cxf}}', specially JAXB dependencies (see PETALSDISTRIB-474)
Christophe DENEUX made changes - Thu, 29 Apr 2021 - 15:50:26 +0200
Link This issue depends on PETALSDISTRIB-474 [ PETALSDISTRIB-474 ]
Christophe DENEUX made changes - Thu, 29 Apr 2021 - 15:50:41 +0200
Link This issue blocks PETALSDISTRIB-416 [ PETALSDISTRIB-416 ]
Christophe DENEUX made changes - Thu, 29 Apr 2021 - 15:51:02 +0200
Link This issue blocks PETALSSEFLOWABLE-71 [ PETALSSEFLOWABLE-71 ]
Christophe DENEUX made changes - Thu, 29 Apr 2021 - 15:51:38 +0200
Description According to the following Java 11 migration guide: https://nipafx.dev/java-11-migration-guide/

{quote}Java 9 and the module system improved the platform's class loading strategy, which is implemented in a new type and in Java 11 the application class loader is of that type. That means it is not a {{URLClassLoader}}, anymore, so the occasional {{(URLClassLoader) getClass().getClassLoader()}} or {{(URLClassLoader) ClassLoader.getSystemClassLoader()}} sequences will no longer execute. This is another typical example where Java 11 is backwards compatible in the strict sense (because that it's a {{URLCassLoader}} was never specified) but which can nonetheless cause migration challenges.

*Symptoms*

This one is very obvious. You'll get a {{ClassCastException}} complaining that the new {{AppClassLoader}} is no {{URLClassLoader}}:
{code}
Exception in thread "main" java.lang.ClassCastException:
java.base/jdk.internal.loader.ClassLoaders$AppClassLoader
cannot be cast to java.base/java.net.URLClassLoader
at monitor.Main.logClassPathContent(Main.java:46)
at monitor.Main.main(Main.java:28)
{code}

*Fixes*

The class loader was probably cast to access methods specific to {{URLClassLoader}}. If so, you might have to face some serious changes.

If you want to access the class path content, check the system property {{java.class.path}} and parse it:
{code}
String pathSeparator = System
.getProperty("path.separator");
String[] classPathEntries = System
.getProperty("java.class.path")
.split(pathSeparator);
{code}
If you've used the {{URLClassLoader}} to dynamically load user provided code (for example as part of a plugin infrastructure) by appending to the class path, then you have to find a new way to do that as it can not be done with Java 11. You should instead consider creating a new class loader for that. This has the added advantage that you'll be able to get rid of the new classes as they are not loaded into the application class loader. You should also read up on layers - they give you a clean abstraction for loading an entirely new module graph.

Beyond that, your chances to do a migration with only small changes are slim. The only supported (and hence accessible) super types of the new {{AppClassLoader}} are {{SecureClassLoader}} and {{ClassLoader}} and only few methods were added here in 9. Still, have a look, they might do what you're looking for.
{quote}

Consequently all common dependencies available in the entry 'Class-Path' of the JAR '{{petals-bootstrap-launcher}} are no more available for CXF Dynamic client used by the Petals SE Flowable through the Flowable's module '{{flowable-cxf}}', specially JAXB dependencies (see PETALSDISTRIB-474)
According to the following Java 11 migration guide: https://nipafx.dev/java-11-migration-guide/

{quote}Java 9 and the module system improved the platform's class loading strategy, which is implemented in a new type and in Java 11 the application class loader is of that type. That means it is not a {{URLClassLoader}}, anymore, so the occasional {{(URLClassLoader) getClass().getClassLoader()}} or {{(URLClassLoader) ClassLoader.getSystemClassLoader()}} sequences will no longer execute. This is another typical example where Java 11 is backwards compatible in the strict sense (because that it's a {{URLCassLoader}} was never specified) but which can nonetheless cause migration challenges.

*Symptoms*

This one is very obvious. You'll get a {{ClassCastException}} complaining that the new {{AppClassLoader}} is no {{URLClassLoader}}:
{code}
Exception in thread "main" java.lang.ClassCastException:
java.base/jdk.internal.loader.ClassLoaders$AppClassLoader
cannot be cast to java.base/java.net.URLClassLoader
at monitor.Main.logClassPathContent(Main.java:46)
at monitor.Main.main(Main.java:28)
{code}

*Fixes*

The class loader was probably cast to access methods specific to {{URLClassLoader}}. If so, you might have to face some serious changes.

If you want to access the class path content, check the system property {{java.class.path}} and parse it:
{code}
String pathSeparator = System
.getProperty("path.separator");
String[] classPathEntries = System
.getProperty("java.class.path")
.split(pathSeparator);
{code}
If you've used the {{URLClassLoader}} to dynamically load user provided code (for example as part of a plugin infrastructure) by appending to the class path, then you have to find a new way to do that as it can not be done with Java 11. You should instead consider creating a new class loader for that. This has the added advantage that you'll be able to get rid of the new classes as they are not loaded into the application class loader. You should also read up on layers - they give you a clean abstraction for loading an entirely new module graph.

Beyond that, your chances to do a migration with only small changes are slim. The only supported (and hence accessible) super types of the new {{AppClassLoader}} are {{SecureClassLoader}} and {{ClassLoader}} and only few methods were added here in 9. Still, have a look, they might do what you're looking for.
{quote}

Consequently all common dependencies available in the entry 'Class-Path' of the JAR '{{petals-bootstrap-launcher}}' are no more available for CXF Dynamic client used by the Petals SE Flowable through the Flowable's module '{{flowable-cxf}}', specially JAXB dependencies (see PETALSDISTRIB-474).
Hide
Christophe DENEUX added a comment - Thu, 29 Apr 2021 - 16:03:56 +0200 - edited

The Petals Boostrap Launcher must create a dedicated URLClassloader from all Petals common dependencies as following:

Previous classloader hierarchy:

PlatformClassloader------------------
                                    |
                              AppClassloader
                          (loaded from MANIFEST
                       of petals-bootstrap-launcher
                         with common dependencies)
                                    |
              -----------------------------------------------
              |                                             |
        URLClassloader                          SharedLibrariesClassloader
(containing petals-default-launcher)                        |
              |                                             |
   PetalsContainerClassloader                      ComponentClassloader

New classloader hierarchy:

PlatformClassloader------------------
                                    |
                              AppClassloader
                        (empty, without extra JAR)
                                    |
                               URLClassloader                    <---------------- The new classloader layer
                    (created by petals-bootstrap-launcher,
                    and containing all common dependencies)
                                    |
              -----------------------------------------------
              |                                             |
        URLClassloader                          SharedLibrariesClassloader
(containing petals-default-launcher)                        |
              |                                             |
   PetalsContainerClassloader                      ComponentClassloader
Show
Christophe DENEUX added a comment - Thu, 29 Apr 2021 - 16:03:56 +0200 - edited The Petals Boostrap Launcher must create a dedicated URLClassloader from all Petals common dependencies as following: Previous classloader hierarchy:
PlatformClassloader------------------
                                    |
                              AppClassloader
                          (loaded from MANIFEST
                       of petals-bootstrap-launcher
                         with common dependencies)
                                    |
              -----------------------------------------------
              |                                             |
        URLClassloader                          SharedLibrariesClassloader
(containing petals-default-launcher)                        |
              |                                             |
   PetalsContainerClassloader                      ComponentClassloader
New classloader hierarchy:
PlatformClassloader------------------
                                    |
                              AppClassloader
                        (empty, without extra JAR)
                                    |
                               URLClassloader                    <---------------- The new classloader layer
                    (created by petals-bootstrap-launcher,
                    and containing all common dependencies)
                                    |
              -----------------------------------------------
              |                                             |
        URLClassloader                          SharedLibrariesClassloader
(containing petals-default-launcher)                        |
              |                                             |
   PetalsContainerClassloader                      ComponentClassloader
Christophe DENEUX made changes - Thu, 29 Apr 2021 - 16:03:56 +0200
Status New [ 10000 ] Open [ 10002 ]
Christophe DENEUX made changes - Thu, 29 Apr 2021 - 16:08:02 +0200
Summary {{AppClassLoader}} is no more a {{URLClassLoader}} In Java 11, AppClassLoader is no more a URLClassLoader
Christophe DENEUX made changes - Thu, 29 Apr 2021 - 16:13:53 +0200
Link This issue blocks PETALSSEFLOWABLE-74 [ PETALSSEFLOWABLE-74 ]
Christophe DENEUX made changes - Thu, 29 Apr 2021 - 16:20:15 +0200
Status Open [ 10002 ] In Progress [ 10003 ]
Hide
Christophe DENEUX added a comment - Tue, 23 Nov 2021 - 11:46:47 +0100

Fixed by svn#43779

Show
Christophe DENEUX added a comment - Tue, 23 Nov 2021 - 11:46:47 +0100 Fixed by svn#43779
Christophe DENEUX made changes - Tue, 23 Nov 2021 - 11:46:47 +0100
Status In Progress [ 10003 ] Resolved [ 10004 ]
Fix Version/s 5.3.0 [ 10877 ]
Resolution Fixed [ 1 ]
Transition Status Change Time Execution Times Last Executer Last Execution Date
New New Open Open
17m 51s
1
Christophe DENEUX
Thu, 29 Apr 2021 - 16:03:56 +0200
Open Open In Progress In Progress
16m 19s
1
Christophe DENEUX
Thu, 29 Apr 2021 - 16:20:15 +0200
In Progress In Progress Resolved Resolved
207d 20h 26m
1
Christophe DENEUX
Tue, 23 Nov 2021 - 11:46:47 +0100



People

Dates

  • Created:
    Thu, 29 Apr 2021 - 15:46:05 +0200
    Updated:
    Tue, 23 Nov 2021 - 11:46:47 +0100
    Resolved:
    Tue, 23 Nov 2021 - 11:46:47 +0100