Using #Resource to load environment entries - java

I'm trying to load bean runtime configuration.
#Stateless
public class MyBean implements MyLocal{
#Resource String runtimeSetting1="default_value";
//....
}
I cannot find out how to create custom resource on app server side (Glassfish) - I have no idea what I should enter in "Factory Class" field.
Maybe there is a better way of loading configuration...
Thanks.

To my knowledge, the standard way in Java EE is to declare env-entry for configuration data. This applies to all Java EE components like EJB 3 bean class, servlet, filters, interceptors, listener classes, etc. Here, declare something like this in your ejb-jar.xml:
<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd">
<enterprise-beans>
<session>
<ejb-name>FooBean</ejb-name>
<env-entry>
<description>foobar entry</description>
<env-entry-name>foo</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>bar</env-entry-value>
</env-entry>
...
</session>
...
</enterprise-beans>
....
</ejb-jar>
Then look up the env-entry with JNDI or inject it by its name. For example, to inject it in your bean:
#Resource(name="foo")
private String myProperty;

Related

Deltaspike TransactionStrategy Alternative Ambiguous dependencies

I'm defining the TransactionStrategy in apache-deltaspike.properties, using Global Alternatives configuration:
globalAlternatives.org.apache.deltaspike.jpa.spi.transaction.TransactionStrategy=org.apache.deltaspike.jpa.impl.transaction.ResourceLocalTransactionStrategy
My beans.xml has the deltaspike-data module Interceptor only:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
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">
<interceptors>
<class>org.apache.deltaspike.jpa.impl.transaction.TransactionalInterceptor</class>
</interceptors>
</beans>
But I'm being hit by the exception below, which doesn't make any sense to me:
WELD-001409: Ambiguous dependencies for type TransactionStrategy with qualifiers #Default
at injection point [UnbackedAnnotatedField] #Inject private org.apache.deltaspike.jpa.impl.transaction.TransactionalInterceptor.transactionStrategy
at org.apache.deltaspike.jpa.impl.transaction.TransactionalInterceptor.transactionStrategy(TransactionalInterceptor.java:0)
Possible dependencies:
- Managed Bean [class org.apache.deltaspike.jpa.impl.transaction.BeanManagedUserTransactionStrategy] with qualifiers [#Any #Default],
- Managed Bean [class org.apache.deltaspike.jpa.impl.transaction.ResourceLocalTransactionStrategy] with qualifiers [#Any #Default]
Apparently the BeanManagedUserTransactionStrategy alternative is being activated by default. Cause when I remove the Global alternative definition I can see that deltaspike-data module uses the BeanManagedUserTransactionStrategy.
Dependencies Versions:
weld-se-shaded: 3.0.6.Final
deltaspike: 1.9.3
Any ideas of how to get around it? I need to use the ResourceLocalTransactionStrategy.
I'm using a work-around: excluding the BeanManagedUserTransactionStrategy from the beans scan.
I'm doing this in beans.xml using the WELD specific XML schema:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:weld="http://jboss.org/schema/weld/beans">
<weld:scan>
<weld:exclude name="org.apache.deltaspike.jpa.impl.transaction.BeanManagedUserTransactionStrategy"/>
</weld:scan>
<interceptors>
<class>org.apache.deltaspike.jpa.impl.transaction.TransactionalInterceptor</class>
</interceptors>
</beans>
By doing this I'm giving up on portability, meaning this will only work with WELD.

Move beans defined in applicationContext.xml to jboss configuration

currently I have a spring project with an applicationContext.xml that defines some beans that are being used for code injection:
<bean class="com.example.Example1ClientImpl">
<constructor-arg type="java.lang.String" value="${EXAMPLE1_URL}" />
</bean>
<bean class="com.example.Example2ClientImpl">
<constructor-arg type="java.lang.String" value="${EXAMPLE2_URL}" />
</bean>
I want to refactor this code into another project that does not use spring. It runs on a JBoss server, so I assume these beans can be declared in ejb-jar.xml or jboss-ejb3.xml, but I can't figure out how.
Is it possible to do this and can somebody give me some pointers on how to do this?
EDIT: The ExampleXClientImpl classes are not defined in the project itself, they are defined in a dependency of the project. I could adapt this dependency, but I'd prefer if that's not necessary.
If your aim is to make EJB's out of those beans then I would try doing a mix of xml and annotations:
ejb-jar.xml
Here you define your environment properties:
<ejb-jar xmlns="http://java.sun.com/xml/ns/javaee" version="3.0" metadata-complete="false">
<enterprise-beans>
<session>
<ejb-name>Configuration</ejb-name>
<env-entry>
<env-entry-name>EXAMPLE1_URL</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>url1</env-entry-value>
</env-entry>
<env-entry>
<env-entry-name>EXAMPLE2_URL</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>url2</env-entry-value>
</env-entry>
</session>
</enterprise-beans>
</ejb-jar>
Ejb
Here you create a Singleton (as this is the default Spring scope). IF you want to have the bean to have the default prototype scope of EJB's then you can annotate it with Stateless instead:
import javax.annotation.Resource;
import javax.ejb.Singleton;
#Singleton
public class Example1ClientImpl{
#Resource(name = "EXAMPLE1_URL")
private String url;
...
}
#Singleton
public class Example2ClientImpl{
#Resource(name = "EXAMPLE2_URL")
private String url;
...
}
I decided to use #Produces, I forgot that this existed. The solution looks something like this:
public class ClientProducer {
private static final String CLIENT1_ENDPOINT_VAR = "CLIENT1_URL";
private static final String CLIENT2_ENDPOINT_VAR = "CLIENT2_URL";
#Produces
public Example1Client produceExample1Client() {
String uri = System.getProperty(CLIENT1_ENDPOINT_VAR);
return new Example1ClientImpl(uri);
}
#Produces
public Example2Client produceExample2Client() {
String uri = System.getProperty(CLIENT2_ENDPOINT_VAR);
return new Example2ClientImpl(uri);
}
}

Glassfish4 + EJB + Spring, deploy fails

I am upgrading an application from Java7 on Glassfish 3.1.2.2, to Java8 on Glassfish 4.1. The application is packaged as an ear file, containing a jar-file with remote EJBs and Spring beans, as well as a war-file with a couple of servlets and some webservices.
There are only some minor changes done to the actual application, compared to how it was with Glassfish 3.x, the total changes made are:
Built with Java8 instead of Java7.
Deployed on Glassfish 4.1 instead of 3.1.2.2
Newer version of Hibernate
Newer version of ActiveMQ (client)
I can't see any difference between the previous ear-file and the new one (except the abovementioned lib-jars), but still when I try to deploy I get errors like this for all my EJBs:
org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type SomethingLogic with qualifiers #Default
at injection point [BackedAnnotatedField] #Inject private com.my.application.server.service.SomethingServiceSession.somethingLogic
Where SomethingService is an EJB, SomethingLogic is a Spring bean.
My EJBs are defined like this:
#Stateless
#RolesAllowed("secure")
#Interceptors(SpringBeanAutowiringInterceptor.class)
public class SomethingServiceSession implements SomethingService {
#Inject
private SomethingLogic somethingLogic; //Spring bean
SomethingLogic is an interface.
I have a beanRefContext.xml containing:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="beanFactory" class="org.springframework.context.support.ClassPathXmlApplicationContext">
<constructor-arg value="classpath*:applicationContext-glassfish.xml"/>
</bean>
</beans>
The EJB services are defined in glassfish-ejb-jar.xml, like this:
<ejb>
<ejb-name>SomethingServiceSession</ejb-name>
<ior-security-config>
<as-context>
<auth-method>USERNAME_PASSWORD</auth-method>
<realm>AD</realm>
<required>true</required>
</as-context>
</ior-security-config>
</ejb>
I have tried adding a beans.xml with the following content to the resources\META-INF folder of my EJB-project:
<?xml version="1.0"?>
<beans 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://jboss.org/schema/cdi/beans_1_0.xsd" />
No luck.
I have also tried adding #LocalBean to all my EJBs, also with no luck.
In addition, I have tried to disable CDI all together, using this command:
asadmin set configs.config.server-config.cdi-service.enable-implicit-cdi=false
This actually allows my EJB services to be deployed, but I'm suspecting that it has the not so good side effect of my webservices not being discovered, so I want to be able to deploy with CDI enabled to rule this out.
Update:
I have tried changing #Inject with #Autowired in all my non-Spring-handled classes (EJBs, webservices and servlets). Now I get the same error for actual Spring beans. It seems that Glassfish will try to look for EJB beans when encountering #Inject, no matter where they occur.
Fixed my problem by adding bean-discovery-mode="none" to my various beans.xml files.
<?xml version="1.0"?>
<beans 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://jboss.org/schema/cdi/beans_1_2.xsd"
bean-discovery-mode="none" />

Migrating jboss.xml to jboss-ejb3.xml

I'm currently migrating an Java/EE5 application to run with WildFly-8.0.0.Final. As stated here: https://docs.jboss.org/author/display/WFLY8/How+do+I+migrate+my+application+from+AS5+or+AS6+to+WildFly , the legacy jboss.xml file seems to be ignored by now. Unluckily (for me) I was unable to find a good resource for migrating the session part within enterprise-beans. My current jboss.xml looks like this:
<?xml version='1.0' encoding='UTF-8' ?>
<jboss xmlns="http://www.jboss.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.jboss.com/xml/ns/javaee http://www.jboss.org/j2ee/schema/jboss_5_1.xsd" version="5.1">
<security-domain>java:/jaas/customAdmin</security-domain>
<enterprise-beans>
<session>
<ejb-name>CustomConfigBean</ejb-name>
<pool-config>
<pool-value>StrictMaxPool</pool-value>
<pool-max-size>10</pool-max-size>
<pool-timeout>30002</pool-timeout>
</pool-config>
</session>
</enterprise-beans>
<assembly-descriptor>
<security-role>
<role-name>customUser</role-name>
<principal-name>customUser</principal-name>
</security-role>
<security-role>
<role-name>customAdmin</role-name>
<principal-name>customAdmin</principal-name>
</security-role>
</assembly-descriptor>
</jboss>
What is required to make this run in jboss-ejb3.xml ?
Have you taken a look at the schema? It looks like it has the same elements so it should be rather straightforward to create jboss-ejb3.xml using your existing jboss.xml as a starting point.
Here's the jboss-ejb3.xml Reference.
NOTE: I think the schemaLocation is not correct in the reference. It uses http://www.jboss.org/j2ee/schema/jboss-ejb3-2_0.xsd, which does not exist. The correct schema location is http://xmlns.jcp.org/xml/ns/javaee/ejb-jar_3_2.xsd. I just created a discussion in the Wildfly group about the schema location problem.
You don't mention where your jboss.xml is located so for completeness just a reminder that for Wildfly it should be in WEB-INF of a war, or META-INF of an EJB jar.

JNDI name not found - how to use JNDI in WCM workflow plugin?

I'm using Rational Application Developer 8.5 to develop a custom workflow action plugin for IBM Web Content Manager (WCM) in WebSphere Portal 7.0.
The plugin needs to get a JDBC data source with JNDI, but all my attempts to do so produce this error:
javax.naming.NameNotFoundException: Name comp/env/jdbc not found in context "java:".
A data source named "jdbc/wcmbulletins" is defined in the WebSphere Application Server.
Here's the java code to get the data source:
javax.naming.InitialContext ctx=new javax.naming.InitialContext();
javax.sql.DataSource ds=(javax.sql.DataSource)ctx.lookup("java:comp/env/jdbc/wcmbulletins");
The RAD project contains the following XML files only. There's no "persistence.xml" or any other files I've seen mentioned in similar SO questions.
There are also some JSP files referenced by WCM JSP components. The JSP files have no connection with the plugin and don't use JNDI or JDBC.
ibm-web-bnd.xml:
<web-bnd
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://websphere.ibm.com/xml/ns/javaee"
xsi:schemaLocation="http://websphere.ibm.com/xml/ns/javaee http://websphere.ibm.com/xml/ns/javaee/ibm-web-bnd_1_0.xsd"
version="1.0">
<virtual-host name="default_host"/>
<resource-ref name="jdbc/wcmbulletins" binding-name="jdbc/wcmbulletins"/>
</web-bnd>
ibm-web-ext.xml:
<web-ext
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://websphere.ibm.com/xml/ns/javaee"
xsi:schemaLocation="http://websphere.ibm.com/xml/ns/javaee http://websphere.ibm.com/xml/ns/javaee/ibm-web-ext_1_0.xsd"
version="1.0">
<jsp-attribute name="reloadEnabled" value="false"/>
<jsp-attribute name="reloadInterval" value="10"/>
<reload-interval value="3"/>
<enable-directory-browsing value="false"/>
<enable-file-serving value="true"/>
<enable-reloading value="true"/>
<enable-serving-servlets-by-class-name value="true"/>
</web-ext>
plugin.xml:
<plugin id="com.company.wcm.CompanyWCMPlugins"
name="Company WCM Plugins"
version="1.0.0"
provider-name="Company Name Australia">
<extension
point="com.ibm.workplace.wcm.api.CustomWorkflowActionFactory"
id="CompanyWorkflowActionFactory">
<provider class="com.company.wcm.workflow.CompanyWorkflowActionFactory"/>
</extension>
</plugin>
web.xml:
<web-app id="WebApp_ID" version="2.5"
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-app_2_5.xsd">
<display-name>CompanyWCM_JSPs</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<resource-ref id="ResourceRef_1377568155870">
<description/>
<res-ref-name>jdbc/wcmbulletins</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
</web-app>
What do I need to make the JNDI lookup work?
What happens if you change the code to bypass the resource reference and use the name jdbc/wcmbulletins instead?
Also - at what scope is the DS defined? If at cluster level try the name cell/persistent/jdbc/wcmbulletins and see what you get.
Lastly - there is always the WebSphere naming trace. You can enable them via Naming=all, re-run your app, and check trace.log for insight as to what might be going on.
Hope this helps,
ScottH
From my experience, wcm plugins are somewhat independent from the web-application they are contained in (they are more related to OSGI or so). For example during server startup plugins are instantiated, before the web-application itself is, so it might not even be possible to reliably lookup resources from the web-app.

Categories

Resources