You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@felix.apache.org by "Arjan Tijms (Jira)" <ji...@apache.org> on 2021/06/10 14:29:00 UTC
[jira] [Updated] (FELIX-6430) Felix uses sun.misc.Unsafe, crashed
on JDK 17
[ https://issues.apache.org/jira/browse/FELIX-6430?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Arjan Tijms updated FELIX-6430:
-------------------------------
Description:
When running on JDK 17, Felix crashes with the following exception:
{noformat}
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)
{noformat}
The offending code in question reflectively uses {{sun.misc.Unsafe}}
{code:java}
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);
}
{code}
For JDK 17+ it may be needed to stop using {{sun.misc.Unsafe}} and use a JDK replacement?
was:
When running on JDK 17, Felix crashes with the following exception:
{noformat}
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)
{noformat}
The offending code in question reflectively uses {{sun.misc.Unsafe}}
{code:java}
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);
}
{code}
For JDK 17+ it may be needed to stop using {{sun.misc.Unsafe}} and use a JDK replacement?
> Felix uses sun.misc.Unsafe, crashed on JDK 17
> ---------------------------------------------
>
> Key: FELIX-6430
> URL: https://issues.apache.org/jira/browse/FELIX-6430
> Project: Felix
> Issue Type: Bug
> Affects Versions: framework-7.0.0
> Reporter: Arjan Tijms
> Priority: Major
>
> When running on JDK 17, Felix crashes with the following exception:
>
> {noformat}
> 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)
> {noformat}
> The offending code in question reflectively uses {{sun.misc.Unsafe}}
> {code:java}
> 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);
> }
> {code}
> For JDK 17+ it may be needed to stop using {{sun.misc.Unsafe}} and use a JDK replacement?
--
This message was sent by Atlassian Jira
(v8.3.4#803005)