- What is a Code Kata
- Project Structure
- Java Reflection and recent alternates
- Sun Unsafe and recent alternates
- Solutions to the Katas
- Take Away
Many Java libraries and frameworks currently use Reflection and Unsafe APIs. With the newer modular Java some of these important tools of our trade may become incompatible and/or may not work as desired. In addition several enterprise applications also rely on Core Reflection, (if not the use of Unsafe APIs).
A code-kata is a coding exercise that builds muscle memory by a practice of programming to arrive at a known solution.
The essence of the exercise (presentation material and code kata) is to demonstrate the alternates for the current usage patterns for some of the simpler and more common usages of Java Reflection API and the sun.misc.Unsafe among applications, libraries and frameworks. An explanation of the newer Handles API will be followed with code that allows for a comparison between using both styles.
This set of code katas rely on fixing broken tests. The tests may have multiple solutions, the intent is to learn and experiment.
The project contains several JUnit tests that fail with a message "Test Failure - Fix all TODOs. "
.
Here are simple steps to use this kata:
- Run the test class(es).
- One or more tests will fail with the test failure message, phrased above.
- Fix the failing tests by taking hints from the
TODO
s. - Repeat above steps until all tests pass.
- Check the solutions to see if there are other ways to solve. (Remember, the solution may be less performant than yours)
- Rinse and repeat (delete and checkout again, then back to Step 1) to build muscle memory.
Each test class has two types of test methods:
-
Solved test methods show how an invocation/access can be achieved with the traditional calls.
-
Unsolved/failing test methods provide TODO hints that will allow the kata-taker to manually solve the exercise to achieve the same with MethodHandles/VarHandles.
Your mission, should you choose to accept it, will be to fix the JUnit tests to achieve the same results with the Handles API as the solved one(s) do with traditional reflection. This message will self-destruct in NaN minutes
How to prepare for coding along
This kata is developed as a Java maven project. Ensure that you have:
-
Apache Maven 3.3.x or above. Tested with Apache Maven 3.5.0. Link: https://maven.apache.org/download.cgi
-
JDK 11. Tested with OpenJDK 11 Link: http://jdk.java.net/11/
-
Your favorite Java IDE. IntelliJ IDEA Ultimate was used to develop this kata.
The structure of the project:
|____pom.xml
|____README.md
|
|____src
| |
| |____test <------------------- Kata Tests
| | |____java
| | |____none
| | |____cvg
| | |____constructors
| | |____methods
| | |____variables
| |
| |____main <------------------- Shared ErrorMessages & DemoClass
| | |____java
| | |____none
| | |____cvg
| |
| |____solutions <------------------- Solutions
| | |____java
| | |____none
| | |____cvg
| | |____constructors
| | |____methods
| | |____variables
There are a few JUnit tests with an aim to practice method access alternates to Reflection.
-
This test aims at using MethodHandles to invoke a default constructor on a class in order to create a new instance.
-
This test aims at using MethodHandles to invoke a constructor with a parameter on a class in order to create a new instance.
-
This test aims at using MethodHandles to invoke a public method on a class.
-
This test aims at using MethodHandles to invoke a package-protected (default-access) method on a class.
-
This test aims at using MethodHandles to invoke a protected method on a class.
-
This test aims at using MethodHandles to invoke a private method on a class.
-
This test aims at using MethodHandles to invoke a public static method on a class.
There are a few JUnit tests with an aim to practice variable access alternates to Unsafe.
-
This test aims at showing the differences between traditional reflection/Unsafe usage and the Handles API.
In each of the below: The traditional access test passes, solve the alternate.
public
variables.private
variables.one-dimensional array
variables.two-dimensional array
variables.
-
This test aims at showing the differences between traditional reflection/Unsafe usage and the Handles API.
In each of the below: The traditional access test passes, solve the alternate.
- Using
AtomicReference
- Solved. - Using
AtomicReferenceFieldUpdater
- Solved. - Using
Unsafe
- Solved. - Using
VarHandle
- Unsolved, use theTODO
s to fix.
- Using
-
This test aims at highlighting functionality available with Reflection/Unsafe that no longer are available using VarHandles.
- Modify a
private final
variable using traditional calls - Solved. - Cannot modify a
private final
variable using VarHandles - Unsolved, use theTODO
s to fix. - Modify a
public static final
constant using traditional calls - Solved. - Cannot modify a
public static final
constant using VarHandles - Unsolved, use theTODO
s to fix.
- Modify a
Solutions for each test:
The key take-away from this kata is a solid understanding of the simpler and more common usages of Core Reflection API and Unsafe API alongside the newer Handles API both in similarity and in certain cases, how they differ.
Who knows if your next open source/enterprise contribution is with helping out a library, framework or an enterprise application in converting to the newer APIs ?