TomEE Share Persistence among different applications - java

Supposing I have a jar with the persistence.xml configuration and the jpa entities.
I would like to have the same persistence unit shared among different applications.
For example deploy a war application and have the same persistence unit (that other applications use) injected.
#PersistenceContext(unitName="MySharedPersistence")
private EntityManager entityManager;
I can not consider packaging all the applications in an ear file since I want to have the other applications up and running while I reupload an application (the application reuploaded uses some remote ejbs from the already deployed applications and uses the same persistence unti as described above).
Are there any solutions to this problem?
Thank you in advance.
EDIT: Probably It is not recomended are there any appropriate tryouts with the same result?

You can place your Entity classes and your persistence.xml in a jar, and reuse this jar in all projects. As long as you also include a beans.xml file along with your persistence.xml, it should work just fine. You should then be able to inject the persistence context in any project that uses this jar file.
You need the beans.xml file for autodiscovery by the container. For reference, here's how a beans.xml file would look:
<?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"
xsi:schemaLocation="
http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
</beans>

Related

Weblogic JPA 2.1 Hibernate 4 Not Working java.lang.NoSuchMethodError

I've run into the classic issue of trying to run a web app on a weblogic server and running into errors because of the weblogic server having old copies of classes.
The main issue I run into is when trying to use JPA 2.1 I get the following issue:
weblogic.application.ModuleException: java.lang.NoSuchMethodError: javax.persistence.Table.indexes()[Ljavax/persistence/Index;
The obvious answer here is that it is using the JPA version on the server which does not have that class.
I've set my weblogic.xml file to the following:
<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/web-app_2_5.xsd http://xmlns.oracle.com/weblogic/weblogic-web-app http://xmlns.oracle.com/weblogic/weblogic-web-app/1.7/weblogic-web-app.xsd">
<wls:weblogic-version>12.1.3</wls:weblogic-version>
<wls:jsp-descriptor/>
<wls:debug>true</wls:debug>
</wls:jsp-descriptor>
<wls:container-descriptor>
<wls:prefer-web-inf-classes>true</wls:prefer-web-inf-classes>
</wls:container-descriptor>
<wls:context-root>DiscoveryPortal</wls:context-root>
</wls:weblogic-web-app>
With the key line being:
prefer-web-inf-classes: true
This seems to work for some classes but not all.
Weblogic 12c (supposedly) allows class filtering in both .war and .ear files. I would recommend moving from:
<wls:container-descriptor>
<wls:prefer-web-inf-classes>true</wls:prefer-web-inf-classes>
</wls:container-descriptor>
to:
<prefer-application-packages>
<package-name>javax.persistence.*</package-name>
</prefer-application-packages>
<prefer-application-resources>
<resource-name>javax.persistence.*</resource-name>
<resource-name>META-INF/services/javax.servlet.ServletContainerInitializer</resource-name>
</prefer-application-resources>
The filtering seems to work much better than prefer-web-inf-classes.
See the Oracle docs here that says it works for .war files. If not, you may consider switching to an .ear to see what happens.
Placing following code into weblogic.xml
<container-descriptor>
<prefer-application-packages>
<package-name>javax.persistence.*</package-name>
</prefer-application-packages>
</container-descriptor>
seems to be enough for related expection, on WebLogic Server 12.1.2.0 if you have JPA 2.1 jar on your classpath.
Official answer: "While WebLogic Server 12.1.3 supports JPA 2.1, the Java Archive (JAR) files are not configured by default; some additional configuration is required to enable JPA 2.1 support. In this tutorial, the JPA 2.1 implementation is configured on the WebLogic Server classpath."
And solution for weblogic is here: http://www.oracle.com/webfolder/technetwork/tutorials/obe/fmw/wls/12c/01-06-004-JavaEE7andWebLogicServer/javaee7.html
you need to add:
PRE_CLASSPATH=/YOUR_MIDDLEWARE_HOME/oracle_common/modules/javax.persistence_2.1.jar:/YOUR_MIDDLEWARE_HOME/wlserver/modules/com.oracle.weblogic.jpa21support_1.0.0.0_2-1.jar
export PRE_CLASSPATH
to setDomainEnv.sh which is located in your domain folder under 'bin' directory.
so you have inconsistent JPA API jar and Hibernate jars in the CLASSPATH.
JPA API 2.1 brought in that method and Hibernate 4.3 would be required to support that IIRC
I confirm that <wls:prefer-web-inf-classes>true</wls:prefer-web-inf-classes> doesn't work with WebLogic12/Spring4/Hibernate4/HibernateValidator5/JPA2.1,
you have to resort to <prefer-application-packages> but listing only java.persistence.* is far to be enough...
You have also to list:
javassist.*
org.hibernate.*
org.hibernate.validator.*
javax.validation.*
+
any other ones the Class Loader Analysis Tool will recommend you to include
+
include a ServletContextListener filter in your web.xml to register an "HibernatePersistencerProviderResolver implements PersistenceProviderResolver" that will return an singleton Collection holding an HibernatePersistenceProvider when called "getPersistenceProviders()"
if you are using Spring
in your Spring applicationContext to support method validation:
you need a bean "validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"
and another one
class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor"
for your entityManager (class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean") jpaProperties:
<prop key="java.persistence.transactionType">jta</prop>
<prop key="hibernate.transaction.jta.platform">org.hibernate.engine.transaction.jta.platform.internal.WebLogicJtaPlatform</prop>
<prop key="hibernate.event.merge.entity_copy_observer">allow</prop>
if you are using maven, in your pom.xml (if using another build system refer to its doc to do the equivalent set-up)
you have to exclude org.jboss.spec.javax.transaction:jboss-transaction-api_1.1_spec from the dependencies org.hibernate:(hibernate-core and hibernate-entitymanager)
and then add it org.jboss.spec.javax.transaction:jboss-transaction-api_1.1_spec but as a "provided" independent dependency.
and last but not least…
DON'T use a persistence.xml !
not only with a LocalContainerEntityManagerFactoryBean you don't need it anymore but it will mess-up with WebLogic too and if you need to generate a DDL you can't use hbm2ddl anymore since the hibernate maven plugin is no more compatible with JPA2.1, you have to use an EntityManagerFactoryBuilder.generateSchema()... (not Persistence.generateSchema(...) as you will find when googling: this doesn't work without a persistence.xml...)

How to validate beans.xml using a local XSD?

In my application, I have some beans.xml files (for eeach module). each of these files contains required XSD declarations :
<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"
xsi:schemaLocation="
http://java.sun.com/xml/ns/javaee http://docs.jboss.org/cdi/beans_1_0.xsd
http://jboss.org/schema/weld/beans http://jboss.org/schema/weld/beans_1_1.xsd">
Yesterday, due to some JBoss.org outage, schema files were unavailable, and as a consequence my beans.xml couldn't correctly validate.
It didn't prevent the project from validating, but slowed down project build (due to weld usage in tests, mainly).
So, what is a the solution, when using Weld 1.1.5 as CDI implementation, to not validate beans.xml during compilation, or to use a local XSD file (and if so, how to declare it, and where to put it in a maven project) ?
Just spoke with Pete Muir. He said its a bug. Would you mind creating a JIRA ticket please?

Not able to deploy EJB in WebLogic server 12c

I have created a EJB, created a jar of it( containing required ejb-jar.xml and weblogic-ejb-jar.xml files).
when i add this jar to weblogic server 12c, using admin console, i get following issue-
Issues were encountered while parsing this deployment to determine module type. Assuming this is a library deployment.
Due to this my ejb is not shown in jndi tree view. So I am not able to do my jndi lookup. Please rectify my error.
ejb-jar.xml-
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN" "http://java.sun.com/dtd/ejb-jar_2_0.dtd">
<ejb-jar id="ejb-jar_ID">
<display-name>ProductManager</display-name>
<enterprise-beans>
<session>
<ejb-name>Product</ejb-name>
<home>rohit.ProductHome</home>
<remote>rohit.ProductRemote</remote>
<ejb-class>rohit.ProductBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
</session>
</enterprise-beans>
<ejb-client-jar>ProductManagerClient.jar</ejb-client-jar>
</ejb-jar>
weblogic-ejb-jar.xml-
<?xml version=“1.0? encoding=“UTF-8??>
<weblogic-ejb-jar
xmlns=“http://www.bea.com/ns/weblogic/90? xmlns:j2ee=“http://java.sun.com/xml/ns/j2ee” xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance” xsi:schemaLocation=“http://www.bea.com/ns/weblogic/90 http://www.bea.com/ns/weblogic/90/weblogic-ejb-jar.xsd”>
<welogic-enterprise-bean>
<ejb-name>Product</ejb-name>
<jndi-name>Product</jndi-name>
<stateless-session-descriptor></stateless-session-descriptor>
</welogic-enterprise-bean>
</weblogic-ejb-jar>
Contrary to what you seem to be thinking, the ejb-jar.xml and weblogic-ejb-jar.xml files are not required. As primary deployment descriptors they are ancient artifacts from 2004.
Your ProductHome class should also be removed if you value your sanity. This is an EJB2 artifact that's completely and utterly unnecessary this time of age.
To get started with EJB, all you need is a POJO with an #Stateless annotation:
#Stateless
public class ProductBean {
// ...
}
Jar this up and deploy it. That's all. You don't have to explicitly name your bean (it will get a name) and you certainly don't have to declare its existence in some XML file.
The ejb-jar.xml is mandatory when deploying an application as a jar file. The correct place to put it is in the META-INF in the jar.
Yes, annotations are definitely nice and easier to maintain. Try this by leaving the ejb-jar.xml minimal.
I always package my applications in EAR with the jars inside. In this case an application.xml file is needed.
It sounds like the container does not recognize the jar as an application. Check the position of the ejb-jar.xml or use EAR packaging.
Oracle recommends that even standalone EJBs be packed as an EAR file. The EJB descriptors should be inside the META-INF of the ejb-module.
See this link for the EAR structure for more details.
http://docs.oracle.com/cd/E24329_01/web.1211/e24368/splitcreate.htm#i1103260

How to reference JSF managed beans which are provided in a JAR file?

I have a WAR file with the following structure:
The JSF managed bean BusinessObjectTypeListController is located in commons-web-1.0.jar in /WEB-INF/lib and referenced in BusinessObjectTypeListView.xhtml. When I run my web application and I call that view, I get the following error:
javax.servlet.ServletException: /view/common/businessObjectTypeListView.xhtml #34,94 listener="#{businessObjectTypeListController.selectData}": Target Unreachable, identifier 'businessObjectTypeListController' resolved to null
Why isn't the controller class found? It should be in the classpath, is it?
You need to have a JSF 2.0 compliant /META-INF/faces-config.xml file in the commons-web-1.0.jar file in order to get JSF to scan the JAR file for classes with JSF annotations like #ManagedBean and auto-register them.
<?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>
JSF does namely not scan every class of every single JAR file in the classpath, that would have been too expensive. Only JARs with the above /META-INF/faces-config.xml file will be scanned.
You should also ensure that you do not have the metadata-complete="true" attribute in the <faces-config> declaration of webapp's own /WEB-INF/faces-config.xml file, otherwise JSF will assume that this faces config is complete and therefore won't auto-scan JAR files for annotations.
If none of those conditions are (or can be) met, then you need to manually register the bean as <managed-bean> in webapp's own /WEB-INF/faces-config.xml instead of relying on annotations.
See also chapter 11.4.2 of JSF 2.0 specification (emphasis mine).
11.4.2 Application Startup Behavior
...
This algorithm provides considerable flexibility for developers that are assembling the components of a JSF-based web
application. For example, an application might include one or more custom UIComponent implementations, along with
associated Renderers, so it can declare them in an application resource named “/WEB-INF/faces-config.xml”
with no need to programmatically register them with Application instance. In addition, the application might choose
to include a component library (packaged as a JAR file) that includes a “META-INF/faces-config.xml” resource.
The existence of this resource causes components, renderers, and other JSF implementation classes that are stored in this
library JAR file to be automatically registered, with no action required by the application.
I have same problem with CDI beans in my case.
I have common.jar project where i placed the CDI beans. (without beans.xml)
and
I have webapp.war that contains common.jar in it`s lib and beans.xml.
when i call a cdi bean from jsf, i get it is not reachable exception:/
project structure is created using maven :
- maven-archetype-quickstart for common.jar
- maven-archetype-webapp for webapp.war
I am using eclipse/juno en deploy to Glassfish 3.1.x.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Resolved:
For EJB and JAR packaging you should place the beans.xml in src/main/resources/META-INF/.
For WAR packaging you should place the beans.xml in src/main/webapp/WEB-INF/.
Remember that only .java files should be put in the src/main/java and src/test/java directories. Resources like .xml files should be in src/main/resources.
from topic:
CDI: beans.xml, where do I put you?
In my opinion the class BusinessObjectTypeListController is founded properly but does not instantiated.
How you create the instance of class on a view? If you use a BeanFactory review the config xml files

Resolution should not happen via injection container error

I have an EJB3 project to be deployed on JBoss 5.1.0 GA. I have Stateless EJBs being injected into other Stateless beans and Servlets.
I'm using the #EJB annotation without any parameters to inject the EJB beans, (i have a test project just to simulate the injection, which works).
When i try deploying i get the error below.
"Caused by: java.lang.RuntimeException: java.lang.IllegalStateException: Resolution should not happen via injection container"
I have searched but can't seem to find/pinpoint the cause of the error.
Update: 1
Both the EJB jar and WAR are deployed in the same EAR. I'm using the JEE5 archtype, http://code.google.com/p/javaee5-maven-archetype/ to create both the main project and test. The default code generated by the archtype works, and there is no need to specify the JNDI name in the #EJB injection.
Update: 2
The full deployment stacktrace, http://pastebin.com/CknXie13
Here's an oft overlooked gotcha: Make sure that you use the name of the Local Interface and not the implementation when declaring the class type of the EJB in the servlet or web service. So, the mappedName in JBOSS will point to the jndi binding for the implementation while the class type in the declaration will point to the interface. For example:
#EJB(mappedName="Foo/EmployeeManagerBean/local")
EmployeeManagerLocal manager;
Gotcha #2: Make sure that you are compiling with Java 1.6 or higher. This can be tricky in Eclipse. You have to check three places in Project->Properties to make sure: Project Facets, compiler compliance settings, and the build path.
Use the mappedName attribute of #EJB annotation, while injecting into the servlet
The attribute should contain the jndi name of the ejb.
Please check your web.xml version. Version 2.4 or earlier does not support dependency injection.
Here is the sample excerpt of version="2.5"
<?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">
Are you putting your servlet in .WAR file? Put your servlet in .WAR file and your bean in .JAR file. Create and ear file and then deploy it
Known Issue;
http://community.jboss.org/message/8196#8196
https://jira.jboss.org/browse/JBAS-6332

Categories