Triangle amoureux déroutant entre JavaFx, Maven et JPA

Fermé
stevyal Messages postés 25 Date d'inscription mardi 11 mars 2008 Statut Membre Dernière intervention 19 mai 2023 - Modifié le 19 mai 2023 à 08:34
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 - 19 mai 2023 à 21:55


Bonjour à tous les compaires. j'ai décidé de laisser tomber swing pour JAVAFX du moins pour ce qui est des interfaces graphiques.
Pour ce faire, j'ai alors adopté la même architecture à avoir pour une application multi modules avec l'aide de maven:
- le module des classes métiers que j'appelle model
- le module DAO (data access object) qui gère les interactions avec la base de données
- le module service qui ecapsules les services de l'application
- le module IHM pour les interfaces graphiques totalement conçu en javaFX

* les dépendances sont les suiventes:
le module DAO est dépendant du module model
le module service est à la fois dépendant du modèle et de la dao
le module IHM dépend du modèle, de la DAO et du service.

La persistance des données est faite avec JPA implémenté par TopLinck et la base de donnée est H2

Lorsque j'exécute l'application j'ai une tonne de message erreur.

pour mieux illustrer mon problème voici le code qui pour des besoins de simplicité est allégé.

// le modèle



@Entity
public class MemoDomain{
	@Version
    private Long version;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "entity_id", nullable = false, updatable = false, unique = true)
    private Long id;

    @Column(name = "entity_name", length = 100, nullable = false, updatable = true)
    private String entityName;

    @Column(columnDefinition = "mediumtext", nullable = true, updatable = true)
    private String description;

    @Column(columnDefinition = "date", name = "creation_date", nullable = false, updatable = false)
    @Convert(converter = DateAttributeConverter.class)
    private LocalDate creationDate;
	
	public MemoDomain(String entityName, String description){
		this.entityName = entityName;
        this.description = description;
	}

	//getters, setters equals hashCode and toString methods
	
}


// la dao

public class H2DBConnectionProvider implements DatabaseConnectionProvider {

    private static H2DBConnectionProvider instance;
    private static final Object VERROU = new Object();

    private static EntityManagerFactory emf;
    private EntityManager memoryHelpEntitymanager;

    public H2DBConnectionProvider() {
        initEmf();       
    }



    private void initEmf() {
        emf = Persistence.createEntityManagerFactory(JpaConfig.PERSISTENCE_UNIT_NAME);
    }
    
    private void initEmf(String persistenceUnitName) {
        emf = Persistence.createEntityManagerFactory(persistenceUnitName);
    }

    public static H2DBConnectionProvider getInstance() {
        if (instance == null) {
            synchronized (VERROU) {
                instance = new H2DBConnectionProvider();
            }
        }
        return instance;
    }

    @Override
    public EntityManager provideEntityManager() throws NoConnectionException {
        if (Objects.isNull(memoryHelpEntitymanager)) {
            throw new NoConnectionException("There is no database connection!");
        } else {
            return memoryHelpEntitymanager;
        }
    }

    @Override
    public boolean getConnectedToDb() {
        createEntityManager();
        return !Objects.isNull(memoryHelpEntitymanager);
    }
    
    @Override
    public boolean getConnectedToDb(String puName) {
        createEntityManager(puName);
        return !Objects.isNull(memoryHelpEntitymanager);
    }

    private void createEntityManager(String puName) {
        try {
            initEmf(puName);
            if (emf != null) {
                memoryHelpEntitymanager = emf.createEntityManager();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    private void createEntityManager() {
        try {
            initEmf();
            if (emf != null) {
                memoryHelpEntitymanager = emf.createEntityManager();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public boolean isConnectedToDb(){
        return !Objects.isNull(memoryHelpEntitymanager);
    }
}


public interface Dao<T extends Object, ID extends Serializable> {

 
    public T createEntity(T newEntity) throws Exception, DuplicateEntryException;

    public T readEntity(ID entityId) throws SQLException;


    public T updateEntity(T entity) throws Exception;

 
    public T deleteEntity(T entity) throws Exception;


    public boolean entityExist(String entityName) throws SQLException;

 
    public List<T> readAll() throws SQLException;
}

public interface GenericEntityDao<T extends GenericEntity, ID extends Serializable> extends Dao<T, ID> {
    public void setDatabaseConnectionProvider(DatabaseConnectionProvider connectionProvider);
}
//implementation
public abstract class GenericEntityDaoImpl<T extends GenericEntity, ID extends Serializable> implements GenericEntityDao<T, ID> {

    protected Class<T> entityClass;
    protected DatabaseConnectionProvider databaseConnectionProvider;
    protected EntityManager entityManager;
    /**
     *
     * @param entityClass
     * @param databaseConnectionProvider
     */
    public GenericEntityDaoImpl(Class<T> entityClass, DatabaseConnectionProvider databaseConnectionProvider) {
        super();
        this.entityClass = entityClass;
        this.databaseConnectionProvider = databaseConnectionProvider;             
    }

    @Override
    public T createEntity(T newEntity) throws Exception, DuplicateEntryException {
        
        entityManager = databaseConnectionProvider.provideEntityManager();
        entityManager.getTransaction().begin();
        try {
            entityManager.persist(newEntity);             
            entityManager.flush();
            entityManager.getTransaction().commit();
            entityManager.refresh(newEntity);
        } catch (Exception e) {
            entityManager.getTransaction().rollback();
            Logger.getLogger(GenericEntityDaoImpl.class.getName()).log(Level.SEVERE, null, e);
        } finally {
            entityManager.close();
        }
        return newEntity;
    }

    @Override
    public T readEntity(ID entityId) throws SQLException {
        T entity = null;
        entityManager = (EntityManager) databaseConnectionProvider.provideEntityManager();
        try {
            entity = entityManager.find(entityClass, entityId);
        } catch (Exception ex) {
            Logger.getLogger(GenericEntityDaoImpl.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            entityManager.close();
        }
        return entity;
    }

    @Override
    public T updateEntity(T entity) throws Exception {
        T updatedEntity = null;
        entityManager = (EntityManager) databaseConnectionProvider.provideEntityManager();
        try {
            entityManager.getTransaction().begin();
            updatedEntity = entityManager.merge(entity);
            
            entityManager.flush();
            entityManager.getTransaction().commit();
        } catch (Exception e) {
            entityManager.getTransaction().rollback();
            Logger.getLogger(GenericEntityDaoImpl.class.getName()).log(Level.SEVERE, null, e);
        } finally {
            entityManager.close();
        }
        return updatedEntity;
    }

    @Override
    public T deleteEntity(T entity) throws Exception {
        entityManager = (EntityManager) databaseConnectionProvider.provideEntityManager();
        try {
            entityManager.getTransaction().begin();
            entityManager.merge(entity);
            entityManager.remove(entity);
            entityManager.flush();           
            entityManager.getTransaction().commit();             
        } catch (Exception e) {
            entityManager.getTransaction().rollback();
            Logger.getLogger(GenericEntityDaoImpl.class.getName()).log(Level.SEVERE, null, e);
        } finally {
            entityManager.close();
        }
        return entity;
    }

    @Override
    public boolean entityExist(String entityName) throws SQLException {
        boolean exists = false;
        try {
            entityManager = databaseConnectionProvider.provideEntityManager();
            Query query = entityManager.createNamedQuery("findByName");
            query.setParameter("entityName", entityName);
            List<T> resultList = query.getResultList();
            exists = !resultList.isEmpty();
        } catch (NoConnectionException e) {
            Logger.getLogger(GenericEntityDaoImpl.class.getName()).log(Level.SEVERE, null, e);
        }
        return exists;
    }

    @Override
    public List<T> readAll() {
        entityManager = (EntityManager) databaseConnectionProvider.provideEntityManager();
        TypedQuery<? extends T> query;
        query = entityManager.createQuery("SELECT entity FROM GenericEntity entity ORDER BY entity.entityName ASC", entityClass);
        List<T> entityList = (List<T>) query.getResultList();
        entityList.sort(Comparator.naturalOrder());
        return entityList;
    }

    
    @Override
    public void setDatabaseConnectionProvider(DatabaseConnectionProvider connectionProvider){
        this.databaseConnectionProvider = connectionProvider;
    }
}


public interface DomainDao<T extends MemoDomain> extends GenericEntityDao<T, Long> {

}

public class DomainDaoImpl<T extends MemoDomain> extends MemoryHelpHeaderDaoImpl<T> implements DomainDao<T> {

    /**
     * Default Constructor
     *
     * @param entityClass
     * @param connectionProvider
     */
    public DomainDaoImpl(Class<T> entityClass, DatabaseConnectionProvider connectionProvider) {
        super(entityClass, connectionProvider);
    }


}


/* le controlleur de l'ihm */

public class MemoryHelp extends Application {

    private Stage mainStage;
    private DatabaseConnectionProvider connectionProvider;
    private MemoryHelpDataModel dataModel;

    @Override
    public void start(Stage primaryStage) throws IOException {
        this.mainStage = primaryStage;
        Rectangle2D screenSize = Screen.getPrimary().getVisualBounds();
        mainStage.setMaxWidth(screenSize.getWidth());
        mainStage.setMaxHeight(screenSize.getHeight());
        mainStage.setMinWidth(screenSize.getWidth());
        mainStage.setMinHeight(screenSize.getHeight());
        mainStage.setTitle("Application");

        Parent rootNode = loadFXML("MainView");
        mainStage.setScene(new Scene(rootNode));
        mainStage.sizeToScene();
        mainStage.getIcons().add(new Image(MemoryHelp.class.getResourceAsStream("/imgs/icon.png")));
        mainStage.setOnCloseRequest(event -> {
            event.consume();
            Optional<ButtonType> option = MHDialog.getConfirmationBox("Souhaitez-vous quitter l'application?");
            if (option.get() == ButtonType.YES) {
                mainStage.hide();
            }
        });
        mainStage.show();
    }


    private Parent loadFXML(String fxml) throws IOException {
        URL fxmlLocation = MemoryHelp.class.getResource("/fxml/" + fxml + ".fxml");
        ResourceBundle resources = ResourceBundle.getBundle("i18n.application");

        FXMLLoader fxmlLoader = new FXMLLoader();
        fxmlLoader.setLocation(fxmlLocation);
        fxmlLoader.setResources(resources);
        Parent root = fxmlLoader.load(); 

        MainController mainController = (MainController) fxmlLoader.getController();
      
        if(dataModel == null){
            try {
                dataModel = new MemoryHelpDataModel(null);
            } catch (SQLException ex) {
                Logger.getLogger(MemoryHelp.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

        return root;
    }

    public static void main(String[] args) {
        launch();
    }
    
    @Override
    public void init()throws NoSuchMethodException {
        initDataModel();        
    }
    
    
    public Stage getMainStage(){
        return this.mainStage;
    }
    
    private void initDataModel(){
        connectionProvider = new H2DBConnectionProvider();
		connectionProvider.getConnectedToDb();
        try {
            this.dataModel = new DataModel(connectionProvider);
        }catch(SQLException e){
            Logger.getLogger(Application.class.getName()).log(Level.SEVERE, null, e);
        }
    }
    

    public MemoryHelpDataModel getDataModel() {
        if(dataModel == null){
            initDataModel();
        }
        return dataModel;
    }
}


//


Lorsque je teste l'accès à la bae de données dans un module autre que celui réservé à javaFx tout va bien

le message erreur est le suivant:

Exception in Application init method
java.lang.reflect.InvocationTargetException
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at javafx.graphics@20/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:464)
    at javafx.graphics@20/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:363)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:1082)
Caused by: java.lang.RuntimeException: Exception in Application init method
    at javafx.graphics@20/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:888)
    at javafx.graphics@20/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:195)
    at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: java.lang.NoClassDefFoundError: java/lang/instrument/ClassFileTransformer
    at org.eclipse.persistence.jpa@2.7.10/org.eclipse.persistence.jpa.PersistenceProvider.getInitializer(PersistenceProvider.java:277)
    at org.eclipse.persistence.jpa@2.7.10/org.eclipse.persistence.jpa.PersistenceProvider.createEntityManagerFactory(PersistenceProvider.java:190)
    at java.persistence@2.2/javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:79)
    at java.persistence@2.2/javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:54)
    at Dao@1.0-SNAPSHOT/com.lifesoft.memoryhelp.dao.database.H2DBConnectionProvider.initEmf(H2DBConnectionProvider.java:37)
    at Dao@1.0-SNAPSHOT/com.lifesoft.memoryhelp.dao.database.H2DBConnectionProvider.createEntityManager(H2DBConnectionProvider.java:87)
    at Dao@1.0-SNAPSHOT/com.lifesoft.memoryhelp.dao.database.H2DBConnectionProvider.getConnectedToDb(H2DBConnectionProvider.java:65)
    at com.lifesoft.memoryhelp.gui/com.lifesoft.memoryhelp.gui.application.MyApplication.initDataModel(MyApplication.java:154)
    at com.lifesoft.memoryhelp.gui/com.lifesoft.memoryhelp.gui.application.MyApplication.init(MyApplication.java:111)
    at javafx.graphics@20/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:817)
    ... 2 more
Caused by: java.lang.ClassNotFoundException: java.lang.instrument.ClassFileTransformer
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
    ... 12 more
Exception running application com.lifesoft.memoryhelp.gui.application.MyApplication
Command execution failed.
org.apache.commons.exec.ExecuteException: Process exited with an error: 1 (Exit value: 1)
    at org.apache.commons.exec.DefaultExecutor.executeInternal (DefaultExecutor.java:404)
    at org.apache.commons.exec.DefaultExecutor.execute (DefaultExecutor.java:166)
    at org.openjfx.JavaFXBaseMojo.executeCommandLine (JavaFXBaseMojo.java:553)
    at org.openjfx.JavaFXBaseMojo.executeCommandLine (JavaFXBaseMojo.java:420)
    at org.openjfx.JavaFXRunMojo.execute (JavaFXRunMojo.java:105)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:137)
    at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute2 (MojoExecutor.java:370)
    at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute (MojoExecutor.java:351)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:215)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:171)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:163)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
    at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:298)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
    at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105)
    at org.apache.maven.cli.MavenCli.execute (MavenCli.java:960)
    at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:293)
    at org.apache.maven.cli.MavenCli.main (MavenCli.java:196)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:77)
    at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke (Method.java:568)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:282)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:225)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:406)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:347)
org.apache.commons.exec.ExecuteException: Process exited with an error: 1 (Exit value: 1)
    at org.apache.commons.exec.DefaultExecutor.executeInternal(DefaultExecutor.java:404)
    at org.apache.commons.exec.DefaultExecutor.execute(DefaultExecutor.java:166)
    at org.openjfx.JavaFXBaseMojo.executeCommandLine(JavaFXBaseMojo.java:553)
    at org.openjfx.JavaFXBaseMojo.executeCommandLine(JavaFXBaseMojo.java:420)
    at org.openjfx.JavaFXRunMojo.execute(JavaFXRunMojo.java:105)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:137)
    at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute2(MojoExecutor.java:370)
    at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute(MojoExecutor.java:351)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:215)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:171)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:163)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:117)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:81)
    at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:56)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:128)
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:298)
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:192)
    at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:105)
    at org.apache.maven.cli.MavenCli.execute(MavenCli.java:960)
    at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:293)
    at org.apache.maven.cli.MavenCli.main(MavenCli.java:196)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:282)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:225)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:406)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:347)


 


Windows / Chrome 113.0.0.0

1 réponse

KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
19 mai 2023 à 21:55

Bonjour,

L'exception peut être lié à un oubli de module, ClassFileTransformer est dans le module java.instrument, à configurer dans le fichier module-info.java

Remarque : sur l'architecture de l'application cela semble une mauvaise idée d'avoir le client JavaFX qui appelle directement la base de données, cela signifie que tous les clients auront les user/password de la base de données configurés dans leur logiciel, en terme de sécurité il vaudrait mieux passer par un serveur intermédiaire qui sera le seul à accéder à la base de données.


0