Getting persistence.xml error while integrating jBPM 5.4 into a J2EE web app - maven

I have been having trouble getting "jBPM integrated into a web app" while using Eclipse (Kepler). As a test I am simply trying to replicate the code found in the jBPM Full Installer's evaluation sample into the template code produced by a Maven JavaEE6 Archetype. I have noted my steps below so that the problem can be easily reproduced.
1) Add to the JBoss standalone.xml:
<datasource jndi-name="java:jboss/jdbc/jbpm-ds" pool-name="jBPMDS" enabled="true" use-java-context="true">
<connection-url>jdbc:h2:mem:test;DB_CLOSE_DELAY=-1</connection-url>
<driver>h2</driver>
<security>
<user-name>sa</user-name>
<password>sa</password>
</security>
</datasource>
2) JBoss Central > Maven Project > filter on "javaee6" (to create the "myservlet" Project):
Archetype = jboss-javaee6-webapp
Accept all defaults
3) Set src\main\resources\META-INF\persistence.xml to contain:
<?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="primary">
<!-- If you are running in a production environment, add a managed
data source, the example data source is just for proofs of concept! -->
<jta-data-source>java:jboss/datasources/ExampleDS</jta-data-source>
<properties>
<!-- Properties for Hibernate -->
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
<property name="hibernate.show_sql" value="false" />
</properties>
</persistence-unit>
</persistence>
4) Add a jBPM Runtime by pointing at the \runtime folder from the jBPM Full Installer.
5) Select the jBPM Perspective, right click the myservlet Project > Convert to jBPM Project.
6) Add to the Deployment Assembly the Java Build Path Entries > jBPM Library.
7) In src\main\java\com\mycompany\mywebapp\controller add to (arbitrarily chosen) MemberRegistration.java (which was automatically created as part of the Project) the following which comes from the evaluation sample code:
import java.util.HashMap;
import java.util.Map;
import org.drools.KnowledgeBase;
import org.drools.builder.KnowledgeBuilder;
import org.drools.builder.KnowledgeBuilderFactory;
import org.drools.builder.ResourceType;
import org.drools.io.ResourceFactory;
import org.drools.logger.KnowledgeRuntimeLogger;
import org.drools.logger.KnowledgeRuntimeLoggerFactory;
import org.drools.runtime.StatefulKnowledgeSession;
import org.jbpm.process.workitem.wsht.HornetQHTWorkItemHandler;
8) In this same module, in register() add the following which also comes from the evaluation sample code:
try {
// load up the knowledge base
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add(ResourceFactory.newClassPathResource("Evaluation.bpmn"), ResourceType.BPMN2);
KnowledgeBase kbase = kbuilder.newKnowledgeBase();
StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
HornetQHTWorkItemHandler humanTaskHandler = new HornetQHTWorkItemHandler(ksession);
humanTaskHandler.setIpAddress("127.0.0.1");
humanTaskHandler.setPort(5153);
ksession.getWorkItemManager().registerWorkItemHandler("Human Task", humanTaskHandler);
KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newThreadedFileLogger(ksession, "test", 1000);
// start a new process instance
Map<String, Object> params = new HashMap<String, Object>();
params.put("employee", "krisv");
params.put("reason", "Yearly performance evaluation");
ksession.startProcess("com.sample.evaluation", params);
System.out.println("Process started ...");
logger.close();
} catch (Throwable t) {
t.printStackTrace();
}
Upon deploying along with the six jBPM WARs we get this error:
...
Caused by: java.lang.IllegalArgumentException: JBAS011470: Persistence unitName was not specified and there are 2 persistence unit definitions in application deployment "myservlet.war". Either change the application to have only one persistence unit definition or specify the unitName for each reference to a persistence unit.
I have confirmed that there is exactly one persistence.xml file anywhere in the deployed myservlet folder (it is in jboss-as-7.1.1.Final\standalone\deployments\myservlet.war\WEB-INF\classes\META-INF).
Can someone explain what this error means and how to eliminate it?

My guess is that somewhere along all those configured .xml you made some mistake that's not that clear. I know how much a pain in the a** that can be. I've written a small tutorial on how to configure persistence for JBPM using JBoss AS here. I suggest you follow it step by step to re-configure your project.
Hope it solves your problem!

Related

Change mongo dbname through build script

What do I want:
I want to set up an automated deployment pipeline - my plan is as follows:
I create two .war files, let's call them prod.war and test.war, using a gradle build script, and deploy them to my tomcat server.
My problem:
The prod.war needs to access the production database (mongoprod), and the test.war to the test database (mongotest).
My attempt:
I thought I could use Spring profiles and simply...
...change a line in my application-context.xml from:
<mongo:db-factory id="mongoDbFactory" dbname="mongoprod"/>
to:
<mongo:db-factory id="mongoDbFactory" dbname="${mongo.db.name}"/>
...create two files, in the same folder (<filename>:<content>):
application-production.properties:mongo.db.name=mongotest
application-test.properties:mongo.db.name=mongoprod
...execute some gradle build script with an argument that can change the profile to production or test and then use the corresponding .property file to insert the desired mongo dbname...but that's where I ran out of luck!
I tried to add this to my build.gradle file:
bootRun { args = ["--spring.profiles.active=" + profiles] }
and then run it with $ ./gradlew bootRun -Ptest
but I just get the error:
Main class name has not been configured and it could not be resolved
and besides that I haven't used bootRun before, only a war task so far to create my .war files:
war {
archiveName = 'application.war'
dependsOn 'lessc', 'webpack'
from "$buildDir/webapp"
exclude 'WEB-INF/js/main.js'
rename 'main\\.min\\.js', 'main.js'
}
Does anyone know how I can get my problem to work or could give me useful information on this?
You need to provide a main class name to be run by the bootRun task, for example as follows:
springBoot {
mainClassName = 'org.baeldung.DemoApplication'
}
You can read more about it in thos tutorial
Update:
configuration for application plugin could be done as follows
application {
mainClassName = 'org.gradle.sample.Main'
}
As it's said in the plugin docs
I found out that for my case it turned out to be much easier (and I think better) to decide during runtime wether a test or a production DB should be used and I solved it the following way:
In my application-context.xml I created two beans instead of one, one for each DB (I had to nest them below a "root"-beans, otherwise I got errors during building):
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mongo="http://www.springframework.org/schema/data/mongo"
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
http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo-1.5.xsd">
<beans profile="prod">
<mongo:db-factory id="mongoDbFactory" dbname="mongoprod"/>
<mongo:mapping-converter id="mongoConverter" base-package="my.company.project">
<mongo:custom-converters base-package="my.company.project"/>
</mongo:mapping-converter>
<mongo:gridFsTemplate bucket="images" converter-ref="mongoConverter" db-factory-ref="mongoDbFactory"/>
</beans>
<beans profile="test">
<mongo:db-factory id="mongoDbFactory" dbname="mongotest"/>
<mongo:mapping-converter id="mongoConverter" base-package="my.company.project">
<mongo:custom-converters base-package="my.company.project"/>
</mongo:mapping-converter>
<mongo:gridFsTemplate bucket="images" converter-ref="mongoConverter" db-factory-ref="mongoDbFactory"/>
</beans>
</beans>
In order for the .war file creation to work properly I had to set enabled to true in my build.gradle file here:
war {
enabled = true //without this no .war file was created before - https://stackoverflow.com/a/52315049/4120196
dependsOn 'lessc', 'webpack'
from "$buildDir/webapp"
exclude 'WEB-INF/js/main.js'
rename 'main\\.min\\.js', 'main.js'
}
I then created a .war file, copied it and renamed it - so I had two: prod.war and test.war and put them into my Tomcat 8.5_Tomcat8.5.23\webapps folder (I'm working on Win10 in case this differs on other systems). Then I created two .xml files with the same name as the .war files where I defined the spring profile that decides which bean to take in Tomcat 8.5_Tomcat8.5.23\conf\Catalina\localhost:
prod.xml
<Context>
<Environment name="spring.profiles.active" value="prod" type="java.lang.String" override="false" />
</Context>
test.xml
<Context>
<Environment name="spring.profiles.active" value="test" type="java.lang.String" override="false" />
</Context>
I started up tomcat and finally everything worked as I wanted it to.
If you have any hints how my solution can be improved feel free to comment :)
I feel like my application-context.xml could be shortened somehow for example...

NoSuchMethodError in Jetty with Spring Data Mongo custom repository

I have a small web application in development using Maven, Spring MVC and Spring Data Mongo. I am getting a java.lang.NoSuchMethodError when one of my Controllers attempts to access a method defined in a custom repository. The same method works fine when exercised via a JUnit 4 test extending AbstractJUnit4SpringContextTests and using a near-identical XML configuration file.
Standard repository:
public interface IndividualRepository extends MongoRepository<Individual, String>, IndividualRepositoryCustom {
...
}
Custom interface:
public interface IndividualRepositoryCustom {
Individual findByIdentifier(String identifierType, String identifierValue);
}
Custom implementation:
public class IndividualRepositoryImpl implements IndividualRepositoryCustom {
#Autowired
private MongoTemplate mongoTemplate;
#Override
public Individual findByIdentifier(String identifierType, String identifierValue) {
String locator = String.format("identifiers.%s", identifierType);
return mongoTemplate.findOne(query(where(locator).is(identifierValue)), Individual.class);
}
}
dataaccess-config.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"
xmlns:mongo="http://www.springframework.org/schema/data/mongo"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/data/mongo
http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd">
<mongo:repositories base-package="com.myco.dataaccess"/>
<mongo:mongo host="mongo.myco.com" port="27017"/>
<mongo:db-factory dbname="test" mongo-ref="mongo"/>
<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg ref="mongo"/>
<constructor-arg value="test"/>
</bean>
</beans>
In my JUnit test I have (excerpt):
#Autowired
private IndividualRepository individualRepo;
...
List<Individual> foundList = individualRepo.findAll();
assertNotNull(foundList);
assertTrue(foundList.size() > 0);
Individual found = individualRepo.findByIdentifier("someid", "123456");
assertNotNull(found);
assertEquals("Bob", found.getFirstName());
The test passes fine, calling both findAll() (standard Repository method) and findByIdentifier() (custom method). The latter fails with NoSuchMethodError when called by a Controller running in a web application in Jetty, while the same Controller can call findAll() with no issues.
This turned out to be nothing to do with Spring Data, but an issue with the way I was using the maven-jetty-plugin with my multi-module build.
Basically, I was running mvn jetty:run for my web module which had a dependency on my dataaccess module (where my JUnit tests lived). As I was rebuilding the project with mvn clean package, the latest versions were not being placed in my local repo, and therefore were not being picked up by the mvn jetty:run process running alongside my build process. Problem was solved by building with mvn clean install.
So, as usual, the error message was spot on - the method indeed did not exist in the version of the JAR that Jetty was being supplied.

Tomcat 7 - Spring 3.2.1 - OpenJPA No persistent class is specified in eager initialization mode

I'm trying to get a simple web app called Debugger running under Tomcat 7 using Spring 3.2.1 and OpenJPA. I use Eclipse as the IDE and run Tomcat external to the IDE. I'm getting a error when the WAR is being deployed. This is the error message:
org.apache.openjpa.persistence.ArgumentException: No persistent class is specified in eager initialization mode.
Here is the persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--
-->
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
version="2.0">
<persistence-unit name="applicationDB" transaction-type="RESOURCE_LOCAL">
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
<properties>
<property name="openjpa.jdbc.SchemaFactory" value="native(ForeignKeys=true)"/>
<property name="openjpa.InitializeEagerly" value="true"/>
<property name="openjpa.DynamicEnhancementAgent" value="false"/>
</properties>
</persistence-unit>
</persistence>
Is the error caused by not having any classes specified in this file? I'm just trying to get a base application configuration setup so I'm not yet ready to place any classes in the persistence file. Maybe you have to have at least one?
Either list your persistent classes, or remove the openjpa.InitializeEagerly property.

Weird behaviour of import tag in spring's configuration file

I am working on the spring spring-3.2.2. I have created two java projects in eclipse.
SpringTest
Testclasspath
SpringTest project is having the below beans.xml in which the one bean is defined.
<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">
<bean id="helloWorld" class="com.spring.HelloWorld" init-method="testUpdate" scope="prototype">
<property name="message" value="Hello World!"/>
</bean>
</beans>
I have created the jar springtest.jar of the project SpringTest and it is been added in the classpath of the project Testclasspath. Bean configuration file for the Testclasspath project is talentacquisition.xml and it is importing the beans.xml file of the Springtest project. Please find the below content of talentacquisition.xml
<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">
<import resource="Beans.xml"/>
<bean id="juggler" class="com.springaction.springidol.Juggler" />
</beans>
I am confused with behavior of the import tag in the talentacquisition.xml How it is able to locate the Beans.xml which is present in the jar (springtest.jar) in the classpath and able to load the beans? Why spring is not giving any error ? Don't I have to modify the import tag in the talentacqusition.xml to following
<import resource="classpath:Beans.xml"/>
If import is able to locate the file Beans.xml , then when should we use classpath: and classpath* :?
ResourceLoaders are responsible for how Spring loads the resource. From the reference manual
The location path or paths supplied to an ApplicationContext
constructor are actually resource strings, and in simple form are
treated appropriately to the specific context implementation.
ClassPathXmlApplicationContext treats a simple location path as a
classpath location. You can also use location paths (resource strings)
with special prefixes to force loading of definitions from the
classpath or a URL, regardless of the actual context type.
The ClassPathXmlApplicationContext you're instantiating "treats a simple location path as a classpath location", i.e. it treats "Beans.xml" as "classpath:Beans.xml". Similarly, FileSystemXmlApplicationContext would treat "Beans.xml" as "file:Beans.xml".
Section 6.7 of the manual has more details too.

Webapp cannot find Persistence Unit. No persistence unit named 'X' is available in scope

I am trying to run my webapp on my weblogic 12c server using EJB 3.1, JPA 2.0, M2E-WTP, and JSF 2.1 technologies and continue to get the following error:
javax.ejb.EJBException: EJB
Exception: : java.lang.IllegalArgumentException: No persistence unit named 'X'
is available in scope Webapp. Available persistence units: [] at
weblogic.persistence.ModulePersistenceUnitRegistry
.getPersistenceUnit(ModulePersistenceUnitRegistry.java:130) at
weblogic.persistence.BasePersistenceContextProxyImpl
.<init>(BasePersistenceContextProxyImpl.java:40) at
weblogic.persistence.TransactionalEntityManagerProxyImpl
.<init>(TransactionalEntityManagerProxyImpl.java:31) at
weblogic.persistence.EntityManagerInvocationHandlerFactory.
createTransactionalEntityManagerInvocationHandler
(EntityManagerInvocationHandlerFactory.java:20) at
weblogic.persistence.PersistenceManagerObjectFactory
.createPersistenceContextProxy(PersistenceManagerObjectFactory.java:66) at
weblogic.persistence.PersistenceManagerObjectFactory
.getObjectInstance(PersistenceManagerObjectFactory.java:31) at
javax.naming.spi.NamingManager.getObjectInstance(NamingManager.java:304)
at weblogic.jndi.internal.WLEventContextImpl.lookup(WLEventContextImpl.java:251) at
weblogic.jndi.internal.WLContextImpl.lookup(WLContextImpl.java:406) at
weblogic.j2eeclient.java.ClientReadOnlyContextWrapper.lookup
This is the EJBBean that is triggering the exception
#Stateless
public class QuoteSessionEJB implements QuoteSessionEJBLocal {
/**
* Default constructor.
*/
public QuoteSessionEJB() {
// TODO Auto-generated constructor stub
}
#PersistenceContext(unitName="X")
private EntityManager em;
/**
* Returns a list of Quote objects in the database
* #return List<Customer>
*/
public List<Quote> getQuote() {
Query query = em.createNamedQuery("findQuotes");
return query.getResultList();
}
}
Here is the persistence.xml file which is located under src/main/java --> META-INF which eclipse built.
<?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="X" transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>localJTA</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="eclipselink.target-server" value="WebLogic"/>
<property name="eclipselink.logging.level" value="FINEST"/>
</properties>
</persistence-unit>
</persistence>
I have spent hours searching the web for answers with no avail. I don't understand why the persistence unit X in my persistence.xml cannot be located...
I'm hoping someone has ran into this same problem or know hows to fix it.
Any help is greatly appreciated!
Update: Per better_use_mkstemp comment below I moved the META-INF folder containing my persistence.xml from src/main/java to WEB-INF/classes. I have to create the classes folder in eclipse. This worked! Much appreciated!
Following up question: Doing some more research I found that putting the META-INF folder in src/main/resources would also solve the problem, however it did not. I dont know if this is an issue with Maven's M2E-WTP eclipse plugin or I am simply misunderstanding something here. Below is a screen shot of the folder structure.
By browsing the war file the maven install command creates, I can see that the META-INF folder IS correctly placed in the WEB-INF/classes folder. But simply publishing to the server within Eclipse does not work. Unless I manually create the classes folder under WEB-INF and manually drop/move the META-INF folder in there I can't get it to work inside the IDE. Also it doesn't seem to make sense to have a copy of the META-INF folder in two places as a solution.
try to replace in your persistence.xml:
<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">
for:
<persistence version="1.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_1_0.xsd">

Resources