Partage
  • Partager sur Facebook
  • Partager sur Twitter

[Java EE / GlassFish / JPA] NullPointer.

Impossible de dialoguer avec ma base MySQL...

    6 mars 2014 à 19:05:29

    Bonjour à tous,

    Et merci d'avance à qui voudra bien consacrer un peu de temps à mon problème.

    Je suis débutant en Java EE et développe une application web (Dynamic Web Project) sous Eclipse (version Kepler) connectée à une base de données MySQL en mode localhost. J'ai appris à persister mes données avec Tomcat 7 et Hibernate, tout marchait bien. Je suis passé à GlassFish 3.1.2 et EclipseLink. GlassFish démarre bien et déploie mon application. Mais dès la première requête adressée à ma base lors de l'authentification, la console d'eclipse m'affiche une page d'erreur intitulée "HTTP Status 500". Le message : "the server encountered an internal error () that prevented it from fulfilling this request" (description: "java.lang.NullPointerException"). Et voici le détail de l'erreur en console :

    2014-03-06T17:49:02.694+0100|Infos: WEB0671: Loading application [2014] at [/2014]

    2014-03-06T17:49:02.714+0100|Infos: 2014 a été déployé en 3 793 ms.

    2014-03-06T17:49:39.507+0100|Avertissement: StandardWrapperValve[com.pro2014.servlet.EntranceServlet]: PWC1406: Servlet.service() for servlet com.pro2014.servlet.EntranceServlet threw exception

    java.lang.NullPointerException

    at com.pro2014.dao.SecurityDao.idCheck(SecurityDao.java:22)

    at com.pro2014.service.SecurityService.idCheck(SecurityService.java:11)

    at com.pro2014.servlet.EntranceServlet.doPost(EntranceServlet.java:43)

    at javax.servlet.http.HttpServlet.service(HttpServlet.java:688)

    at javax.servlet.http.HttpServlet.service(HttpServlet.java:770)

    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1550)

    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281)

    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)

    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)

    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)

    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161)

    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331)

    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)

    at com.sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.java:317)

    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195)

    at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:860)

    at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:757)

    at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1056)

    at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:229)

    at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)

    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)

    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)

    at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)

    at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)

    at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)

    at com.sun.grizzly.ContextTask.run(ContextTask.java:71)

    at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)

    at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)

    at java.lang.Thread.run(Thread.java:744)

    Après avoir cherché sur plusieurs tutoriels et forums depuis 1 semaine sans succès, je ne sais pas d'où vient l'erreur (ou les erreurs). Voici quelques infos :

    • GlassFish 3.1.2 est installé à la racine de C: et reconnu en tant que serveur par Eclipse
    • ma base de données est en MySQL, je l'administre avec PhpMyAdmin dans Wamp
    • j'ai créé le pool de connexions BoneCP et exécuté la commande "add-resources bonecp-datasource.xml" dans le asadmin de GlassFish avec succès
    • ajouté les jar mysql-connector-java.5.1.18-bin + slf4j-api-1.6.6 + guava-13.0.1 + bonecp-0.7.1.RELEASE dans le dossier domain1/lib/ext de GlassFish ainsi que dans le Build Path du projet Eclipse et dans le WEB-INF/lib
    • créé le fichier persistence.xml dans le dossier src/META-INF de mon projet en renseignant une unité de persistence et en intégrant toutes mes classes entité
      <?xml version="1.0" encoding="UTF-8"?>
      <persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://java.sun.com/xml/ns/persistence 
       http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
      <persistence-unit name="pro2014_PU" transaction-type="JTA">
          <jta-data-source>jdbc/bonecp_resource</jta-data-source>
          <class>com.pro2014.entity.Account</class>
          <class>com.pro2014.entity.Action</class>
          <class>com.pro2014.entity.Activity</class>
          <class>com.pro2014.entity.Association</class>
          <class>com.pro2014.entity.Avatar</class>
          <class>com.pro2014.entity.Bloc</class>
          <class>com.pro2014.entity.Book</class>
          <class>com.pro2014.entity.Calculi</class>
          <class>com.pro2014.entity.Chapter</class>
          <class>com.pro2014.entity.Comment</class>
          <class>com.pro2014.entity.GeoPlace</class>
          <class>com.pro2014.entity.Image</class>
          <class>com.pro2014.entity.Item</class>
    •  <properties>
    •  <property name="eclipselink.logging.level.sql" value="FINE"/>
    •             <property name="eclipselink.logging.parameters" value="true"/>
              </properties>
      </persistence-unit>
      </persistence>
    • le fichier glassfish-web.xml dans le dossier WEB-INF 
      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE glassfish-web-app PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Servlet 3.0//EN" "http://glassfish.org/dtds/glassfish-web-app_3_0-1.dtd">
      <glassfish-web-app>
        <context-root>/2014</context-root>
        <class-loader delegate="true"/>
        <jsp-config>
          <property name="keepgenerated" value="true">
            <description>Conserve une copie du code des servlets auto-générées.</description>
          </property>
        </jsp-config>
      </glassfish-web-app>

    • voici ma servlet d'authentification (qui fonctionnait avec Tomcat et Hibernate) 
      package com.pro2014.servlet;
      import com.pro2014.entity.User;
      import com.pro2014.service.*;
      import java.io.IOException;
      import javax.servlet.ServletException;
      import javax.servlet.annotation.WebServlet;
      import javax.servlet.http.HttpServlet;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      import javax.servlet.http.HttpSession;
      
      /**
       * Servlet implementation class Entrance
       */
      @WebServlet("/EntranceServlet")
      public class EntranceServlet extends HttpServlet {
      	private static final long serialVersionUID = 1L;
      	
          /**
           * @see HttpServlet#HttpServlet()
           */
          public EntranceServlet() {
              super();
              // TODO Auto-generated constructor stub
          }
      
      	/**
      	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
      	 */
      	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
      		// get user mail & password from index.jsp -> already registered user form 
      		String regmail = "";
      		String regpass = "";
      		HttpSession http = null;
      		User user = null;
      				
      		regmail = request.getParameter("regmail");
      		regpass = request.getParameter("regpass");
      		
      		if(regmail!="" && regpass!="")
      		{	
      			if(SecurityService.idCheck(regmail, regpass)!=null)
      			{	
      					user = SecurityService.idCheck(regmail, regpass);
      					http = request.getSession();
      					http.setAttribute("user", user);
      					response.sendRedirect("welcome.jsp");
      			}
      			else {response.sendRedirect("index.jsp");}
      		}
      		else {response.sendRedirect("index.jsp");}
      	}
      }

    • voici mon entité 
      package com.pro2014.entity;
      import javax.persistence.Column;
      import javax.persistence.Entity;
      import javax.persistence.GeneratedValue;
      import javax.persistence.GenerationType;
      import javax.persistence.Id;
      import javax.persistence.JoinColumn;
      import javax.persistence.OneToOne;
      import javax.persistence.Table;
      
      @Entity
      @Table(name="security")
      public class Security {
      		
      	//Attributes
      	@Id
      	@GeneratedValue(strategy=GenerationType.AUTO)
      	@Column
      	private int idSecurity;
      
      	@OneToOne
      	@JoinColumn(name="securityUser", referencedColumnName="idUser")
      	private User securityUser;
      
      	@Column
      	private String securityEmail;
      	
      	@Column
      	private String securityPassword;
      
      	//Constructor
      	public Security(User securityUser, String securityEmail, String securityPassword) {
      		super();
      		this.securityUser = securityUser;
      		this.securityEmail = securityEmail;
      		this.securityPassword = securityPassword;
      	}	
      	
      	public Security() {
      		super();
      	}
      
      	//Methods
      	public int getIdSecurity() {
      	return idSecurity;
      	}
      
      	public void setIdSecurity(int idSecurity) {
      	this.idSecurity = idSecurity;
      	}
      
      	public String getSecurityEmail() {
      		return securityEmail;
      	}
      
      	public void setSecurityEmail(String securityEmail) {
      		this.securityEmail = securityEmail;
      	}
      
      	public User getSecurityUser() {
      		return securityUser;
      	}
      
      	public void setSecurityUser(User securityUser) {
      		this.securityUser = securityUser;
      	}
      
      	public String getSecurityPassword() {
      		return securityPassword;
      	}
      
      	public void setSecurityPassword(String securityPassword) {
      		this.securityPassword = securityPassword;
      	}
      
      }
      

    • voici mon service 
      package com.pro2014.service;
      import com.pro2014.dao.SecurityDao;
      import com.pro2014.entity.*;
      
      public class SecurityService {
      
      	public static User idCheck(String regmail, String regpass)
      	{
      		User user = null;
      		
      		if(SecurityDao.idCheck(regmail, regpass)!=null)
      		{
      			user = SecurityDao.idCheck(regmail, regpass);
      		}
      		
      		return user;
      	}
      

    • voici mon dao stateless 
      package com.pro2014.dao;
      import javax.ejb.Stateless;
      import javax.persistence.EntityManager;
      import javax.persistence.PersistenceContext;
      import javax.persistence.Query;
      import com.pro2014.entity.Security;
      import com.pro2014.entity.User;
      
      @Stateless
      public class SecurityDao {
      
      	@PersistenceContext(unitName="pro2014_PU")
      	private static EntityManager em;
      
      	public static User idCheck(String regmail, String regpass)
      	{
      		User user = null;
      		Security secure = null;
      		
      		Query q = em.createQuery("SELECT security FROM Security security WHERE security.securityEmail=:regmail AND security.securityPassword=:regpass");
      		q.setParameter("regmail", regmail);
      		q.setParameter("regpass", regpass);
      		
      		if(q.getSingleResult()!=null)
      		{
      			secure = (Security) q.getSingleResult();
      		}
      		user = secure.getSecurityUser();
      		return user;
      	}
      

    • Enfin, quand je teste mon code avec un mauvais username/password de connexion à la base de données jdbc:mysql://localhost:3306/pro2014 dans le fichier de configuration domain.xml de glassfish, Eclipse me renvoie bien une erreur d'accès interdit, donc je crois que la connexion à la base fonctionne...
    Voilà, je pense vous avoir donné tous les détails de mon cas. Je ne sais pas si c'est une erreur de code ou de configuration (ou les 2) et vous demande un coup de main car je n'arrive plus à avancer... Merci beaucoup.
    • Partager sur Facebook
    • Partager sur Twitter
    Anonyme
      6 mars 2014 à 19:35:44

      regpass est null?
      • Partager sur Facebook
      • Partager sur Twitter
        6 mars 2014 à 19:44:23

        Non, c'est le mot de passe récupéré dans le formulaire d'authentification
        • Partager sur Facebook
        • Partager sur Twitter
          6 mars 2014 à 19:44:27

          SetParameter ne throw pas de NPE à priori. De plus l'exception s'arrête à la classe SecurityDAO :/ Les lignes ne matchent peut-être pas celles de son eclipse ?

          Sinon ça:

          if(regmail!=""&& regpass!="")

          c'est pas bon du tout !

          if(!"".equals(regmail)&& !"".equals(regpass))

          • Partager sur Facebook
          • Partager sur Twitter
            6 mars 2014 à 19:47:14

            Merci Olivier, je rectifie mon if() même si le nullpointer vient d'ailleurs. Une idée de solution à ce problème ?

            -
            Edité par éé 6 mars 2014 à 19:54:22

            • Partager sur Facebook
            • Partager sur Twitter
              6 mars 2014 à 20:09:51

              Autre info : j'utilise aussi une classe Main juste pour tester la persistence d'objets instanciés avec leurs constructeurs : ça marchait avec Tomcat et Hibernate, mais là, dès la première requête ligne 24, j'ai encore une NullPointerException : 
              package com.pro2014.entity;
              import javax.ejb.Stateless;
              import javax.persistence.EntityManager;
              import javax.persistence.PersistenceContext;
              
              @Stateless
              public class MainTest {
              
              	@PersistenceContext(unitName="pro2014_PU")
              	private static EntityManager em;
              	
              	public static void main(String[] args) {
              		
              		World world = new World("Reality");
              		Post p = new Post("ceci est un test");
              		User ee = new User("ee");
              		Security sec = new Security(ee, "ee@yahoo.com", "eepass");
              		Avatar av = new Avatar("eeAvatar", "self", ee, world, "man");
              		ee.setUserCurrentAvatar(av);
              		Item itm = new Item(ee, av, p);
              		Story story = new Story(ee);
              		ee.setUserSelfStory(story);
              				
              		em.persist(world);
              		em.persist(p);
              		em.persist(ee);
              		em.persist(av);
              		em.persist(story);
              		em.persist(sec);
              		em.persist(itm);
              	}
              }
              Le problème est vraiment lié au dialogue avec la base de données...
              • Partager sur Facebook
              • Partager sur Twitter
              Anonyme
                6 mars 2014 à 21:14:43

                Dans ton dernier exemple, le soucis est que ton entity manager n'est pas initialisé.

                tu passes par un main, donc pas par le contexte managé, le conteneur n'existe pas et donc les objets ne sont plus créés "par magie".

                • Partager sur Facebook
                • Partager sur Twitter
                  6 mars 2014 à 21:54:35

                  Merci pour cette précision Shakhal, ok donc le Main de test ne sert pas à grand chose du coup...
                  • Partager sur Facebook
                  • Partager sur Twitter
                  Anonyme
                    6 mars 2014 à 21:58:35

                    si, mais il faut instancier tes objets à la main(ou du moins un conteneur spring qui va s'occuper du reste si tu veux)
                    • Partager sur Facebook
                    • Partager sur Twitter
                      6 mars 2014 à 23:02:38

                      Ok je ne connais pas encore Spring, je vais me documenter.

                      • Qu'est-ce qui délimite le "contexte managé" ?
                      • Quand tu dis "instancier tes objets à la main", est-ce que ça veut dire de ne plus déclarer en static mes services et dao ? ou est-ce que c'est juste pour le EntityManager du main de test ?
                      • Une idée de la cause du problème initial ?
                      Merci encore pour ton aide.

                      -
                      Edité par éé 6 mars 2014 à 23:11:34

                      • Partager sur Facebook
                      • Partager sur Twitter
                      Anonyme
                        7 mars 2014 à 0:12:23

                        -un conteneur qui se charge du cycle de vie des objets.

                        -j'avais meme pas vu que c'etait en static, on en a pendu pour moins que ça.

                        tu utilises des annotations jee sans être dans un conteneur, il ne peut pas processer tes annotations par magie.

                        -oui, le static n'est pas une bonne idée, ça se marie très mal avec l'injection de dépendance.

                        • Partager sur Facebook
                        • Partager sur Twitter
                          7 mars 2014 à 0:36:30

                          Merci pour tes réponses Shakhal,

                          je vais revoir le code sans static et étudier le conteneur spring. Je publierai demain si ça a marché ou pas.

                          • Partager sur Facebook
                          • Partager sur Twitter

                          [Java EE / GlassFish / JPA] NullPointer.

                          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                          × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                          • Editeur
                          • Markdown