I have a Spring3.1/Hibernate3 project where the app-context is built by annotating classes + component scanning. Everything works fine when I build it with eclipse, but having built it with maven it seems the annotations are overlooked (nothing is injected, services are null, etc).
We have the compiler plugin as shown below:
<artifactId>maven-compiler-plugin</artifactId>
<version>3.0</version>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
The "main" spring application context is loaded via contextloaderlistener from one of the associated web-projects (services/daos etc resides in a separate Common-project") To avoid instantiating one context for each web-project (we have a few, yes one can question that but..) we use the tecnique detailed in this blog:
http://blog.springsource.org/2007/06/11/using-a-shared-parent-application-context-in-a-multi-war-spring-application/
This is ripped from the web-xml instantiating the context:
<listener>
<display-name>ContextLoaderListener</display-name>
<listener- class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:beanRefContext.xml</param-value>
</context-param>
<context-param>
<param-name>parentContextKey</param-name>
<param-value>common.context</param-value>
</context-param>
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>SpringHibernate</param-value>
</context-param>
BeanRefContext which lies in the Common-project looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<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-2.0.xsd">
<bean id="common.context" class="org.springframework.context.support.ClassPathXmlApplicationContext">
<constructor-arg>
<list>
<value>appContext.xml</value>
</list>
</constructor-arg>
</bean>
</beans>
And this in turns starts and ordinary ClassPathXmlApplicationContext with annotation-config and component scan definitions:
<?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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org /schema/context/spring-context-3.0.xsd">
<context:annotation-config/>
<import resource="persistenceContext.xml" />
<import resource="businessContext.xml" />
<context:component-scan base-package="com.XX.supplierportal.common.spring">
<context:exclude-filter type="regex" expression="com.XX.supplierportal.common.spring.*Test.java"/>
</context:component-scan>
<context:component-scan base-package="com.XX.supplierportal.userdirectory.incoming"/>
</beans>
And as stated above, everything preforms amiably in eclipse instantiating and sharing ONE common-applicationContext containing services etc among a number of web-projects, building it with maven however the contexts gets instantiated but it seems annotations are not read.
Anyone have a clue as to what is missing?
Having worked with this for a while, we saw it was the javax.annotation.Resource annotation that wasn't working and we finally realized that the maven build lacked the jsr250-api.jar (bonk self)
I'm pretty sure this has nothing to do with maven, but with the spring configuration.
How do you instantiate the Spring Container? Which ApplicationContext implementation are you using? Please show the code that starts Spring and at least parts of your Spring XML.
Related
I need some help: I have one EAR-File, containing one WAR-File, one EJB-Jar-File and some "shared" libs:
aopalliance-1.0.jar commons-logging-1.1.1.jar log4j-1.2.16.jar spring-aop-4.0.5.RELEASE.jar spring-beans-4.0.5.RELEASE.jar spring-context-4.0.5.RELEASE.jar spring-context-support-4.0.5.RELEASE.jar spring-core-4.0.5.RELEASE.jar spring-expression-4.0.5.RELEASE.jar
The War File has a Context initializer which find the spring config and loads everything well.
I now want to use another Spring Context for the EJB Jar.
My EJB is defined as
#Stateless(mappedName = "ejb/SpringRocks")
#RemoteHome(com.ibm.websphere.ola.ExecuteHome.class)
#Interceptors(SpringBeanAutowiringInterceptor.class)
public class WolaUseCaseOne {
#Autowired
private DummyService dummyService;
/* ...More stuff here */
Inside the EJB-JAR, there is also a beanRefContext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<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="myEjb" name="myEjb" class="org.springframework.context.support.ClassPathXmlApplicationContext">
<constructor-arg value="classpath*:META-INF/spring/simpleEjb.xml" />
</bean>
</beans>
The simpleEjb.xml is is also inside the EJB-Jar and is defining a very simple Bean:
<?xml version="1.0" encoding="UTF-8"?>
<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="myDummyService" class="com.provinzial.beispielanwendung.batch.wola.DummyServiceImpl" />
</beans>
As described, the WEB Part works perfect, but when the EJB is called, the SpringBeanAutowiringInterceptor is called, but seems to do nothing. What do I have to do, to get a Spring Context created?! My hope was that it is initialized when the EJB is created. I created a Subclass of SpringBeanAutowiringInterceptor with some loggers, but the class is only created, no method is called !
What else do I have to do? Or does anybody have a valid EAR File example?
I think the Problem is that inside the EJB Module no context is initialized...
Greets
Timo
I was facing similar issue with my EJB (no WAR). This is what fixed mine,
I was missing the spring-aop jar on my classpath. I see you have it so good there.
In my ejb-jar.xml file, I set the meta-data flag to true so I did not get prompted on deployment to complete.
I set to "false" for one deployment to see what IBM generated for me. In the ejb-jar.xml it added the following (my MDB is named TaskMDB),
<assembly-descriptor>
<interceptor-binding>
<ejb-name>TaskMDB</ejb-name>
<interceptor-class>org.springframework.ejb.interceptor.SpringBeanAutowiringInterceptor</interceptor-class>
</interceptor-binding>
</assembly-descriptor>
<interceptors>
<interceptor>
<interceptor-class>org.springframework.ejb.interceptor.SpringBeanAutowiringInterceptor</interceptor-class>
<post-activate>
<lifecycle-callback-class>org.springframework.ejb.interceptor.SpringBeanAutowiringInterceptor</lifecycle-callback-class>
<lifecycle-callback-method>autowireBean</lifecycle-callback-method>
</post-activate>
<pre-passivate>
<lifecycle-callback-class>org.springframework.ejb.interceptor.SpringBeanAutowiringInterceptor</lifecycle-callback-class>
<lifecycle-callback-method>releaseBean</lifecycle-callback-method>
</pre-passivate>
<post-construct>
<lifecycle-callback-class>org.springframework.ejb.interceptor.SpringBeanAutowiringInterceptor</lifecycle-callback-class>
<lifecycle-callback-method>autowireBean</lifecycle-callback-method>
</post-construct>
<pre-destroy>
<lifecycle-callback-class>org.springframework.ejb.interceptor.SpringBeanAutowiringInterceptor</lifecycle-callback-class>
<lifecycle-callback-method>releaseBean</lifecycle-callback-method>
</pre-destroy>
</interceptor>
</interceptors>
Then I added what IBM generated (the assembly-descriptor and interceptors stanzas) back to my ejb-jar.xml and set the metadata-complete back to true.
Then it worked. Hope this helps.
Here is the full ejb-jar.xml
<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar version="3.1" 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/ejb-jar_3_1.xsd">
<display-name>ares-api-uow-ejb</display-name>
<enterprise-beans>
<message-driven id="TaskMDB">
<ejb-name>TaskMDB</ejb-name>
<ejb-class>something.api.uow.ejb.mdb.TaskMDB</ejb-class>
<messaging-type>javax.jms.MessageListener</messaging-type>
<transaction-type>Bean</transaction-type>
</message-driven>
</enterprise-beans>
</ejb-jar>
I have got a problem with JNDI configuration on Jetty server. I cannot by any means configure it in a way that afterwards Spring (3.0.5) can retrieve JNDI variables.
I have some credentials which I do not want to store in properties so that it will not exist in git repo. My web application is running on Jetty (most recent version 9.2.3), thus I came up with idea to store this credentials in Jetty web application context. Jetty provides such solution with jetty-env.xml. So I have created jetty-env.xml file in my WEB-INF/ like following:
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
<Configure id="webappCtx" class="org.eclipse.jetty.webapp.WebAppContext">
<New id="username" class="org.eclipse.jetty.plus.jndi.Resource">
<Arg><Ref refid="webappCtx"/></Arg> <!-- scope -->
<Arg>server/username</Arg> <!-- name -->
<Arg type="java.lang.String">myUsername</Arg> <!-- value -->
</New>
<New id="password" class="org.eclipse.jetty.plus.jndi.Resource">
<Arg><Ref refid="webappCtx"/></Arg> <!-- scope -->
<Arg>server/password</Arg> <!-- name -->
<Arg type="java.lang.String">qwerty</Arg> <!-- value -->
</New>
</Configure>
After that I have defined binding in the web.xml as follows:
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="MyWebApp" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>My Web App</display-name>
<!-- INITIALIZE SPRING -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:/spring-context.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- JETTY-ENV JNDI -->
<resource-ref>
<res-ref-name>server/username</res-ref-name>
<res-type>java.lang.String</res-type>
</resource-ref>
<resource-ref>
<res-ref-name>server/password</res-ref-name>
<res-type>java.lang.String</res-type>
</resource-ref>
</web-app>
And configured my Spring context in this way:
<?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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:amq="http://activemq.apache.org/schema/core"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:ehcache="http://www.springmodules.org/schema/ehcache"
xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core-5.2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springmodules.org/schema/ehcache http://www.springmodules.org/schema/cache/springmodules-ehcache.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd">
<jee:jndi-lookup id="serverUsername" jndi-name="server/username" expected-type="java.lang.String" resource-ref="true" />
<jee:jndi-lookup id="serverPassword" jndi-name="server/password" expected-type="java.lang.String" resource-ref="true"/>
<bean name="abstractServerConnectionFactory" class="my.package.ServerConnectionFactory" abstract="true">
<constructor-arg value="${server.host}"/>
<constructor-arg value="${server.port}"/>
<constructor-arg ref="serverUsername"/>
<constructor-arg ref="serverPassword"/>
</bean>
</beans>
After that I am starting Jetty with --add-to-startd=jndi enabled and I am always getting javax.naming.NameNotFoundException when creating serverUsername and serverPassword. I have tried many modfication, but non have seem to work. I have tried:
Changing org.eclipse.jetty.plus.jndi.Resource to org.eclipse.jetty.plus.jndi.EnvEntry and then refering to it via resource-env-ref in web.xml
Setting resource scope to JVM instead of webapp so changing <Arg><Ref refid="webappCtx"/></Arg> to <Arg></Arg> as mentioned here
Adding automatic binding without using web.xml as mentioned here
<Call name="bindToENC">
<Arg>server/username</Arg> <!-- binds server/username to java:comp/env/server/username for this webapp -->
</Call>
And many other, but it just does not work. Please give me a working example how I can get it to work. Thank you!
Ok so I have managed to get this working. The problem was the configuration. I am using Jetty 9 so according to the official documentation (http://www.eclipse.org/jetty/documentation/current/jndi.html#jndi-quick-setup) the only thing that needs to be done prior to using JNDI in Jetty is adding jndi module to start.d by doing --add-to-startd=jndi. And well, that's not exactly true, because this will enable JNDI, BUT WILL NOT INCLUDE jetty-env.xml contents (Jetty do not even touch it). I've been reading about the container lifecycle and noticed that in order to use JNDI one need to include following classes in the web application context configuration classes set:
org.eclipse.jetty.plus.webapp.EnvConfiguration
org.eclipse.jetty.plus.webapp.PlusConfiguration
This is done by default in $JETTY_HOME/etc/jetty-plus.xml, which is config file for plus module. So in order to add this classes into the Jetty container lifecycle, and by this include and parse jetty-env.xml, one need to enable plus module in addition to jndi module (jndi does not depend upon plus)! Thus I have changed my start.d config by invoking --add-to-startd=jndi,plus (no space between modules) and everything started working like a charm.
Hi I have got the webservice up and running , i have used jax ws. I have used Spring to be able to use beans with Autowired and stuff that spring gives like property value injection in applicationContext.xml.
I have the below spring applicationcontext.xml entry:
<context:component-scan base-package="com.mybeans.service" />
<bean id="myProperty" class="com.mybeans.service.MyBeanProperty"
p:Size="BIG">
</bean>
In web service end point class , i have done:
#Autowired private MyBeanProperty myProperty;
And I have a method :
public String getSize() {
return myProperty.getSize();
}
Unfortunately when i invoke the method it does not get any value and throws nullpointerexception.
PS: I used soapUI to run the wsdl of the webservice and invoked the method.
Is the webservice runs before the beans get created by Spring??
To duffmo
Yes i used component scan in applicationContext. And i do have the context loader listener as below in web.xml. Please help me..
Here is my complete code explainaton with code
I am using JAX-WS and Spring and try to setup a few WebServices which need run on Tomcat 7.
I am using Maven as build tool therefore I just list my two dependencies here:
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>3.0.5.RELEASE</version>
</dependency>
<dependencies>
<dependency>
<groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-rt</artifactId>
<version>2.1.3</version>
</dependency>
</dependencies>
my service classes are located in com.test.services and are named TestService & HelloWorldService and look as follows:
package com.test.services;
import javax.jws.WebMethod;
import javax.jws.WebService;
#WebService( name = "Test", serviceName = "TestService" )
public class TestService {
#WebMethod
public String getTest() {
return "Test";
}
}
this is my web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app 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>toolbox</display-name>
<description>testing webservices</description>
<listener>
<listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class>
</listener>
<servlet>
<servlet-name>jaxws-servlet</servlet-name>
<servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jaxws-servlet</servlet-name>
<url-pattern>/testservice</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>jaxws-servlet</servlet-name>
<url-pattern>/helloworldservice</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>10</session-timeout>
</session-config>
</web-app>
and this is my sun-jaxws.xml:
<?xml version="1.0" encoding="UTF-8"?>
<endpoints xmlns='http://java.sun.com/xml/ns/jax-ws/ri/runtime' version='2.0'>
<endpoint
name="jaxws-servlet"
implementation="com.test.services.TestService"
url-pattern="/testservice"/>
<endpoint
name="jaxws-servlet"
implementation="com.test.services.HelloWorldService"
url-pattern="/helloworldservice" />
</endpoints>
This works great and I can access the services by pointing my browser to [url]http://localhost:8080/toolbox/testservice[/url] respectively [url]http://localhost:8080/toolbox/helloworldservice[/url].
However Spring support is obviously not activated.
I tried the following which just leaver the HelloWorldService available:
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app 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>toolbox</display-name>
<session-config>
<session-timeout>30</session-timeout>
</session-config>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
and applicationContext.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:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd">
<context:component-scan base-package="com.test.services" />
<bean class="org.springframework.remoting.jaxws.SimpleJaxWsServiceExporter">
<property name="baseAddress" value="http://localhost:8080/" />
</bean>
</beans>
furthermore I annotated both Service classes with #Service annotation. As I mentioned before, this only publishes the alphabetically first webservice, hence HelloWorldService.
Also it changes the URL, as the service is now available as [url]http://localhost:8080/[/url] rather than [url]http://localhost:8080/toolbox/helloworldservice[/url].
The logging of Tomcat shows, that the Spring Context loads both Classes as Spring beans.
Do you have any ideas or suggestions on how to enable Spring support while keeping both services available??
It is answered here. Ultimately nothing worked other than adding below code to service impl.
#PostConstruct
public void init() {
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
}
No Need to use ApplicationContext as well, if you do the following things
Annotate your service class with #Service
Service class should extends "SpringBeanAutowiringSupport".
Please have a look at the following snippet.
#org.springframework.stereotype.Service
#javax.jws.WebService (endpointInterface="a.b.c.MyPort",
targetNamespace="http://a.b.co.in/Retail/MyService/V1",
serviceName="MyService",
portName="MyServicePort",
wsdlLocation="wsdl/MyService.wsdl")
public class MyServiceBindingImpl extends org.springframework.web.context.support.SpringBeanAutowiringSupport{
I got the same issue, to resolve it I started the jaxws listener after the spring listener:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class>
</listener>
Hope it helps
Your TestService (which is annotated with #WebService) should extend "SpringBeanAutowiringSupport" class to kick start spring binding.
Please have a look at the duffmo mentioned points as well.
I think it's more likely that your Spring context has not be loaded and made available to the web service. How have you done that?
You should have a ContextLoaderListener configured in the web.xml for the WAR in which the web service is deployed. Did you tell it where to load the Spring context? Are you using component scan?
http://renidev.wordpress.com/2009/02/02/how-to-use-springs-context-component-scan-and-annotation/
You misses the configuration for webservice inject. So put more inside the web.xml
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class>
</listener>
Please don't forget the order. Because you need to init the bean for the autowired field first
Thanks
I am trying to create a Spring MVC web app (Spring Framework 3.0.5). I am using IntelliJ IDEA 11.1.3 to deploy my app on a WebLogic Server (10.3.4). One of my web pages attempts to store some data in a database using JPA. My persistence.xml specifies:
<?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="LeaveSchedulerJPA" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>com.engilitycorp.leavetracker.jpa.UserRole</class>
<properties>
<property name="javax.persistence.jdbc.url" value="jdbc:oracle:thin:#localhost:1521:xe "/>
<property name="javax.persistence.jdbc.user" value="leavescheduler"/>
<property name="javax.persistence.jdbc.password" value="xxx"/>
<property name="javax.persistence.jdbc.driver" value="oracle.jdbc.OracleDriver"/>
</properties>
</persistence-unit>
</persistence>
However, when I look in the debugger, my EntityManagerFactory is shown as an org.apache.openjpa.persistence.EntityManagerFactoryImpl, and when I call createEntityManager, I get an org.apache.openjpa.persistenceArgumentException that states that "A JDBC Driver or DataSource class name must be specified in the ConnectionDriverName property".
It appears to my newbie eye that the persistence.xml may not be getting processed. I've tried putting it in (project)/src/main/resources/META-INF and (project)/src/main/resources/META-INF/spring, with the same unfortunate result.
I am not committed to using Hibernate persistence; however, I do want to use something that implements JPA 2, and I am having a real hard time configuring my environment. For example, I have little idea how openjpa got involved in my app. I suppose it may be the default JPA provider for something (WebLogic?, IntelliJ IDEA?). Any help/suggestions would be much appreciated.
My web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app 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">
<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/root-context.xml</param-value>
</context-param>
<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Processes application requests -->
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
root-context.xml:
<?xml version="1.0" encoding="UTF-8"?>
<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-3.0.xsd">
</beans>
servlet-context.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
<!-- Enables the Spring MVC #Controller programming model -->
<annotation-driven />
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />
<!-- Resolves views selected for rendering by #Controllers to .jsp resources in the /WEB-INF/views directory -->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
<context:component-scan base-package="com.engilitycorp.leavetracker" />
</beans:beans>
WebLogic 10.3.4 is Java EE 5 compliant and is shipped with JPA 1.0 implementations: OpenJPA and TopLink.
According to WebLogic documentation ( http://docs.oracle.com/cd/E17904_01/web.1111/e13720/using_toplink.htm#CIHDJHHI ) it can be used also with JPA 2.0 but only after applying a patch. Simply follow the instructions (patching seems to be quite simple but I didn't test it).
Probably you can also use your own JPA 2.0 provider without patching, as user1654209 wrote in first answer. But JPA 1.0 classes supplied with WebLogic can get in the way, because they are loaded by higher level classloader and have priority over classes packaged in your WAR file. To prevent such behaviour you have two options:
pack your application's WAR within an EAR archive with META-INF/weblogic-application.xml file containing following lines (you must also include standard META-INF/application.xml file):
<?xml version="1.0" encoding="UTF-8"?>
<weblogic-application xmlns="http://xmlns.oracle.com/weblogic/weblogic-application/1.0/weblogic-application.xsd">
<prefer-application-packages>
<package-name>javax.persistence.*</package-name>
</prefer-application-packages>
</weblogic-application>
add WEB-INF/weblogic.xml file to your WAR archive with following lines:
<?xml version='1.0' encoding='UTF-8'?>
<weblogic-web-app xmlns="http://www.bea.com/ns/weblogic/weblogic-web-app">
<container-descriptor>
<prefer-web-inf-classes>true</prefer-web-inf-classes>
</container-descriptor>
</weblogic-web-app>
You need to configure an entityManagerFactory bean in your context.xml. Heres is an exemple using eclipselink as the JPA provider
<bean class="org.springframework.jdbc.datasource.DriverManagerDataSource"
id="dataSource">
<property name="driverClassName" value="${database.driverClassName}" />
<property name="url" value="${database.url}" />
<property name="username" value="${database.username}" />
<property name="password" value="${database.password}" />
</bean>
<bean
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
id="entityManagerFactory">
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean id="jpaAdapter"
class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter">
</bean>
</property>
</bean>
Just setting the provider isn't enough. You need to set the database connection data, like jdbc url, username and password. Did you set it? You also need to set the jdbc class name, as said, and the jdbc driver needs to be in your classpath.
If you are running this on a container and want to configure the datasource in weblogic, you can just refer to a jndi datasource from your hibernate cfg, but you will need to enter in the weblogic console and create a datasource and a connection pool there.
Look at hibernate docs on how to set the JNDI name in persistence.xml
My controllers are currently mapped to be something like http://example.com/fix.go and, of course, I think that's idiotic and want something nicer like http://example.com/fix or http://example.com/mmm/fix with no extension. When I try to configure this, however, I can't get it to work. I'm clearly missing a key part of understanding on the entire mapping. I'm using Spring 3.x, tomcat, and annotations for the controllers.
My web.xml is as follows:
<?xml version="1.0" encoding="UTF-8"?>
<web-app
version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<servlet>
<servlet-name>BooBoo</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>BooBoo</servlet-name>
<url-pattern>*.*</url-pattern> <!-- was *.go when it worked -->
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
BooBoo-servlet.xml is:
<?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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:component-scan base-package="com.foofoo.booboo"/>
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
And one of my controllers is configured as such:
#Controller
public class BangBangController extends BaseController {
// Used to be fix.go when it worked
#RequestMapping( value="fix", method=RequestMethod.GET )
public ModelAndView choose(
HttpSession session,
#RequestParam( value="fixId", required=false, defaultValue="-1" ) Integer fixId,
#RequestParam( value="forkId", required=false, defaultValue="-1" ) Integer forkId
)
throws Exception { ... }
}
I've tried changing the mapping in web.xml to /mmm/* expecting URLs like http://example.com/mmm/fix to work, but that too has not worked. I get "missing resource" errors when I enter what I think are the correct URLs in the browser.
What am I goofing up here? What critical piece of understanding do I lack? I've tried making the no extension thing work on another project at work, and couldn't get it to go there either. I'm obviously missing something.
The problem is your dispatcher servlet is matching anything with a "." in it.
Change it to
<url-pattern>/*</url-pattern>
However, that's also bad as you won't be able to serve static content.
What you really should do is this:
<url-pattern>/webapp/*</url-pattern>
Where "webapp" is some prefix. All of your URLs will need to be prefixed with it, but that allows you to still serve static content.
The answer was that I flubbed up the spring-servlet.xml file by not specifying that I was using the Spring MVC stuff. I appreciate Chris' help in diagnosing the issue. I needed confirmation that some of the things I tried (but failed because of this mistake) were correct.
I added
xmlns:mvc="http://www.springframework.org/schema/mvc"
and
<mvc:annotation-driven />
to that file, and boom, it started working. What leaves me scratching my head is, "How did it work without that?" Cuz it worked for *.go patterns.
Here's the resulting file in full:
<?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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:component-scan base-package="com.barbar.foofoo"/>
<!-- Enables the Spring MVC #Controller programming model -->
<mvc:annotation-driven />
<!--
Declare View Resolver: when view 'view_name' is called (from the Controller),
the file '/jsp/view_name.jsp' will be used.
-->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>