@PostConstruct didn't get called by JSF if ManagedBean is inside jar library
Asked Answered
R

2

6

I'm running with the following problem.

I have a few Managed Beans that are shared between, at this moment, two JSF applications. As I don't want to copy and paste the code in the two (more in the coming future) I've put this shared managed beans inside a JAR library. I've followed this blog: http://jsflive.wordpress.com/2011/03/24/custom-component-library/

Well, even if I put the faces-config.xml inside JAR/META-INF/ the @ManagedBean and @ViewScoped didn't work. I couldn't realise why, but if I register the beans in faces-config.xml (JAR ones, not WAR ones) this problem goes away.

I could live with this, but for my surprise the @PostConstruct annotation didn't get called for this managed beans inside JAR library. I don't get any error, warning or else. I suppose that the beans are getting loaded, but the their annotations aren't being processed.

Have anyone faced this?

My environment: Glassfish 3.1.1 (build 12) JSF 2.1.3

Thanks in advance.

Restrictive answered 29/8, 2011 at 18:21 Comment(0)
B
16

Then the @PostConstruct annotation has not been scanned. This is result of the same problem which caused that your @ManagedBean annotation and likes have not been scanned.

There are several causes of this problem:

  1. You used Mojarra 2.1.0 on Jetty/Tomcat/JBoss AS. This is a very specific bug in the annotation scanner. See issue 1937.

  2. Your /WEB-INF/faces-config.xml file has a metadata-complete="true" attribute. This conflicts the 1st requirement as outlined in JSF 2.0 specification:

    11.5.1 Requirements for scanning of classes for annotations

    • If the <faces-config> element in the WEB-INF/faces-config.xml file contains metadata-complete attribute whose value is “true”, the implementation must not perform annotation scanning on any classes except for those classes provided by the implementation itself. Otherwise, continue as follows.

    • If the runtime discovers a conflict between an entry in the Application Configuration Resources and an annotation, the entry in the Application Configuration Resources takes precedence.

    • All classes in WEB-INF/classes must be scanned.

    • For every jar in the application's WEB-INF/lib directory, if the jar contains a “META-INF/faces-config.xml” file or a file that matches the regular expression “.*\.faces-config.xml” (even an empty one), all classes in that jar must be scanned.

  3. Your JAR file is not been dropped in /WEB-INF/lib, but somewhere else in the classpath. This conflicts the 4th requirement as outlined above.

  4. Your webapp's /WEB-INF/faces-config.xml and/or your JAR's /META-INF/faces-config.xml is not JSF 2.x compatible. It must not contain a JSF 1.x specific <faces-config> declaration, but a JSF 2.x specific one.

    <?xml version="1.0" encoding="UTF-8"?>
    <faces-config
        xmlns="http://java.sun.com/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
        version="2.0">
    </faces-config>
    

    The one in JAR's /META-INF is allowed to be completely empty.

Cause 1 can be scratched in your particular case as you're using Mojarra 2.1.3 on Glassfish. I'll bet it to be the other causes.

Buran answered 29/8, 2011 at 18:40 Comment(4)
Thanks BalusC for answering. Well, the faces-config files (JAR and WAR) are pointing to JSF 2.x and both don't use metadata-complete, so I'm lost. I suppose that #1 is the problem because I didn't pack the JAR inside WAR but I'd deployed it as a library in ...domains/domain1/lib.Restrictive
Oh, I totally didn't expect that. Why did you put the JAR there? The JSF2 spec mandates that the JAR must be in /WEB-INF/lib. I improved the answer to add it as point 3.Buran
Sorry, I didn't notice that. My mistake. Explaining why: just because I don't want to "replicate" jars ... I'm using Primefaces too and I put it in the domain/lib too. It works, so as I am new in JSF world I thought that I could do the same with my library.Restrictive
PF libraries do not contain any managed beans and everything is registered in xml files. I'd just bundle the JAR in your webapp.Buran
D
8

Also note that post-construct method must not be declared to throw any checked exception. Message from stderr:

Method 'public void my.app.MyBean.postConstruct() throws java.lang.Exception' marked with the 'javax.annotation.PostConstruct' annotation cannot declare any checked exceptions. This method will be ignored.
Drub answered 13/2, 2013 at 11:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.