Uploaded image for project: 'Felix'
  1. Felix
  2. FELIX-6430

Felix uses sun.misc.Unsafe, crashed on JDK 17

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major
    • Resolution: Fixed
    • framework-7.0.0
    • framework-7.0.1
    • None
    • None

    Description

      When running on JDK 17, Felix crashes with the following exception:

      java.lang.NoSuchMethodException: sun.misc.Unsafe.defineAnonymousClass(java.lang.Class,[B,[Ljava.lang.Object;)
       at java.base/java.lang.Class.getMethod(Class.java:2227)
       at org.apache.felix.framework.util.SecureAction.getAccessor(SecureAction.java:1134)
       at org.apache.felix.framework.util.SecureAction.<clinit>(SecureAction.java:86)
       at org.apache.felix.framework.Felix.<clinit>(Felix.java:114)
       at org.apache.felix.framework.FrameworkFactory.newFramework(FrameworkFactory.java:30)
      

      The offending code in question reflectively uses sun.misc.Unsafe

      private static Consumer<AccessibleObject[]> getAccessor(Class clazz) {
          String packageName = clazz.getPackage().getName();
          
          if ("java.net".equals(packageName) || "jdk.internal.loader".equals(packageName)) {
              if (m_accessorCache == null) {
                  try {
                      // Use reflection on Unsafe to avoid having to compile against it
                      Class<?> unsafeClass = Class.forName("sun.misc.Unsafe");
                      Field theUnsafe = unsafeClass.getDeclaredField("theUnsafe");
                      
                      // NOTE: deep reflection is allowed on sun.misc package for java 9.
                      theUnsafe.setAccessible(true);
                      Object unsafe = theUnsafe.get(null);
                      
                      // using defineAnonymousClass here because it seems more simple 
                      // to get what we need
                      Method defineAnonymousClass = 
                          unsafeClass.getMethod("defineAnonymousClass", 
                              Class.class, 
                              byte[].class, 
                              Object[].class);
                      
                      // The bytes stored in a resource to avoid real loading of it 
                      // (see accessible.src for source).
                      Class<Consumer<AccessibleObject[]>> result =
                         (Class<Consumer<AccessibleObject[]>>) 
                         defineAnonymousClass.invoke(
                              unsafe, URL.class,
                              accessor, null);
                      m_accessorCache = result.getConstructor().newInstance();
                  } catch (Throwable t) {
                      t.printStackTrace();
                      m_accessorCache = 
                          objects -> AccessibleObject.setAccessible(objects, true);
                  }
              }
              
              return m_accessorCache;
          }
          
          return objects -> AccessibleObject.setAccessible(objects, true);
      }
      

      For JDK 17+ it may be needed to stop using sun.misc.Unsafe and use a JDK replacement?

      Attachments

        Issue Links

          Activity

            People

              karlpauls Karl Pauls
              arjan.tijms Arjan Tijms
              Votes:
              1 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: