Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 974
ebianchini Avatar asked Aug 29 '11 18:08

ebianchini


2 Answers

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.

like image 110
BalusC Avatar answered Nov 19 '22 00:11

BalusC


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.
like image 8
Alexey Berezkin Avatar answered Nov 19 '22 00:11

Alexey Berezkin