JAVAFX: Ubicación no configurada error

Mi proyecto se ejecuta correctamente en eclipse, pero cuando estoy creando un archivo jar de este proyecto y tratando de ejecutarlo a través de cmd, aparece el error “La ubicación no está configurada”.

Mi estructura de proyecto es:

Esta es la estructura de mi proyecto

El método es (Corriendo en eclipse):

@FXML private void RegularCustomer(ActionEvent event) throws Exception{ Stage stage = (Stage) dailySales.getScene().getWindow(); Scene scene = dailySales.getScene(); FXMLLoader loader = new FXMLLoader(getClass().getResource("../customer/CustomerHome.fxml")); System.out.println(loader.getLocation()); scene.setRoot(loader.load()); stage.setScene(scene); stage.show(); } 

¿Qué está mal con este código?

Hay algunas preguntas relativas pero son diferentes de eso. Su código no se ejecutó en IDE, pero mi código se ejecuta en IDE.

FYI: Hice algunos cambios en la estructura de la carpeta y pude ejecutar con éxito. Pero esa estructura era horrible porque puse todos mis archivos y controladores FXML en el mismo paquete.

Cuando utiliza getClass().getResource(...) está cargando un recurso, no especificando una ruta a un archivo. En el caso donde el cargador de clases carga clases desde el sistema de archivos, estas esencialmente equivalen a lo mismo, y realmente funciona (aunque incluso entonces no hay una razón técnica para hacerlo). Cuando el cargador de clases está cargando clases por otros mecanismos (y probablemente en todos los casos de todos modos), entonces es importante prestar atención a las especificaciones de Java para un recurso .

En particular, nota:

Recursos, nombres y contextos

Un recurso se identifica mediante una cadena que consta de una secuencia de subcadenas, delimitada por barras inclinadas (/), seguida de un nombre de recurso. Cada subcadena debe ser un identificador de Java válido. El nombre del recurso es de la forma shortName o shortName.extension. Tanto shortName como la extensión deben ser identificadores de Java.

(Mi énfasis.) Como .. no es un identificador de Java válido, no hay garantía de que este recurso se pueda resolver. Sucede que el cargador de clases del sistema de archivos resuelve esto de la manera esperada, por lo que funciona en su IDE, pero la implementación de getResource(...) en el cargador de clases jar no implementa esto de la manera en que espera .

Tratar

 FXMLLoader loader = new FXMLLoader(getClass().getResource("/sm/customer/CustomerHome.fxml")); 

Usar ubicaciones de controlador para cargar FXML:

Como ha organizado su código para que cada FXML esté en el mismo paquete que su archivo controlador correspondiente (que creo que es una forma sensata de hacer las cosas), también puede aprovechar esto al cargar el FXML: simplemente cargue el FXML “relativo a su controlador “:

 FXMLLoader loader = new FXMLLoader(CustomerHomeCtrl.class.getResource("CustomerHome.fxml")); 

Esto parece bastante natural en esta configuración, y el comstackdor comprobará que tiene el nombre del paquete para CustomerHomeCtrl correcto en el punto donde importa la clase. También facilita la refactorización: por ejemplo, suponga que desea dividir sm.admin en varios subpaquetes. En Eclipse crearía los subpaquetes, arrastrar y soltar el FXML y los controladores a los subpaquetes correspondientes, y las declaraciones de importación se actualizarían automáticamente: no se necesitarían más cambios. En el caso en que la ruta se especifique en getResource(...) , todos ellos deberían cambiarse a mano.