{"id":134,"date":"2018-03-19T03:08:38","date_gmt":"2018-03-19T03:08:38","guid":{"rendered":"http:\/\/www.russgold.net\/sw\/?p=134"},"modified":"2018-04-03T05:08:02","modified_gmt":"2018-04-03T05:08:02","slug":"ch-ch-ch-changes","status":"publish","type":"post","link":"https:\/\/www.russgold.net\/sw\/2018\/03\/ch-ch-ch-changes\/","title":{"rendered":"Ch- ch- ch- changes!"},"content":{"rendered":"<p>Java 9 was, in a number of ways, possibly the most disruptive change to the language, largely due to the introduction of the Java Platform Module System (JPMS), which for the first time enforces the Java team&#8217;s insistence that programs not use JDK internals. Not only are many classes and methods suddenly inaccessible, a number have actually been removed, and even reflective access to those internals is suddenly deprecated. I can illustrate the impact with my library, <a href=\"http:\/\/simplestub.meterware.com\">SimpleStub<\/a>. This library generates stub classes at run time using ASM, a capability that was originally implemented by using reflection on JDK internals, such as:<\/p>\n<pre><code><em>defineClassMethod<\/em> = AccessController.doPrivileged(\r\n<strong>      new<\/strong> PrivilegedExceptionAction() {\r\n           <strong>public<\/strong> Method run() <strong>throws<\/strong> Exception {\r\n             Class&lt;?&gt; cl = Class.forName(\"java.lang.ClassLoader\");\r\n             <strong>return<\/strong> cl.getDeclaredMethod(\"defineClass\", String.<strong>class<\/strong>, \r\n                                 byte[].<strong>class<\/strong>, int.<strong>class<\/strong>, int.<strong>class<\/strong>);\r\n           }\r\n       });\r\n <em>defineClassMethod<\/em>.setAccessible(true);\r\n <strong>return<\/strong> <em>defineClassMethod<\/em>.invoke(anchorClass.getClassLoader(), \r\n                         className, classBytes, 0, classBytes.<strong>length<\/strong>);<\/code><\/pre>\n<p>As of Java 9, we&#8217;re not supposed to use reflection on the <code>java.lang<\/code> package, and at runtime, the JDK will print an illegal access warning, which is supposed to be turned into an error in the future. So in SimpleStub I changed the code to use Unsafe.defineClass:<\/p>\n<pre><code><strong>private final<\/strong> Unsafe <em>unsafe<\/em> = AccessController.doPrivileged(\r\n     <strong>new<\/strong> PrivilegedAction() {\r\n          <strong>public<\/strong> Unsafe run() {\r\n            <strong>try<\/strong> {\r\n               Field field =\r\n                      Unsafe.<strong>class<\/strong>.getDeclaredField(\"theUnsafe\");\r\n               field.setAccessible(true);\r\n               <strong>return<\/strong> (Unsafe) field.get(null);\r\n            } catch (NoSuchFieldException | IllegalAccessException e) {\r\n               <strong>throw new<\/strong> Error(\"Could not access Unsafe\", exc);\r\n            }\r\n          }\r\n     }\r\n);\r\n\r\n<strong>return<\/strong> <em>unsafe.defineClass<\/em>( className, classBytes, 0, \r\n classBytes.<strong>length<\/strong>, classLoader, null );<\/code><\/pre>\n<p>So, problem solved? Not exactly, as the plans for the in-development JDK 11 include removing the Unsafe.defineClass method. It has been replaced by code allowing this:<\/p>\n<pre><code>MethodHandles.Lookup lookup = \r\n     MethodHandles.privateLookupIn(anchorClass, MethodHandles.lookup())\r\n                  .dropLookupMode(MethodHandles.Lookup.PRIVATE);\r\n<strong>return<\/strong> lookup.defineClass(classBytes);\r\n<\/code><\/pre>\n<p>in which <em>anchorClass<\/em> is a class in the package in which the new class will be defined. That will require a bit of rework, but the main problem is that this relies on methods that were only added in Java 9! Switching to that implementation would break the library for earlier implementations.<\/p>\n<p>The language designers, of course, were fully aware of the problems they were creating, and added a new feature: the multi-release (MR) JAR, as part of <a href=\"http:\/\/openjdk.java.net\/jeps\/238\">JEP-238<\/a>. A problem, though, is that more than two years after this feature was announced, the tools still don&#8217;t actually provide much in the way of support. My next post will explore the current options.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Java 9 was, in a number of ways, possibly the most disruptive change to the language, largely due to the introduction of the Java Platform Module System (JPMS), which for the first time enforces the [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":135,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false},"version":2}},"categories":[10],"tags":[],"class_list":["post-134","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-java"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/www.russgold.net\/sw\/wp-content\/uploads\/2018\/04\/puzzle-1713170__340.jpg?fit=645%2C340&ssl=1","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p8ubzQ-2a","jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/www.russgold.net\/sw\/wp-json\/wp\/v2\/posts\/134","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.russgold.net\/sw\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.russgold.net\/sw\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.russgold.net\/sw\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.russgold.net\/sw\/wp-json\/wp\/v2\/comments?post=134"}],"version-history":[{"count":4,"href":"https:\/\/www.russgold.net\/sw\/wp-json\/wp\/v2\/posts\/134\/revisions"}],"predecessor-version":[{"id":141,"href":"https:\/\/www.russgold.net\/sw\/wp-json\/wp\/v2\/posts\/134\/revisions\/141"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.russgold.net\/sw\/wp-json\/wp\/v2\/media\/135"}],"wp:attachment":[{"href":"https:\/\/www.russgold.net\/sw\/wp-json\/wp\/v2\/media?parent=134"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.russgold.net\/sw\/wp-json\/wp\/v2\/categories?post=134"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.russgold.net\/sw\/wp-json\/wp\/v2\/tags?post=134"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}