So I created a custom reference in the domain.xml
<custom-resource res-type="java.lang.String" jndi-name="jndi/myResource" factory-class="org.glassfish.resources.custom.factory.PrimitivesAndStringFactory">
<property name="value" value="myValue"/>
</custom-resource>
And referencing it through #Resource(lookup = "jndi/myResource") in a #ApplicationScoped bean.
I am also starting the server with the endorsed directory(containing the endorsed-api.jar). Still when I reference the resource, its not injecting and throwing a null.
Looks like everything is setup correctly, not sure what I am missing here.
And yes, I have beans.xml in the Meta-inf directory too.
Related
I have EAR with in Which WAR & few JARS. Eventually few more JARS under my WAR too.
I have packaged a set of DATA OBJECTs inside a EAR as JAR, out which one of its Managed Bean is under 'SessionScope' and with its property -> 'eager = true'. Say 'A.Java'
Now, From My WAR I have a ManagedBean, say 'B.java', with 'RequestScope' trying to get an instance of A.java, Which is returned as NULL. From the Logs, When traced got the below exception:
The managed-bean with name 'B' must be application scoped to support eager=true.
Is there a hierarchy of Managed Bean Scope, that we have to ensure while archiving and deploying as EAR???
Eager Application-Scoped Beans
Managed beans are lazily instantiated. That is, that they are instantiated when a request is made from the application.
To force an application-scoped bean to be instantiated and placed in the application scope as soon as the application is started and before any request is made, the eager attribute of the managed bean should be set to true as shown in the following example:
#ManagedBean(eager=true)
#ApplicationScoped
The eager property means that the container creates the instance at application startup and not on demand. It can put this instance just into the application scope. (There are no other scopes at this time). So the eagerly created managed beans must be ApplicationScoped.
I develop a confluence plugin using atlassian sdk. When using plugins-version 2, according to Atlassian docs, for every a bean is instantiated, if the bean is public, it is also exposed as OSGI service (which i can see on the Felix console). (See atlassian docu.)
I have 3 copmponents in my confluence plugin so far, one of them is public, the others are "private" (public="false"). My main bean (named "artifact-store") - the one which is public - i use in some macro classes and inject it via constructor. In atlassian-plugin.xml i've declared the component like this:
<component key="artifact-store" class="info.magnolia.sys.confluence.plugin.artifactinfo.artifactstore.ArtifactCache" name="Artifact store to cache artifacts" public="true">
<interface>info.magnolia.sys.confluence.plugin.artifactinfo.ArtifactSearch</interface>
<description key="artifact-store.decription">Artifact store to cache artifacts based on Atlassian cache api.</description>
</component>
Atlassian docu says: "Instances are created per usage (prototype-scope) ..." I doubt about this. When debugging my macros, i always see the same instance of "artifact-store", that's why i think the scope is NOT "prototype".
This would be fine for me, i want the scope "singleton", but i'm unsure whether it really is.
For further bean control Atlassian recommends declaring the beans in META-INF/spring/, hence i've created the spring beans "definition" artifact-info-plugin/src/main/resources/META-INF/spring/artifact-info-plugin.xml; i have added there one bean:
<bean id="artifactSearchBean" class="info.magnolia.sys.confluence.plugin.artifactinfo.artifactstore.ArtifactCache" scope="singleton">
<description>A bean chaching artifact data</description>
</bean>
In In atlassian-plugin.xml i've changed the component definition to:
<component key="artifact-store" class="bean:artifactSearchBean" name="Artifact store to cache artifacts" public="true">
<interface>info.magnolia.sys.confluence.plugin.artifactinfo.ArtifactSearch</interface>
<description key="artifact-store.decription">Artifact store to cache artifacts based on Atlassian cache api.</description>
</component>
I've tried it out, but doesn't work for me, there is no more bean available; none of the components are created; as a consequence, the macros (consuming component beans) also aren't available any more.
To summarize the questions:
What's the bean scope of a confluence plugin <component/>?
Is the scope the same for both public and "private" component beans?
How can i ensure to have a singleton scoped bean?
Is it really possible to declare the component bean in META-INF/spring/beans.xml? If yes, how? Could you provide an short example?
Some maybe further interesting infos about my environment:
in pom:
<confluence.version>5.8.9</confluence.version>
<confluence.data.version>5.8.9</confluence.data.version>
<amps.version>5.1.11</amps.version>
in atlassian-plugin.xml: <atlassian-plugin plugins-version="2"/>
Because i'm not allowed to add more then 2 links, i'll add complete links to pom file, plugin xml and beans xml as comments.
What's the bean scope of a confluence plugin ?
It's singleton
Is the scope the same for both public and "private" component beans?
Yes
How can i ensure to have a singleton scoped bean?
If defined in atlassian-plugin.xml they already are singleton.
Is it really possible to declare the component bean in META-INF/spring/beans.xml? If yes, how? Could you provide an short example?
I never tried defining beans.xml. I only have spring annotation config:
Added src/main/resources/META-INF/spring/spring.xml with following content:
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<context:annotation-config />
<context:component-scan base-package="com.jiraworkcalendar" />
</beans
We are migrating from WAS 6.1 to 8.5. I simply copied the EAR file which we used to deploy in 6.1 to 8.5. The application worked fine and I was happy until web-sphere admin decided to turn on Java2 security. The current was.policy file had java.security.AllPermission. But I guess this does not work with java2 security, so I changed it and granted io permission to every file which is read/written. After this, all permissions related errors are gone, but i am stuck with a strange exception:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'wsJtaTm' defined in ServletContext resource [/WEB-INF/applicationContext.xml]:
Instantiation of bean failed; nested exception is
org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [org.springframework.transaction.jta.WebSphereTransactionManagerFactoryBean]:
Constructor threw exception; nested exception is
org.springframework.transaction.TransactionSystemException: Could not find WebSphere 5.1/6.0/6.1 TransactionManager factory class; nested exception is
java.lang.ClassNotFoundException: com.ibm.ws.Transaction.TransactionManagerFactory
My spring transaction is defined like this:
<bean id="wsJtaTm"
class="org.springframework.transaction.jta.WebSphereTransactionManagerFactoryBean" />
<bean id="transactionManager"
class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManager" ref="wsJtaTm" />
</bean>
I don't understand why the app would work when Java2 security is turned off, and why would it throw ClassNotFound exception when i turn the java2 security on.
According to my knowledge, com.ibm.ws.Transaction.TransactionManagerFactory should be loaded by server itself and should be made available to the app. i don't have any jar in my app having this class.
The error is originating from the constructor of bean id wsJtaTm. Am I missing something in was.policy file?
On further research, i found that this class is present inside a jar file named com.ibm.ws.runtime.jar in the plugins folder of server installation. I don't understand why this jar becomes in-visible when java2 security is turned on.
Please note I am using spring v2.5
Kindly help.
The com.ibm.ws.Transaction.TransactionManagerFactory class is not API, and WebSphere Application Server restricts access to non-API classes when Java 2 security is enabled (if applications could access internal classes, they could easily circumvent Java 2 security). Try using Spring's org.springframework.transaction.jta.WebSphereUowTransactionManager, which uses the supported UOWManager API.
I have some difficulties deploying my web app on JBoss AS 6.1. My current Project is separated into the main web app (controller/managed beans & web frontend using JSF 2 facelets) and one jar with the composite components + backing beans. But when I try to access the page I got an error that the specified component type could not be instantiated.
Copying the backing bean into the main web app solves the problem, but this isn't what I want. So is there anything to pay attention to?
The backing bean looks like
#FacesComponent(value = "elementBase")
public class ElementBase extends UINamingContainer {
...
}
and the composite components interface
<composite:interface componentType="elementBase">
... some attributes
</composite:interface>
The structure of the jar is the following
-- META-INF
|-- resources
| |-- components
| |-- elementBase.xhtml
-- com
|-- example
| |-- ElementBase.class
I've also tried to add faces-config.xml within META-INF folder, with the component type, but the component type was still not found.
Through the BalusC's answer to the question JEE6> Packaging JSF facelets (xhtml) and ManagedBeans as JAR
As to the managed beans and other JSF classes like validators, converters, etc, just annotate them with #ManagedBean, #FacesValidator, #FacesConverter, etc and package them in the JAR the usual way. You only need to provide a JSF 2.0 compatible /META-INF/faces-config.xml file in the JAR.
<?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>
This way JSF will be triggered to scan the classes in the JAR for JSF specific annotations. Alternatively you can also just register them in the JAR's faces-config.xml the JSF 1.x way.
and Java EE6 Tutorial: Application Configuration Resource File
You can have more than one application configuration resource file for an application. The JavaServer Faces implementation finds the configuration file or files by looking for the following:
A resource named /META-INF/faces-config.xml in any of the JAR files in the web application’s /WEB-INF/lib/ directory and in parent class loaders. If a resource with this name exists, it is loaded as a configuration resource. This method is practical for a packaged library containing some components and renderers. In addition, any file with a name that ends in faces-config.xml is also considered a configuration resource and is loaded as such.
A context initialization parameter, javax.faces.application.CONFIG_FILES, in your web deployment descriptor file that specifies one or more (comma-delimited) paths to multiple configuration files for your web application. This method is most often used for enterprise-scale applications that delegate to separate groups the responsibility for maintaining the file for each portion of a big application.
A resource named faces-config.xml in the /WEB-INF/ directory of your application. Simple web applications make their configuration files available in this way.
.. I could fix my problem.
Step by step solution
Create backing bean
#FacesComponent(value = "elementBase")
public class ElementBase extends UINamingContainer {
...
}
and a composite components with the following interface
<composite:interface componentType="elementBase">
... some attributes, value holder, ..
</composite:interface>
provide a faces-config.xml within the deployed jar, to indicate that the jar contains annotated classes. The structure of the deployed jar should look like
-- META-INF
|-- resources
| |-- components
| |-- elementBase.xhtml
|-- faces-config.xml
-- com
|-- example
| |-- ElementBase.class
deploy the jar within the /WEB-INF/lib folder of the web application.
Research/Related links and topics
JEE6> Packaging JSF facelets (xhtml) and ManagedBeans as JAR
Java EE6 Tutorial: Application Configuration Resource File
JSF facelets template packaging
How to create a modular JSF 2.0 application?
I'm working on a JSF project on Weblogic 11g, and our initial design is calling for JSF Backing Beans to invoke EJB3.0 beans to perform business logic and data access calls. The #EJB annotation doesn't seem to work in my project when I try to inject the EJB reference to the backing bean. Whenever I hit the class that I am testing, the constructor for my EJB is never called and I end up with a NPE. Is it possible to inject an EJB3.0 bean into a JSF backing bean? Is there another way I should be invoking an EJB through the JSF Backing bean? What is the best practice?
I googled somewhat and this indeed seems to be a known issue with Weblogic. Lot of similar topics are kept unanswered.
I found this blog which confirms that #EJB in Weblogic only works for resources definied by web.xml, not for JSF. The blog describes also in detail a workaround using ServletContextListener which is IMO not much better than using JNDI.
I also found this OTN topic which confirms that #EJB in Weblogic started to work when EJB modules are not included in subdirectories (see the answer posted at the bottom, Feb 15, 2011 5:44 PM).
It turns out that it is a Weblogic specific issue when deploying anything using JSF and EJB. I found this post on the Oracle forums that explains how to get the #EJB injection working in JSF Managed Beans using Weblogic 11g:
EJB3.0 Injection into JSF Managed beans
UPDATE:
After spinning my wheels for too long, I have to give up trying to inject an EJB into a JSF ManagedBean on Weblogic 11g. Seems to work fine in Tomcat. Maybe the EJB3 and JSF implementation will be better in 12G...
To make it work you need to follow two steps:
Deploy jsf-2.0.war as LIBRARY, you can find it /ORACLE_HOME/wlserver_10.3/common/deployable-libraries
In your web project, add the reference to the jsf-2.0.war library in WEB-INF/weblogic.xml
<?xml version="1.0" encoding="UTF-8"?>
<wls:weblogic-web-app xmlns:wls="http://xmlns.oracle.com/weblogic/weblogic-web-app" 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/ejb-jar_3_0.xsd http://xmlns.oracle.com/weblogic/weblogic-web-app http://xmlns.oracle.com/weblogic/weblogic-web-app/1.1/weblogic-web-app.xsd">
<wls:weblogic-version>10.3.3</wls:weblogic-version>
<wls:context-root>your_context_app</wls:context-root>
<wls:library-ref>
<wls:library-name>jsf</wls:library-name>
<wls:specification-version>2.0</wls:specification-version>
<wls:implementation-version>1.0.0.0_2-0-2</wls:implementation-version>
<wls:exact-match>true</wls:exact-match>
</wls:library-ref>
</wls:weblogic-web-app>
I have successfully tested this in weblogic 10.3.3 and 10.3.5. If somehow this does not work, try to deploy the application as part of EAR file.
So here is the beat! There is a simple way to fix this.
Open up jsf-2.0.war under ...wlserver_10.3\common\deployable-libraries
Navigate to WEB-INF/lib and save wls.jsf.di.jar JAR somewhere
Place wls.jsf.di.jar JAR under lib folder of your WAR application.
Deploy
all should work now just by adding #EJB to property in your #ManagedBean.
There is an alternative for the #EJB annotation in order to get your local EJB bean accessible in your JSF ManagedBean web application. Considering that you have your EJB classes and your WAR packaged in the same EAR file, do the following:
configure your ejb-jar.xml to tell the weblogic expose the EJB beans to the external components;
<enterprise-beans>
<session>
<ejb-name>MyEJBBean</ejb-name>
<business-local>com.app.MyEJBBeanLocalInterface</business-local>
<ejb-class>com.app.MyEJBBeanLocalImpl</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
<ejb-local-ref>
<ejb-ref-name>ejb/MyEJBBeanLocal</ejb-ref-name>
<local>com.app.MyEJBBeanLocalInterface</local>
</ejb-local-ref>
</session>
<enterprise-beans>
Insert in the web.xml of your web application a reference to the EJB throught the ejb-link name. The ejb-ref-name is name visible for the JSF managed beans.
<ejb-local-ref>
<ejb-ref-name>ejb/MyEJBBeanLocal</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<local>com.app.MyEJBBeanLocalInterface</local>
<ejb-link>MyEJBBean</ejb-link>
</ejb-local-ref>
In your JSF Managed Bean call the EJB Bean through JNDI lookup as the following:
try {
Context context = new InitialContext();
MyEJBBeanLocalInterface myEJBBean =
context.lookup("java:comp/env/ejb/MyEJBBeanLocal");
} catch (NamingException e) {
e.printStackTrace();
}
In my case I was using the Weblogic 10.3.6 (11g), JSF 2.0 and EJB 3.0 with JPA (Eclipselink)