IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Spring Java Discussion :

@Autowired ne fonctionne pas -> NullPointerException


Sujet :

Spring Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 42
    Par défaut @Autowired ne fonctionne pas -> NullPointerException
    Bonjour,

    J'ai remarqué que certains sujets traitaient de ce problème mais aucun ne m'a apporté de réponse à mon problème.

    J'essaye d'implémenter l'exemple du livre intitulé "Spring Security" et tout fonctionne bien excepté l'injection des éléments SaltSource et PasswordEncoder que j'ai pourtant définis dans le fichier applicationContext-business.xml comme suit:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
     <bean id="passwordEncoder" class="org.springframework.security.authentication.encoding.Md5PasswordEncoder"/>
        <bean id="saltSource" class="org.springframework.security.authentication.dao.ReflectionSaltSource">
            <property name="userPropertyToUse" value="salt"/>
        </bean>
      <bean id="jdbcUserServiceCustom" class="springsecurity.security.CustomJdbcDaoImpl">
            <property name="dataSource" ref="dataSource"/>
            <property name="enableGroups" value="true"/> 
            <property name="enableAuthorities" value="true"/>
            <property name="usersByUsernameQuery">
                <value>SELECT username, password, enabled, salt FROM users WHERE username = ?</value>
            </property>
        </bean>
    ...
    <context:annotation-config />
        <context:component-scan base-package="springsecurity.security"/>
    J'obtiens un NullPointerExcpetion à l'invocation de la méthode changePassword:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
     
    package springsecurity.security;
     
    //imports...
     
    public class CustomJdbcDaoImpl extends JdbcDaoImpl {
        // Ch 4 Password Encoder and Salt Exercise
     
        @Autowired
        private PasswordEncoder passwordEncoder;// = new Md5PasswordEncoder();
        @Autowired
        private SaltSource saltSource;
        //private ReflectionSaltSource saltSource = new ReflectionSaltSource();
     
        public void changePassword(String username, String password) {
            /*getJdbcTemplate().update(
                    "UPDATE USERS SET PASSWORD = ? WHERE USERNAME = ?",
                    password, username);*/
            // Ch 4 After password encoder and salt exercise using the username
            UserDetails user = loadUserByUsername(username);
            //saltSource.setUserPropertyToUse("salt");
            String encodedPassword = passwordEncoder.encodePassword(password, saltSource.getSalt(user));
            getJdbcTemplate().update("UPDATE USERS SET PASSWORD = ? WHERE USERNAME = ?", encodedPassword, username);
        }
    Voici le fichier applicationContext-Security.xml:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
     <authentication-manager alias="authenticationManager">
            <authentication-provider user-service-ref="jdbcUserServiceCustom">
                <password-encoder ref="passwordEncoder">
                    <salt-source ref="saltSource"/>
                </password-encoder>
            </authentication-provider>
        </authentication-manager>
    Voici le fichier dispatch servlet bank-servlet.xml:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
     
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:jdbc="http://www.springframework.org/schema/jdbc"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
                               http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                               http://www.springframework.org/schema/jdbc
                               http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
                               http://www.springframework.org/schema/context
                               http://www.springframework.org/schema/context/spring-context-3.0.xsd">
        <bean name="/listAccounts.html" class="bigbank.web.ListAccounts">
            <constructor-arg ref="bankService"/>
        </bean>
     
        <bean name="/post.html" class="bigbank.web.PostAccounts">
            <constructor-arg ref="bankService"/>
        </bean>
        <bean id="viewResolver"  class="org.springframework.web.servlet.view.UrlBasedViewResolver">
            <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
            <property name="prefix" value="/WEB-INF/jsp/"/>
            <property name="suffix" value=".jsp"/>
        </bean>
     
        <context:annotation-config />
        <context:component-scan base-package="springsecurity.security"/>
    </beans>
    Voici mon fichier web.xml:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
     
    <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>
                /WEB-INF/applicationContext-business.xml
                /WEB-INF/applicationContext-security.xml
            </param-value>
        </context-param>
        <context-param>
            <param-name>webAppRootKey</param-name>
            <param-value>tutorial.root</param-value>
        </context-param>
        <filter>
            <filter-name>springSecurityFilterChain</filter-name>
            <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
        </filter>
        <filter-mapping>
            <filter-name>springSecurityFilterChain</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
    <listener>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
     <servlet>
            <servlet-name>bank</servlet-name> <!-- reference to bank-servlet.xml-->
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>bank</servlet-name>
            <url-pattern>*.html</url-pattern>
            <url-pattern>*.do</url-pattern>
        </servlet-mapping>
    Et voici l'erreur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    ATTENTION: StandardWrapperValve[bank]: PWC1406: Servlet.service() for servlet bank threw exception
    java.lang.NullPointerException
            at springsecurity.security.CustomJdbcDaoImpl.changePassword(CustomJdbcDaoImpl.java:40)
            at springsecurity.security.AccountController.submitChangePasswordPage(AccountController.java:43)
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    Il n'y a pas d'erreur au déploiement et tout fonctionne sans problème jusqu'à l'exécution de la méthode changePassword. Évidemment tout fonctionne aussi très bien si je contourne les injections en instanciant les objets directement dans le bean. Je tiens aussi a signaler qu'une injection de l'élément CustomJdbcDaoImpl dans le Bean AccountController avec l'annotation @Controller fonctionne elle très bien
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
     
    package springsecurity.security;
     
    //imports
     
    @Controller
    public class AccountController extends BaseController {
     
        @Autowired
        private CustomJdbcDaoImpl changePasswordDao;
     
        @RequestMapping("home.do")
        public void accountHome() {
        }
     
        @RequestMapping(value = "changePassword.do", method = RequestMethod.GET)
        public void showChangePasswordPage() {
            System.out.println("GET submitChangePasswordPage");
        }
     
        @RequestMapping(value = "changePassword.do", method = RequestMethod.POST)
        public String submitChangePasswordPage(@RequestParam("password") String newPassword) {
            Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
     
            String username = principal.toString();
            if (principal instanceof UserDetails) {
                username = ((UserDetails) principal).getUsername();
            }
            System.out.println("USERNAME: "+username+" "+newPassword);
            changePasswordDao.changePassword(username, newPassword);
            SecurityContextHolder.clearContext();
     
            return "redirect:";//nothing means home
        }
    }
    Je vous remercie par avance.

    Bou

  2. #2
    Membre Expert
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 963
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 963
    Par défaut
    Citation Envoyé par Bourrine Voir le message
    Il n'y a pas d'erreur au déploiement et tout fonctionne sans problème jusqu'à l'exécution de la méthode changePassword. Évidemment tout fonctionne aussi très bien si je contourne les injections en instanciant les objets directement dans le bean. Je tiens aussi a signaler qu'une injection de l'élément CustomJdbcDaoImpl dans le Bean AccountController avec l'annotation
    çà ressemble à un problème déjà signalé dans un autre forum mais concernant Spring et Ajax :
    le même symptôme, la cause dans ce cas étant une instantiation hors Spring de la classe réalisant le service (donc finalement 2 instances coexistent et évidemment celle utilisée par Ajax n'est pas injectée).

    Pour au moins vérifier que vous n'êtes pas en face d'un cas similaire pouvez-vous tracer la création de cette classe : par exemple en faisant un overwrite du constructeur et en y ajoutant un Log ou tout autre moyen que vous jugerez adéquat ?
    (mais au moins faites la vérification et éliminez cette hypothèse…)

    L'autre piste étant le mélange d'une bean et de @Autowired :
    je me souviens avoir utilisé sans probléme @Component/@Repository:@Service + @Autowired sur des classes mais alors elles ne sont pas des beans dans le XML ou des beans dans l'XML et @Resource ou équivalent, mais pas avoir jamais tenté le mélange des deux (mais c'est de mémoire…) .

  3. #3
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    le @autowired est pris en compte, meme si le bean est déclaré dans un xml, ce n'est pas incompatible

    Par contre, effectivement, il serait bien de savoir si c'est bien spring qui a instancé votre classe. Le mieux pour être fixé est de faire un

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    new Exception("instanciation").printStrackTrace()
    dans le constructeur du bean en question

Discussions similaires

  1. [Framework] autowired ne fonctionne pas Spring Struts Hibernate
    Par younesms dans le forum Spring
    Réponses: 4
    Dernier message: 08/12/2012, 23h22
  2. Réponses: 1
    Dernier message: 04/11/2009, 15h33
  3. UNION qui ne fonctionne pas
    Par r-zo dans le forum Langage SQL
    Réponses: 7
    Dernier message: 21/07/2003, 10h04
  4. Un Hint sur un PopupMenu ne fonctionne pas !!??
    Par momox dans le forum C++Builder
    Réponses: 6
    Dernier message: 26/05/2003, 16h48
  5. ca ne fonctionne pas (generateur auto-incrémentant)
    Par tripper.dim dans le forum SQL
    Réponses: 7
    Dernier message: 26/11/2002, 00h10

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo