This is a good discussion but none of the suggestions satisfy the need I'm 
looking 
for.https://stackoverflow.com/questions/450807/how-do-i-make-the-method-return-type-generic

The example code below shows button0 being added to a VBox. It also shows 
button1 being added to the same VBox only instead of being added directly to 
the list returned by vbox.getChildren(), that is 
vbox.getChildren().add(button1), buttton1 is added via 
reflection/introspection. The end goal is the same in both cases. Add a button. 
The methodology is different. Regardless, this should be trivial. It's not. Why?
In this example, adding button0 produces no compile time warnings, Attempt-1. 
As for the code adding button1, Attempt-3 too produces no compile time warning, 
yet when run produces the WARNINGS shown at the bottom of the code. Commenting 
out Attempt-3 and uncommenting Attempt-2, produces compile time warnings.
The bottom of the code example shows how to compile and run the example.
As is, this code references no illegal reference code and yet still produces 
run time WARNINGS.
Is there a way to access the list returned by getChildren() via reflection so a 
widget can be added without producing the run time WARNINGS? It's not the 
WARNINGS that I'm concerned about. I'm concerned that when future Java releases 
become available this code will fail to work. I would like to find a solution 
so that doesn't happen and this code continues to work.
Maps have similar behavior. Try and use reflection to iterate over a Map, a 
trivial exercise, and it quickly becomes an impossible task. The internal class 
of the Map isn't public making it impossible to iterate through the list. I'm 
assuming that is what we are seeing here as well.
Personally I believe internal classes should never be used. They seem to 
produce more problems than they solve. They are a quick, lazy fix that usually 
results in painful long term support. Besides, internal classes defeat write 
once, run anywhere. If it's internal, it's not being used anywhere else; which 
means the code has no useful value elsewhere; obviously false. That implies the 
code will be duplicated elsewhere to leverage it's functionality, meaning the 
code is now written twice, defeating the montra. Therefore, internal classes 
should never be used. In the same spirit, classes should never be private for 
the same reason. The nice thing is, convention easily satisfies this 
suggestion. Just because you can, doesn't mean you should.
Java has been out for 23 years. Does a solution exist? I would like to see this 
example code work for future releases of Java.
Is there a solution? Would you please point me at an example.
Thanks
---------- BEGIN SOURCE ----------

public class ReflectAccessBug extends javafx.application.Application {

    public static void main(String[] args) {
        launch(args);
    }

    public void start(javafx.stage.Stage stage) {
        javafx.scene.control.Button button0 = new javafx.scene.control.Button();
        javafx.scene.control.Button button1 = new javafx.scene.control.Button();
        javafx.scene.layout.VBox vbox = new javafx.scene.layout.VBox();

        javafx.event.EventHandler<javafx.event.ActionEvent> event = e -> {
            javafx.scene.control.Button b =
                (javafx.scene.control.Button)e.getSource();
            System.err.println(b.getText() + " " + e);
        };

        button0.setText("button0");
        button0.setOnAction(event);

        button1.setText("button1");
        button1.setOnAction(event);

        vbox.getChildren().add(button0);

        // Attempt-1
        // This works as expected.
        //vbox.getChildren().add(button1);

        try {
            // Now let's try adding button1 using introspection ...
            java.lang.reflect.Method m =
                vbox.getClass().getMethod("getChildren", new Class[0]);
            Object o = m.invoke(vbox, new Object[0]);
/*
            // Attempt-2
            // This causes the same runtime warning as Attempt-3
            // and I don't believe it should.
            // Attempt-2 produces a compile time warning.
            // Attempt-3 eliminates the compile time warning.
            javafx.collections.ObservableList<javafx.scene.Node> l =
                (javafx.collections.ObservableList<javafx.scene.Node>)o;
            m = l.getClass().getMethod("add", new Class[] { Object.class, });
            o = m.invoke(l, new Object[] { button1, });
System.err.println("o="+o);
*/
            // Attempt-3
            // This results with the same runtime warning as Attempt-2.
            // I don't believe it should produce this warning and is the
            // point of this exercise.
            // Attempt-3 produces *NO* compile time warning as in Attempt-2.
            // It's not the compile time warning I'm concerned about. It's the
            // runtime warning that is the issue.
            // This code references no illegal reference code and yet still
            // produces a runtime warning. It references
            // "illegal reflective access operations". It's not this code
            // that is illegally accessing reflective code. Lower level code
            // accesses illegal reflective code on behalf of this code.
            m = o.getClass().getMethod("add", new Class[] { Object.class, });
            o = m.invoke(o, new Object[] { button1, });
System.err.println("o="+o);
        } catch (Exception x) {
            x.printStackTrace();
        }

        javafx.scene.Scene scene0 = new javafx.scene.Scene(vbox);
        stage.setScene(scene0);
        stage.show();
    }

}

/*
# compile:
javac ReflectAccessBug.java

# run:
java ReflectAccessBug
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by ReflectAccessBug (...) to method 
com.sun.javafx.collections.VetoableListDecorator.add(java.lang.Object)
WARNING: Please consider reporting this to the maintainers of ReflectAccessBug
WARNING: Use --illegal-access=warn to enable warnings of further illegal 
reflective access operations
WARNING: All illegal access operations will be denied in a future release
*/

---------- END SOURCE ----------
  

Reply via email to