I'm trying to inject a PersistenceContext using EJB3 annotations but geronimo doesn't inject dependency. It's an EAR project composed by an EJB and a WEB module.
EJB-module configuration
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<ejb:openejb-jar
xmlns:app="http://geronimo.apache.org/xml/ns/j2ee/application-2.0"
xmlns:bp="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:client="http://geronimo.apache.org/xml/ns/j2ee/application-client-2.0"
xmlns:conn="http://geronimo.apache.org/xml/ns/j2ee/connector-1.2"
xmlns:dep="http://geronimo.apache.org/xml/ns/deployment-1.2" xmlns:ejb="http://openejb.apache.org/xml/ns/openejb-jar-2.2"
xmlns:jaspi="http://geronimo.apache.org/xml/ns/geronimo-jaspi"
xmlns:log="http://geronimo.apache.org/xml/ns/loginconfig-2.0"
xmlns:name="http://geronimo.apache.org/xml/ns/naming-1.2" xmlns:pers="http://java.sun.com/xml/ns/persistence"
xmlns:pkgen="http://openejb.apache.org/xml/ns/pkgen-2.1" xmlns:sec="http://geronimo.apache.org/xml/ns/security-2.0"
xmlns:web="http://geronimo.apache.org/xml/ns/j2ee/web-2.0.1">
<dep:environment>
<dep:moduleId>
<dep:groupId>wedge</dep:groupId>
<dep:artifactId>wedge-ejb</dep:artifactId>
<dep:version>1.0</dep:version>
<dep:type>car</dep:type>
</dep:moduleId>
<dep:dependencies>
<dep:dependency>
<dep:groupId>console.dbpool</dep:groupId>
<dep:artifactId>jdbc_wedgeDS</dep:artifactId>
<dep:version>1.0</dep:version>
<dep:type>car</dep:type>
</dep:dependency>
</dep:dependencies>
</dep:environment>
I've configured persistence.xml as follows
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="wedgePU" transaction-type="RESOURCE_LOCAL">
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
<jta-data-source>jdbc/wedgeDS</jta-data-source>
<class>wedge.entity.Aec</class>
...
<class>wedge.entity.Tnr</class>
<properties>
<property name="openjpa.TransactionMode" value="managed" />
<property name="openjpa.ManagedRuntime"
value="jndi(TransactionManagerName=java:comp/TransactionManager)" />
<property name="openjpa.Log" value="DefaultLevel=INFO" />
</properties>
</persistence-unit>
I've created datasource as Local TX Datasource, and is resolved ok.
I've defined an EJB as follows
#Local(PruebaBL.class)
#Stateless
public class PruebaBLImpl {
#PersistenceContext()
private EntityManager em;
#TransactionAttribute(TransactionAttributeType.REQUIRED)
public void metodoPrueba(HttpServletResponse response) throws IOException, NamingException {
if (em == null) {
response.getOutputStream().println("entity manager is null");
}
I've verified that transaction begins/ends OK, but entityManager is not injected.
Some ideas?
Thanks in advance.
Saul
You don't need to specify the global jndi name. Inject it like this in your servlet:
#EJB
private PruebaBL pruebaBL;
Related
I'm using Spring 4.1.5 and Spring Security 4.0.0.RELEASE.
I read http://spring.io/blog/2014/05/07/preview-spring-security-test-method-security (nice article by Rob Winch) and developed my own implementation of WithSecurityContextFactory to be able to test my Spring MVC controllers:
public class WithMockCustomUserSecurityContextFactory implements WithSecurityContextFactory<WithMockCustomUser> {
#Override
public SecurityContext createSecurityContext(WithMockCustomUser customUser) {
final User fakeUser = new User();
final SecurityUser principal = new SecurityUser(fakeUser);
final Authentication auth = new UsernamePasswordAuthenticationToken(principal, "password", HelpersTest.getAuthorities(customUser.faps()));
final SecurityContext context = SecurityContextHolder.createEmptyContext();
context.setAuthentication(auth);
return context;
}
}
My abstract resource test class is as follow:
#RunWith(SpringJUnit4ClassRunner.class)
#WebAppConfiguration
#ContextConfiguration(locations =
{
"classpath:spring/mock-daos-and-scan-for-services.xml",
"classpath:security.xml",
"classpath:singletons.xml",
"classpath:controller-scan.xml",
"classpath:servlet.xml" })
#TestExecutionListeners(listeners=
{
ServletTestExecutionListener.class,
DependencyInjectionTestExecutionListener.class,
DirtiesContextTestExecutionListener.class,
TransactionalTestExecutionListener.class,
WithSecurityContextTestExcecutionListener.class })
public abstract class AbstractResourceMockMvcTest {
#Autowired
private WebApplicationContext wac;
#Autowired
private Filter springSecurityFilterChain;
private MockMvc mockMvc;
[...]
#Before
public void setup() {
this.mockMvc =
MockMvcBuilders.webAppContextSetup(this.getWac())
.addFilters(springSecurityFilterChain)
.build();
}
[...]
}
Then, my concrete test class inherits from AbstractResourceTest (from above) and it uses the following annotation on a #Test-enabled method:
#WithMockCustomUser(faps={"promotion_read"})
Tracing the code, I can confirm WithMockCustomUserSecurityContextFactory.createSecurityContext() is called and its return value is set in SecurityContextHolder.setContext() (through TestSecurityContextHolder.setContext()).
So far, so good !
However, later in the process, SecurityContextPersistenceFilter.doFilter() calls SecurityContextHolder.setContext() and this overwrites the context set by the test and I lose track of the mocked security context I prepared.
security.xml:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:security="http://www.springframework.org/schema/security"
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-4.1.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-4.0.xsd
"
>
<!-- HTTP security handling -->
<security:http use-expressions="true">
<security:logout logout-url="/j_spring_security_logout" invalidate-session="true" logout-success-url="/login.jsp?loggedout=true" />
<security:custom-filter before="FIRST" ref="multiTenantRequestFilter" />
<!-- make sure following page are not secured -->
<security:intercept-url pattern="/*/*/internal/**" access="hasIpAddress('127.0.0.1')" />
<!-- make sure everything else going through the security filter is secured -->
<security:intercept-url pattern="/resources/**" access="hasRole('ROLE_USER')" requires-channel="any" />
<!-- supporting basic authentication for unattended connections (web services) -->
<security:http-basic />
</security:http>
<!-- authentication strategy -->
<security:authentication-manager alias="authManager">
<security:authentication-provider user-service-ref="userSecurityService">
<security:password-encoder ref="passwordEncoder" />
</security:authentication-provider>
</security:authentication-manager>
<!-- custom filter to intercept the tenant name from the login form -->
<bean id="multiTenantRequestFilter" class="com.meicpg.ti.web.MultiTenantRequestFilter" />
</beans>
servlet.xml:
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-4.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.1.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
"
>
<mvc:annotation-driven>
<!-- Content skipped for StackOverflow question -->
</mvc:annotation-driven>
<context:annotation-config />
<bean id="annotationExceptionResolver" class="org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver"></bean>
<security:global-method-security pre-post-annotations="enabled"/>
<aop:aspectj-autoproxy proxy-target-class="true"/>
</beans>
How can I prevent this security context overwrite ? Does my security.xml contain an obvious flaw I missed ?
PS: I skipped the other context configuration files as they seem irrelevant to the problem.
Thanks in advance !
Unfortunately that blog post is just for method level security and does not have complete instructions for MockMvc setup (the following blog in the series does). Additionally, the blogs are actually dated (I have updated them to reflect that readers should refer to the reference documentation). You can find updated instructions in the Testing Section of the reference.
In short, update your code to the following:
import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.*;
#RunWith(SpringJUnit4ClassRunner.class)
#WebAppConfiguration
#ContextConfiguration(locations =
{
"classpath:spring/mock-daos-and-scan-for-services.xml",
"classpath:security.xml",
"classpath:singletons.xml",
"classpath:controller-scan.xml",
"classpath:servlet.xml" })
public abstract class AbstractResourceMockMvcTest {
#Autowired
private WebApplicationContext wac;
private MockMvc mockMvc;
[...]
#Before
public void setup() {
this.mockMvc =
MockMvcBuilders.webAppContextSetup(this.getWac())
.apply(springSecurity())
.build();
}
#Test
#WithMockCustomUser(faps={"promotion_read"})
public void myTest() {
...
}
[...]
}
A few highlights:
You no longer need to provide the TestExecutionListeners
Use .apply(springSecurity()) instead of adding the spring security filter chain manually
This works because Spring Security's test support i.e. apply(springSecurity()) will override the SecurityContextRepository used by the springSecurityFilterChain to first try the TestSecurityContextHolder.
I'm trying to run an existing application on Tomcat 7.0.28 using JSF 2.1.10
I have the following bean:
#Named
#Dependent
public class FormatterBean
{
public String replaceNewLineWithBrTag(String s)
{
return Formatter.replaceNewLineWithBrTag(s);
}
public String leftJustifyWithZeros(String string, Integer zeroTotal)
{
return Formatter.leftJustifyWithZeros(string, zeroTotal);
}
}
When I do something like this
<p:tooltip for="visualizar" value="#{formatterBean.replaceNewLineWithBrTag(adiantamento.observacao)}" />
I get the following error:
/page/rdv/adiantamento.xhtml #87,117
value="#{formatterBean.replaceNewLineWithBrTag(adiantamento.observacao)}":
Property 'replaceNewLineWithBrTag' not found on type
br.com.spdata.util.FormatterBean
Some details:
Same code works fine on Glassfish 3.1.2
The method leftJustifyWithZeros works fine
Any ideias?
Thanks,
Phillip
One thing to check is whether your web.xml is declared as using the Servlet 3.0 spec, e.g.:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0"
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_3_0.xsd"
>
...
I've encoutered strange issue with annotations in bean.
index.xhtml content:
<h:outputText value="#{ejb.helloWorld}" />
Ejb.java content:
package bean;
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
#ManagedBean(name="ejb")
#SessionScoped
public class Ejb implements Serializable
{
public String getHelloWorld()
{
return "Hello World";
}
}
From what we see above i should be able to call bean method... but i can't, it will work only if i manage bean in faces-config.xml file with content:
<?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">
<managed-bean>
<managed-bean-name>ejb</managed-bean-name>
<managed-bean-class>bean.Ejb</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
</faces-config>
Questions:
Why i have encountered such situation ?
How to resolve this issue ?
I'm using:
JSF 2.0 (imported to lib)
JBoss Server 4.2
My wild guess is that JSF 1.2 bundled by default with JBoss 4.2 is used (JBoss might not care about JSF version). As a result annotations are ignored, faces-config.xml file is used.
Try to use configuration suggested here (thats's google cached page).
I have the following Interfaces MyLocalBean, MyRemoteBean and the stateless MyBean implements MyLocalBean, MyRemoteBean
Which of the following i don't need to get a simple java application to test this ...
ejb-jar.xml, glassfish-ejb-jar.xml, gf-client.jar
Here's ejb-jar.xml
<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:ejb="http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_1.xsd" version="3.1">
<enterprise-beans>
<session>
<ejb-name>MyEJB</ejb-name>
<home>test.ejb.MyLocalBean</home>
<remote>test.ejb.MyRemoteBean</remote>
<ejb-class>test.ejb.MyBean </ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
</session>
</enterprise-beans>
</ejb-jar>
what's missing here? would i be able to lookup using MyEJB?
and here's my lookup code
InitialContext ic;
ic = new InitialContext();
MyRemoteBean remoteBean =
(MyRemoteBean ) ic.lookup("java:comp/env/MyEJB");
[EDIT]
I've update the ejb-jar.xml as follows
<enterprise-beans>
<session>
<ejb-name>MyEJB</ejb-name>
<ejb-class>test.ejb.MyBean</ejb-class>
<ejb-local-ref>
<ejb-ref-name>MyEJB</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<local>test.ejb.MyLocalBean</local>
<ejb-link>MyEJBClient.jar#MyEJB</ejb-link>
</ejb-local-ref>
</session>
</enterprise-beans>
I get an error ...
cannot Deploy MyBeanEAR
Deployment Error for module:
MyBeanEAR: Error occurred
during deployment: Exception while
deploying the app [MyBeanEAR] :
Error: Unresolved :
MyEJBClient.jar#MyEJB.
Please see server.log for more
details.
[\EDIT]
[EDIT]
Hi bkail, let me brake down the problem using the correct names.. Initially, this is what my eclipse-sts IDE created by default
<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:ejb="http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_1.xsd" version="3.1">
<display-name>BatchOverrideEJB</display-name>
<ejb-client-jar>BatchOverrideEJBClient.jar</ejb-client-jar>
</ejb-jar>
and this is how i tried accessing the EJB
Properties p = new Properties();
p.put("org.omg.CORBA.ORBInitialHost","localhost");
p.put("org.omg.CORBA.ORBInitialPort","3700");
InitialContext ctx = new InitialContext(p);
ic = new InitialContext(p);
BatchOverrideManagerRemote batchOverrideRemote =
(BatchOverrideManagerRemote) ic.lookup("java:comp/env/BatchOverrideEJB");
running this i got the following error
javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial
at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:645)
at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:288)
at javax.naming.InitialContext.getURLOrDefaultInitCtx(InitialContext.java:325)
at javax.naming.InitialContext.lookup(InitialContext.java:392)
at za.co.sanlam.batchovveride.test.BatchOverrideTester.main(BatchOverrideTester.java:33)
I thought this error meant that my EJB its not bound to the context, so i modified the ejb-jar.xml as follows
<ejb-jar xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:ejb="http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_1.xsd" version="3.1">
<enterprise-beans>
<session>
<ejb-name>BatchOverrideEJB</ejb-name>
<ejb-class>com.test.ejb.BatchOverrideManagerBean</ejb-class>
<ejb-local-ref>
<ejb-ref-name>BatchOverrideEJB</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<local>com.test.batchoverridemanager.ejb.BatchOverrideManagerLocal</local>
<ejb-link>BatchOverrideEJB</ejb-link>
</ejb-local-ref>
</session>
</enterprise-beans>
</ejb-jar
but now i get javax.naming.NameAlreadyBoundException: Use rebind to override
[/EDIT]
Try <ejb-link>MyEJB</ejb-link>. That said, test.ejb.MyLocalEJB doesn't sound like a home interface that extends EJBHome, so perhaps you meant to use <business-remote> rather than <remote> and <home>? If you're using a container that supports EJB 3.1, you'll probably find it easier to just use annotations:
#Stateless
public class MyBean implements MyLocal { ... }
#Local
public interface MyLocal { ... }
#Remote
public interface MyRemote { ... }
As an aside MyLocalBean and MyRemoteBean are unusual names for business interfaces. Typically, the Bean suffix is reserved for the EJB class itself.
Edit #2:
For the second edit, see this link:
http://glassfish.java.net/javaee5/ejb/EJB_FAQ.html#nonJavaEEwebcontainerRemoteEJB
I'm trying to inject a Map into a Grails controller. I want to inject the same map into many controllers so would like to define it in resources.groovy.
I've looked on the web but can't find an example of creating a simple map.
In Spring MVC I've used something like this:
<util:map id="diplomaPermissions">
<entry>
<key>1</key>
<value>Diploma_AQA_Building_And_Construction</value>
</entry>
<entry>
<key>1</key>
<value>Diploma_Edexcel_Building_And_Construction</value>
</entry>
</util:map>
With this in my xml header:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
But this doesn't seem to work in grails if I use the spring xml files.
Any tips appreciated.
after further investigation, you can create the map in "resources.groovy"
beans = {
diplomaPermissions(org.springframework.beans.factory.config.MapFactoryBean) {
sourceMap = [
1:"Diploma_AQA_Building_And_Construction",
2:"Diploma_Edexcel_Building_And_Construction"
]
}
}
I think it might be related to the version of spring you are expecting; when using the old style for creating map, everything works fine.
try this in your resources.xml in the spring configuration directory
<bean id="testMap"
class="org.springframework.beans.factory.config.MapFactoryBean">
<property name="sourceMap">
<map>
<entry key="key1" value="value1"/>
<entry key="key2" value="value2"/>
</map>
</property>
</bean>
and this on your controller
class DisplayMapController {
def testMap
def index = {
render (contentType: "text/plain") {
div(id:"myDiv") { p "$testMap" }
}
}
}