Search code examples
javareflectionprivateencapsulation

Is there a way to read the "private Node root" variable from class Pattern?


I want to write a parser for regex, and it would be an easy task, if i could use the tree from Pattern class.

I tried to use reflection like this:

import org.w3c.dom.Node;
import java.lang.reflect.Field;
import java.util.regex.*;
public class Main
{
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
        Pattern pattern = Pattern.compile("example+");
        Field field_pattern = Pattern.class.getDeclaredField("root");
        field_pattern.setAccessible(true);
        Node fieldValue = (Node) field_pattern.get(pattern);
        
    }

}

but it fails when on

field_pattern.setAccessible(true);

with InaccessibleObjectException

Exception in thread "main" java.lang.reflect.InaccessibleObjectException: Unable to make field transient java.util.regex.Pattern$Node java.util.regex.Pattern.root accessible: module java.base does not "opens java.util.regex" to unnamed module @27d6c5e0

Then I tried to use command line arguments:

--add-opens java.base/java.util.regex=ALL-UNNAMED

(https://www.springcloud.io/post/2022-07/inaccessibleobjectexception/#gsc.tab=0)

but it didn't help.


Solution

  • for '--add-opens' i used launch parameters in Intellij idea.

    I suspected that the problem is that you are incorrectly using your great IDE. This received confirmation in your comment.

    You can easily get confused in IDEA's Run/Debug configuration window. Yours --add-opens java.base/java.util.regex=ALL-UNNAMED parameter is NOT a parameter for your application, which will be passed in String[] args of main method. It's a parameter of Java Virtual Machine. You must convey this parameter string not to your program, but to JVM.

    enter image description here

    You must choose Add VM options in Add run options menu