Reputation: 13
I try to load a class located in an external jar using classloader. The class "FXMLbase" loads ok, but the error is triggered when the FXMLdocument.fxml try to instantiate the FXMLDocumentController. However when the "FXMLbase" is instantiate throught the JavaFXApplication5.java (located at the external jar) it works fine. Any Ideas?
Class Loader
File file = new File("C:/Users/Os/Dropbox/CODE_OS/JavaFXApplication5/dist/JavaFXApplication5.jar");
URLClassLoader clazzLoader = URLClassLoader.newInstance(new URL[]{file.toURI().toURL()}, this.getClass().getClassLoader());
Class c = clazzLoader.loadClass("javafxapplication5.FXMLbase");
PluginInterface fXMLbase = (PluginInterface) c.newInstance();
Parent loadScreen = fXMLbase.getRoot();
FXMLbase.java -- external jar --
public Parent getRoot() {
Parent root = null;
try {
System.out.println("Class Name:" + getClass().getName());
root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
} catch (IOException ex) {
Logger.getLogger(FXMLbase.class.getName()).log(Level.SEVERE, null, ex);
}
return root;
}
FXMLdocument.fxml -- external jar --
<AnchorPane id="AnchorPane" prefHeight="200" prefWidth="320" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8" fx:controller="javafxapplication5.FXMLDocumentController">
<children>
<Button fx:id="button" layoutX="126" layoutY="90" onAction="#handleButtonAction" text="Click Me! app5" />
<Label fx:id="label" layoutX="126" layoutY="120" minHeight="16" minWidth="69" />
</children>
FXMLDocumentController.java -- external jar --
public class FXMLDocumentController implements Initializable{
@FXML
private Label label;
@FXML
private void handleButtonAction(ActionEvent event) {
System.out.println("You clicked me!");
label.setText("Hello World!");
}
@Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
}
JavaFxApplication5.java -- external jar --
public void start(Stage stage) throws Exception {
FXMLbase fXMLbase=new FXMLbase();
Parent root = fXMLbase.getRoot();
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
Error:
ago 28, 2014 2:26:16 PM javafxapplication5.FXMLbase getRoot
SEVERE: null
javafx.fxml.LoadException:
file:/C:/Users/Os/Dropbox/CODE_OS/JavaFXApplication5/dist/JavaFXApplication5.jar!/javafxapplication5/FXMLDocument.fxml:9
....
Caused by: java.lang.ClassNotFoundException: javafxapplication5.FXMLDocumentController
Upvotes: 1
Views: 3040
Reputation: 209704
The FXMLLoader
at some point has to load the controller class from the value of the fx:controller
attribute in the root element of the FXML file. It looks like it is using the system class loader to do this: I think this is because the system class loader finds the FXMLLoader class and loads it, rather than the class loader used to load your FXMLBase class.
The only fix I can find for this is to explicitly set the controller class from the FXMLbase
class, instead of specifying it in the FXML. This is a bit unsatisfactory; perhaps there is a better way I am missing.
Updated FXMLbase
class:
public Parent getRoot() {
Parent root = null;
try {
System.out.println("Class Name:" + getClass().getName());
FXMLLoader loader = new FXMLLoader(getClass().getResource("FXMLDocument.fxml"));
loader.setController(new FXMLDocumentController());
root = loader.load();
} catch (IOException ex) {
Logger.getLogger(FXMLbase.class.getName()).log(Level.SEVERE, null, ex);
}
return root;
}
and you need to remove the fx:controller
attribute from the FXML file.
Upvotes: 3