Search code examples
javafxproguardfxml

Proguard does not process onAction calls in FXML


A lot of my GUI is described in FXML files, and for Buttons and other elements there's an option to set event handler directly from FXML, tied to the method in the controller, set in the same FXML file. So if there's a class view.Controller and there's a method public void foo(), then it looks something like this:

<StackPane fx:controller="view.Controller" xmlns="http://javafx.com/javafx/8.0.121" xmlns:fx="http://javafx.com/fxml/1">
   <children>
      <Button onAction="#foo" />
   </children>
</StackPane>

However, after obfuscation with ProGuard it becomes like this:

<StackPane fx:controller="b.D" xmlns="http://javafx.com/javafx/8.0.121" xmlns:fx="http://javafx.com/fxml/1">
   <children>
      <Button onAction="#foo" />
   </children>
</StackPane>

The foo() in view.Controller gets obfuscated, but the method call in onAction does not. I'm using -adaptresourcefilecontents **.properties,META-INF/MANIFEST.MF,**.xml,**.css,**.fxml parameter for this. There's a similar bug where ProGuard does not obfuscate custom controls, which can be solved by removing the imports in FXML and writing fully qualified paths. This workaround can not be used in this situation, I think. What can be done about it except moving all of onAction from FXML to button.setOnAction() in Java (which is cumbersome and a lot of work)?

I'm using ProGuard 6.0


Solution

  • So in the end I wrote a tiny tool to unpack the jar from ProGuard, rename all onAction calls according to the provided mapping and pack it back to jar again. This is the tool in case anyone needs it (though it's mostly combined from answers on SO and some regex, nothing fancy).