3

I know a lot of questions are already on StackOverflow about this but I have been struggling for over 5 hours now and I just don't know what to do anymore. I hope when someone sees my situation they can point me in the right direction. I think I've tried every single annotation combo and I can't get it to work.

I am setting up a Java EE application, simple web-app. Currently testing my setup in a simple page. The related files are below. The error occurs when pressing on the button on the xhtml page.

javax.el.PropertyNotFoundException: /greeting.xhtml @12,69 action="#{testServlet.createNewUser}": Target Unreachable, identifier 'testServlet' resolved to null

greeting.xhtml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html">
    <h:head>
        <title>Test Page</title>
    </h:head>
    <h:body>
        <h:form>
            <h:commandButton value="Go"
                             action="#{testServlet.createNewUser}"/>
        </h:form>

    </h:body>
</html>

TestServlet.java

package kwetter.admin.test;

import java.io.Serializable;
import javax.enterprise.context.SessionScoped;
import javax.inject.Inject;
import javax.inject.Named;
import kwetter.domain.entities.User;
import kwetter.logic.beans.TestBean;

@Named
@SessionScoped
public class TestServlet implements Serializable {

    @Inject
    private TestBean testBean;

    public TestServlet() {
        System.out.println("TEST CREATED ");
    }

    public String createNewUser() {
        User user = new User();
        testBean.createUser(user);

        return "cool";
    }

}

TestBean.java

package kwetter.logic.beans;

import java.io.Serializable;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import kwetter.database.daos.interfaces.IUserDao;
import kwetter.domain.entities.User;

@Stateless
public class TestBean implements Serializable
{

    @EJB
    private IUserDao userDao;

    public TestBean() {

    }

    public boolean createUser(User user) {
        userDao.save(user);
        return true;
    }
}

IUserDao declaration

public interface IUserDao extends IDao<User>

And the implemenatation:

@Stateless
public class UserDao implements IUserDao

Dependencies of the different modules are handled in the pom files. Example part of the pom:

    <dependency>
        <groupId>com.woutervanacht.kwetter</groupId>
        <artifactId>logic</artifactId>
        <version>1.0-SNAPSHOT</version>
        <scope>provided</scope>
    </dependency>

Other:

  • I have an empty beans.xml in WEB-INF (not sure if this is needed anymore, started without and read it a couple of times
  • faces-config.xml which has no childs in the root element
  • web.xml with servlet mapping.

I don't want to clutter this question with too much information. If you need anything that is relevant I'll happily share.

Thanks in advance for thinking with me.

  • have you tried the steps described at: https://stackoverflow.com/questions/30128395/identifying-and-solving-javax-el-propertynotfoundexception-target-unreachable ? 1st section at CDI managed bean... –  Feb 22 '19 at 09:52
  • @nikolairiedel Yes. The only related bullet to my situation would be the third of the CDI part (since I'm using `@Named`). I checked the import and it is correctly the CDI one. – Wouter van Acht Feb 22 '19 at 09:55

1 Answers1

1

Judging from this github issue: https://github.com/javaserverfaces/mojarra/issues/4264

you have two options.

1) Add FacesConfig Annotation to your beans and explicitly declare the JSF version:

@FacesConfig(
    // Activates CDI build-in beans
    version = JSF_2_3
)

So that would give you for your TestServlet.java:

package kwetter.admin.test;

import java.io.Serializable;
import javax.enterprise.context.SessionScoped;
import javax.inject.Inject;
import javax.inject.Named;
import kwetter.domain.entities.User;
import kwetter.logic.beans.TestBean;

@FacesConfig(
    // Activates CDI build-in beans
    version = JSF_2_3
)
@Named
@SessionScoped
public class TestServlet implements Serializable {

    @Inject
    private TestBean testBean;

    public TestServlet() {
        System.out.println("TEST CREATED ");
    }

    public String createNewUser() {
        User user = new User();
        testBean.createUser(user);

        return "cool";
    }
}

With your empty WEB-INF/beans.xml you are in bean-discovery-mode annotated and this does not seem to work as described in the issue above. More Info on the bean-discovery-mode can be found here: https://blogs.oracle.com/theaquarium/default-cdi-enablement-in-java-ee-7.

2) Set bean-discover-mode to all in the beans.xml

So that would give you

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
       version="1.1" bean-discovery-mode="all">
</beans>

I think 1 is the most reasonable solution, as it kinds of contains the problem. On the other side you'll probably have the same problem with the other beans.

  • I already tried your second approach because I stumbled upon it when googling for countless hours. I tried your first solution but this doesn't seem to do anything either. Thanks for thinking with me anyway. – Wouter van Acht Feb 22 '19 at 10:28
  • Alright so I found something when copying stuff 'that worked' from the GitHub issue: The problem is with my `@Inject TestBean testBean;`. Whenever I comment that out a simple `getOutput()` function works. But with it enabled it just doesn't get called. – Wouter van Acht Feb 22 '19 at 10:59