Closing the closed APIs

Earlier this year, Wired published an article stating that, “Oracle has actually opened up Java even more — getting rid of some of the closed-door machinations that used to be part of the Java standards-making process.” This openness comes through OpenJDK and the Java Community Process, where different companies and developers all work together to guide the future of the Java Platform.

Part of opening Java involves dealing with the evolution of internal APIs in the JDK outside the actual Java Language specification and APIs. While developers should not be using internal APIs like sun.* packages, over the course of Java’s 18 year history, various applications have at times used these APIs for different reasons. Use of these implementation-specific, internal APIs poses challenges when they change and may decrease an application’s portability between different Java implementations . Given the ease of obtaining component libraries, we are looking at ways of identifying and mitigating usage of internal APIs in favor of APIs intended for public use.

I will cover several topics in dealing with these internal APIs:

  • Approach in identifying internal APIs
  • Current target: CORBA and Applets/SecurityManager
  • JDeps in Detail

Approach in identifying internal APIs

The definition of “internal API” is any package or class provided by a Java implementation that is not in the public API set. Gearing up for JDK8, OpenJDK contains a new tool called JDeps that is able to locate use of internal APIs within an application’s JAR files or bytecode. By running this tool, you can see which components use internal APIs and which internal APIs they use.

We have run JDeps against a number of applications to figure out popularity of internal APIs and understand any impact.

CORBA and Applets/SecurityManager

Starting in Java 7 update 51 (January 2014), we will move the internal undocumented com.sun.corba.se APIs into a restricted API list. This will affect applications only if they do all of three things:

  1. If your application uses restricted permissions (i.e. sandboxed RIA or runs with a SecurityManager)
  2. AND uses CORBA
  3. AND uses undocumented internal Sun APIs (com.sun.corba.se.*) to do it.

The first attempt at moving internal com.sun.corba.se APIs into a restricted API list came back in June of this year on the OpenJDK mailing list. After more reviews, a better patch was created in October. Beginning with Java 7 update 51, the internal CORBA APIs are entering into a restricted API list. This means that if you have an RIA using this internal API, your application will need the manifest entry "Permissions: all-permissions" and cannot use the sandbox. If your application specifies fine-grained permissions through the SecurityManager, then you will need the "accessClassInPackage.com.sun.corba.se" permission.

  • To see if your code or components use these internal CORBAP APIs, use JDeps and search the output for "com.sun.corba.se"
  • If the above JDeps output says that you are using the undocumented internal APIs, you have two options:
    1. Recommended: Update the code to use javax.rmi.CORBA or org.omg.* APIs instead of the otherwise undocumented internal APIs.
    2. Bide time by either using “Permissions: all-permissions” manifest entry in your applet or obtaining the "accessClassInPackage.com.sun.corba.se" permission from your SecurityManager. Please use any time gained to work on Option A, above.

JDeps in detail

OpenJDK 8 introduces a utility called JDeps that looks through JAR files and identifies which JAR files use internal APIs and then lists those APIs. This answers the questions, “am I using these internal classes” and “if so, which ones.” To use JDeps and check your applications, just download a preview release of JDK8. You do not need to actually test or run your application on JDK8, this just happens to be where the JDeps utility is.

You can then run JDeps on an application even if you do not have the source code.

To run JDeps against an application, the command looks like:

jdk8/bin/jdeps -P -jdkinternals *.jar > your-application.jdeps.txt

The output inside your-application.jdeps.txt will look like:

your.package (Filename.jar)
      -> com.sun.corba.se            JDK internal API (rt.jar)

Comments:

Please add the option "-jdkinternals" to the JDeps page ( http://download.java.net/jdk8/docs/technotes/tools/windows/jdeps.html ), as it's currently undocumented there.

Posted by Anthony Ve on December 12, 2013 at 10:29 AM PST #

Will do. The -jdkinternals flag was added recently (JDK 8 b120) so it's just a case of timing.

Posted by costlow on December 12, 2013 at 12:29 PM PST #

You may also have a look at: https://code.google.com/p/forbidden-apis/

This tool provides this for Maven and Ant projects, together with opportunities to fail the build when certain API signatures are used.

Posted by guest on December 17, 2013 at 05:04 AM PST #

Option --help is announced but doesn't work (build 120):

/usr/local/jdk1.8.0/bin/jdeps --help

Error: unknown option: --help
Usage: jdeps <options> <classes...>
use -h, -? or --help for a list of possible options

Posted by rjung on December 17, 2013 at 07:10 AM PST #

The forbidden-apis is a cool project, thank you for sharing.
Does that have its own source of functions or is it able to share with jdeps? From its blog it appears like it's looking for more (locales, print streams) whereas jdeps is mostly focused on internal API usage.

Posted by costlow on December 17, 2013 at 11:42 AM PST #

Post a Comment:
Comments are closed for this entry.
About

Science Duke
This blog contains topics related to Java SE, Java Security and Usability. The target audience is developers, sysadmins and architects that build, deploy and manage Java applications. Contributions come from the Java SE Product Management team.

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
2
3
4
5
6
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today