drools #KSession throws exception when using kmodule in separate jar - drools

using Drools 6.2.0.Final
i am using drools with a kmodules.xml and decisiontable inside a separate jar file. when i attempt to bind the #KSession to the spring application context it throws an nullpointer exception deep inside the annotation.
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'oft.onlineservice.business.FeeRulesEngineTest': Injection of kie dependencies failed; nested exception is java.lang.NullPointerException
at org.kie.spring.annotations.AnnotationsPostProcessor.postProcessPropertyValues(AnnotationsPostProcessor.java:109)
using a simple junittest shows the problem.
public class FeeRulesEngineTest {
#KSession( "ksession1")
private StatelessKieSession ksession;
#KBase("feeDecisionTable")
private KieBase kbase;
the kmodule.xml
<kmodule xmlns="http://jboss.org/kie/6.0.0/kmodule">
<kbase name="feeDecisionTable" packages="oft.rulesengine" default="true">
<ksession name="ksession1" type="stateless" default="true" >
</ksession>
</kbase>
</kmodule>
the spring config is using the annonation postprocessor.
<kie:import />
<bean id="kiePostProcessor"
class="org.kie.spring.annotations.KModuleAnnotationPostProcessor"/>
my curent work around to is to use #Autowire for the KSession and KBase.
any idea what i am doing wrong?
thanks
-lp

It's a bug in Kie Services / Spring integration. The annotation assumes there's always a ReleaseId.
I created a Pull Request some weeks ago, so it should be solved in an upcoming version.
Ticket link: https://issues.jboss.org/browse/DROOLS-845

Related

Spring Integration Message Driven Channel Adapter not working with Spring-Kafka 2.3+

I am getting the following issues when trying to get Message Driven Channel Adaptor working with Spring-Kafka 2.3+. Does anyone have any example code which would help me?
1. org.springframework.kafka.listener.config.ContainerProperties does not actually exist.
2. org.springframework.kafka.listener.ContainerProperties does exist but produces the below issue when trying to run.
Description:
An attempt was made to call a method that does not exist. The attempt was made from the following location:
org.springframework.integration.kafka.inbound.KafkaMessageDrivenChannelAdapter.onInit(KafkaMessageDrivenChannelAdapter.java:318)
The following method did not exist:
org.springframework.kafka.listener.ContainerProperties.isDeliveryAttemptHeader()Z
3. This issue goes if you use kafka version 2.5 and above but is instead replaced by
2021-03-22 13:56:05.102-0400 org{local_sparta} WARN [data-pipeline,,,] [DP-ACCOUNT] [DPA] [] AnnotationConfigServletWebServerApplicationContext:main Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.boot.autoconfigure.kafka.KafkaAnnotationDrivenConfiguration': Bean instantiation via constructor failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.boot.autoconfigure.kafka.KafkaAnnotationDrivenConfiguration]: Constructor threw exception; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'kafkaTemplate' defined in class path resource [org/springframework/boot/autoconfigure/kafka/KafkaAutoConfiguration.class]: Unsatisfied dependency expressed through method 'kafkaTemplate' parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.kafka.core.ProducerFactory<java.lang.Object, java.lang.Object>' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
Tried both with a Java Version and an XML version below both give same error.
Java Version
#Configuration
#Slf4j
public class KafkaChannelConsumer {
#Autowired
MessageChannel preRouterLOB;
#Value("${spring.kafka.bootstrap-servers:localhost9092}")
private String bootstrapServers;
#Value("${spring.kafka.topic:55iptest}")
private String springIntegrationKafkaTopic;
#Bean
public KafkaMessageDrivenChannelAdapter kafkaMessageDrivenChannelAdapter() {
KafkaMessageDrivenChannelAdapter kafkaMessageDrivenChannelAdapter = new KafkaMessageDrivenChannelAdapter(
kafkaListenerContainer());
kafkaMessageDrivenChannelAdapter.setOutputChannel(preRouterLOB);
return kafkaMessageDrivenChannelAdapter;
}
#SuppressWarnings("unchecked")
#Bean
public ConcurrentMessageListenerContainer kafkaListenerContainer() {
ContainerProperties containerProps = new ContainerProperties(springIntegrationKafkaTopic);
return (ConcurrentMessageListenerContainer) new ConcurrentMessageListenerContainer(
consumerFactory(), containerProps);
}
#Bean
public ConsumerFactory consumerFactory() {
return new DefaultKafkaConsumerFactory(consumerConfigs());
}
#Bean
public Map consumerConfigs() {
Map properties = new HashMap();
properties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers);
properties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
properties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
properties.put(ConsumerConfig.GROUP_ID_CONFIG, "dummy");
return properties;
}
}
XML Version
<?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:tx="http://www.springframework.org/schema/tx" xmlns:jms="http://www.springframework.org/schema/integration/jms"
xmlns:int-kafka="http://www.springframework.org/schema/integration/kafka"
xmlns:int="http://www.springframework.org/schema/integration"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/integration/jms http://www.springframework.org/schema/integration/jms/spring-integration-jms.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/kafka http://www.springframework.org/schema/integration/kafka/spring-integration-kafka.xsd">
<int-kafka:message-driven-channel-adapter
id="kafkaListener"
listener-container="container1"
auto-startup="false"
phase="100"
send-timeout="5000"
mode="record"
channel="someChannel"
error-channel="errorChannel" />
<bean id="container1" class="org.springframework.kafka.listener.KafkaMessageListenerContainer">
<constructor-arg>
<bean class="org.springframework.kafka.core.DefaultKafkaConsumerFactory">
<constructor-arg>
<map>
<entry key="bootstrap.servers" value="localhost:9092" />
</map>
</constructor-arg>
</bean>
</constructor-arg>
<constructor-arg>
<bean class="org.springframework.kafka.listener.config.ContainerProperties">
<constructor-arg name="topics" value="foo" />
</bean>
</constructor-arg>
</bean>
POM for issue 1 and 2
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-kafka</artifactId>
<version>5.4.5</version>
</dependency>
This includes version Spring-Kafka 2.3.6
POM for issue 3
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-kafka</artifactId>
<version>5.4.5</version>
<exclusions>
<exclusion>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
<version>2.6.7</version>
</dependency>
<version>5.4.5</version>
This includes version Spring-Kafka 2.3.6
No it does not; the 5.4.x versions of spring-integration-kafka require 2.6.x; that method was added to the properties in 2.5.
See the project page for compatible versions.
https://spring.io/projects/spring-kafka
If you are using Spring Boot, it will bring in all of the right versions, and you should not specify versions at all in your pom.
For problem 3, it looks like you have a producer factory declared somewhere that is not compatible with the kafka template bean.
It looks like you are messing around with different versions.
Since your project is based on the Spring Boot, you definitely have to rely on versions for dependencies it provides. Some version combinations are indeed not going to be compatible. For example that deliveryAttemptHeader property for the ContainerProperties has been introduced starting with 2.5:
/**
* Set to true to populate the
* {#link org.springframework.kafka.support.KafkaHeaders#DELIVERY_ATTEMPT} header when
* the error handler or after rollback processor implements
* {#code DeliveryAttemptAware}. There is a small overhead so this is false by
* default.
* #param deliveryAttemptHeader true to populate
* #since 2.5
*/
public void setDeliveryAttemptHeader(boolean deliveryAttemptHeader) {
Just make sure that you rely on Spring Boot plugin and its dependency management. All the deps in Spring Boot are tested together. Only the problem you are going to have when you try to change deps int your own versions.

TestContext always Null

Is there any way I can inject TestContext in my cucumber step class?
I am using citrus, spring, and cucumber together with the latest version. But when I use the below injection I always get null pointer exception of the TestContext. For TestDesigner and TestRunner I have no issue to get.
#CitrusResource private TestContext tContext;
and in the log i am seeing
Failed to get proper TestContext from Cucumber Spring application context: No qualifying bean of type 'com.consol.citrus.context.TestContext' available
You are obviously using the setting
cucumber.api.java.ObjectFactory=cucumber.runtime.java.spring.CitrusSpringObjectFactory
in the cucumber.properties.
When doing so you need to manually add the Citrus Spring configuration with #ContextConfiguration annotation on your steps class.
#ContextConfiguration(classes = CitrusSpringConfig.class)
public class MySteps {
#CitrusResource
private TestDesigner designer;
[...]
}
In case you are using the default cucumber.xml Spring XML application context you need to add the Citrus Spring config as bean to that file:
<!-- JavaConfig bean post-processor -->
<bean class="org.springframework.context.annotation.ConfigurationClassPostProcessor"/>
<!-- Citrus Java config -->
<bean id="citrusSpringConfig" class="com.consol.citrus.config.CitrusSpringConfig"/>

Error Injecting the JPA Entity Manager in WebSphere Liberty

I have inherited a legacy application that initially was built with WebSphere 6.1 and then was migrated to WebSphere 8.0 running with JPA 2.0 and openJPA without issues. We are migrating to WebSphere Liberty for strategic reasons. We first tested on WebSphere Classic 8.5.5.8 and JPA and the entity manger has no issues there. However, on Liberty 8.5.5.8 I get the following exception:
javax.ejb.EJBException: The java:comp/env/com.xxx.xxxx.service.CHServiceBean/em reference of type javax.persistence.EntityManager for the CHServiceBean component in the CHServiceEJB.jar module of the CHServiceEAR application cannot be resolved.
at com.ibm.wsspi.injectionengine.InjectionBinding.getInjectionObject(InjectionBinding.java:1493)
.....
[err] Caused by:
[err] javax.ejb.EJBException: The java:comp/env/com.xxxx.xxxx.service.CHServiceBean/em reference of type javax.persistence.EntityManager for the CHServiceBean component in the CHServiceEJB.jar module of the CHServiceEAR application cannot be resolved.
[err] at com.ibm.wsspi.injectionengine.InjectionBinding.getInjectionObject(InjectionBinding.java:1493)
[err] at [internal classes]
I had another EJB injection issue that was resolved through configuration of the binding files, however I am unable to resolve this issue. I have two applications that each have their own EAR files but both run in the same Liberty JVM. Application A runs the front end/UI logic while Application B is the back-end EJB / JPA interfaces. In the project facets the JPA application is set to 2.0 (I wanted 2.1 but based on another thread JPA 2.0 and EJB 3.1 are as high as I can go at the moment...See my other thread topic here -->Eclipse Juno and JPA 2.1 support).
Here is my server.xml file:
<server description="new server">
<!-- Enable features -->
<featureManager>
<feature>javaee-7.0</feature>
<feature>localConnector-1.0</feature>
<feature>distributedMap-1.0</feature>
<feature>adminCenter-1.0</feature>
<feature>ssl-1.0</feature>
<feature>usr:webCacheMonitor-1.0</feature>
<feature>webCache-1.0</feature>
<feature>ldapRegistry-3.0</feature>
</featureManager>
<!-- Admin Center Config Start -->
<!-- To access this server from a remote client add a host attribute to the following element, e.g. host="*" -->
<httpEndpoint host="*" httpPort="9080" httpsPort="9443" id="defaultHttpEndpoint"/>
<keyStore id="defaultKeyStore" password="xxxxxx"/>
<basicRegistry id="basic">
<user name="admin" password="xxxxx"/>
<user name="nonadmin" password="xxxxxx"/>
</basicRegistry>
<administrator-role>
<user>admin</user>
</administrator-role>
<remoteFileAccess>
<writeDir>${server.config.dir}</writeDir>
</remoteFileAccess>
<!-- Automatically expand WAR files and EAR files -->
<applicationManager autoExpand="true"/>
<applicationMonitor updateTrigger="mbean"/>
<enterpriseApplication id="CHNewCHRDMEAR" location="CHNewCHRDMEAR.ear" name="CHNewCHRDMEAR">
<application-bnd>
<security-role name="AllAuthenticated">
<special-subject type="ALL_AUTHENTICATED_USERS"/>
</security-role>
</application-bnd>
</enterpriseApplication>
<enterpriseApplication id="CHServiceEAR" location="CHServiceEAR.ear" name="CHServiceEAR"/>
<!-- JAAS Authentication Alias (Global) Config -->
<authData id="dbUser" password="{xor}MzhmJT06ajI=" user="dbUser"/>
<!-- JDBC Driver and Datasource Config -->
<library id="DB2JCC4Lib">
<fileset dir="C:\DB2\Jars" includes="db2jcc4.jar db2jcc_license_cisuz.jar"/>
</library>
<dataSource containerAuthDataRef="dbUser" id="CHTEST2" jndiName="jdbc/nextgen" type="javax.sql.XADataSource">
<jdbcDriver libraryRef="DB2JCC4Lib"/>
<properties.db2.jcc databaseName="CHTEST2" password="{xor}MzhmJT06ajI=" portNumber="60112" serverName="server.com" sslConnection="false" user="dbUser"/>
<containerAuthData password="{xor}MzhmJT06ajI=" user="dbUser"/>
</dataSource>
<dataSource id="CHTEST2_RO" jndiName="jdbc/nextgen_RO" type="javax.sql.XADataSource">
<jdbcDriver libraryRef="DB2JCC4Lib"/>
<properties.db2.jcc databaseName="CHTEST2" password="{xor}MzhmJT06ajI=" portNumber="60112" serverName="server.com" sslConnection="false" user="dbUser"/>
<containerAuthData password="{xor}MzhmJT06ajI=" user="dbUser"/>
</dataSource>
<!-- More in file, but no included...-->
</server>
Here is my persistence.xml file:
<?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"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="CHService" transaction-type="JTA">
<jta-data-source>jdbc/nextgen</jta-data-source>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="openjpa.jdbc.TransactionIsolation" value="read-uncommitted" /></properties></persistence-unit>
<persistence-unit name="CHServiceRO" transaction-type="JTA">
<jta-data-source>jdbc/nextgen_RO</jta-data-source>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="openjpa.jdbc.TransactionIsolation" value="read-uncommitted" />
</properties>
</persistence-unit>
</persistence>
I *believe that we are relying solely on injection to get the context for JPA jndi lookups but that is because I don't see in our code any call to an initial context for any JPA specific JNDI names. Below are my two anotated session beans from the EJB project:
a. The CHService Bean:
#Stateless
#TransactionManagement(TransactionManagementType.CONTAINER)
#Local({ CHServiceLocal.class })
#Remote({ CHServiceRemote.class })
#Interceptors({ CHServiceLog.class })
#Resources({
#Resource(name = "jdbc/nextgen", mappedName = "jdbc/nextgen", authenticationType = AuthenticationType.APPLICATION, shareable = true, type = javax.sql.DataSource.class),
#Resource(name = "services/cache/CHBluepages", mappedName = "services/cache/CHBluepages", authenticationType = AuthenticationType.APPLICATION, shareable = true, type = com.ibm.websphere.cache.DistributedMap.class),
#Resource(name = "services/cache/CHGeneric", mappedName = "services/cache/CHGeneric", authenticationType = AuthenticationType.APPLICATION, shareable = true, type = com.ibm.websphere.cache.DistributedMap.class) })
public class CHServiceBean extends AbstractCHServiceImpl implements
CHService {
#PersistenceContext(unitName = "CHService")
private EntityManager em;
b. The CHServiceRO bean:
#Stateless
#TransactionManagement(TransactionManagementType.CONTAINER)
#Local({CHServiceLocalRO.class})
#Remote({CHServiceRemoteRO.class})
#Interceptors({CHServiceROLog.class})
#Resources({
#Resource(name="jdbc/nextgen_RO", mappedName="jdbc/nextgen_RO", authenticationType=AuthenticationType.APPLICATION, shareable=true, type=javax.sql.DataSource.class),
#Resource(name="jdbc/nextgen", mappedName="jdbc/nextgen", authenticationType=AuthenticationType.APPLICATION, shareable=true, type=javax.sql.DataSource.class),
#Resource(name="services/cache/CHBluepages", mappedName="services/cache/CHBluepages", authenticationType=AuthenticationType.APPLICATION, shareable=true, type=com.ibm.websphere.cache.DistributedMap.class),
#Resource(name="services/cache/CHGeneric", mappedName="services/cache/CHGeneric", authenticationType=AuthenticationType.APPLICATION, shareable=true, type=com.ibm.websphere.cache.DistributedMap.class)
})
public class CHServiceBeanRO implements CHServiceRO {
#PersistenceContext (unitName="CHServiceRO") private EntityManager em;
private CHServiceBase ch;
#PostConstruct
private void init() { ch = new CHServiceBase(em); }
Here is a snippet from the Web.xml of the front-end application calling the JPA application:
<resource-ref id="ResourceRef_1436377001246">
<res-ref-name>jdbc/nextgen</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Application</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
<resource-ref id="ResourceRef_1436377001247">
<res-ref-name>jdbc/nextgen_RO</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Application</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
Based on the post from Gas on this topic: java.lang.ClassCastException,Getting Entitymanager Via JNDI Lookup
I also tried updating the web.xml with the following entries:
<persistence-unit-ref>
<persistence-unit-ref-name>chJPA</persistence-unit-ref-name>
<persistence-unit-name>CHService</persistence-unit-name>
</persistence-unit-ref>
<persistence-unit-ref>
<persistence-unit-ref-name>chJPA_RO</persistence-unit-ref-name>
<persistence-unit-name>CHServiceRO</persistence-unit-name>
</persistence-unit-ref>
and the Bean code with:
#PersistenceContext(name = "chJPA", unitName = "CHService")
and
#PersistenceContext (name="chJPA_RO", unitName="CHServiceRO")
Got the same error just with a different jndi name, ie The java:comp/env/chJPA reference of type javax.persistence.EntityManager for the CHServiceBean com.......etc etc.
Lastly, per this post: Error while accessing EntityManager - openjpa - WAS liberty profile
It seems that maybe I can't have the full JavaEE 7 feature and run JPA 2.0? Please advise!
As in the post you are referring to - you cannot have <feature>javaee-7.0</feature> together with JPA 2.0, as it enables 2.1, thats why you have conflicts.
So you have 2 options:
either use Java EE7 and JPA 2.1
or just enable required Java EE 6 features and then use JPA 2.0
Since you are migrating from WAS 8.0, which doesn't support Java EE7 for now, easier choice might be to use the second option.
So try to remove javee-7.0 feature, and add ejbLite-3.1 and jpa-2.0 and whatever you need more.
You are correct that you cannot have javaee-7.0 and the JPA 2.0 feature, as it enables the JPA 2.1 feature. So the answer Gas gave is correct.
I just wanted to point out since you said that you do want to go to JPA 2.1 eventually, once you work out your eclipse issues, that you should use the WebSphere Application Server Migration Toolkit to identify application changes needed when migrating from JPA 2.0 to JPA 2.1. The Liberty JPA 2.0 implementation is built on OpenJPA, whereas the JPA 2.1 implemtation is built on EclipseLink. The migration toolkit is downloadable for free on wasdev: https://developer.ibm.com/wasdev/downloads/#asset/tools-WebSphere_Application_Server_Migration_Toolkit

Could not initialize class org.springframework.web.context.request.ServletRequestAttributes

I'm trying to create a Rest controller using Spring 4. I'm also using mongodb as a database, and Tomcat 7 as webserver.
I'm getting this error message when i try to submit any Rest request:
type Exception report
message Servlet execution threw an exception
description The server encountered an internal error that prevented it from fulfilling this request.
exception
javax.servlet.ServletException: Servlet execution threw an exception
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
root cause
java.lang.NoClassDefFoundError: Could not initialize class org.springframework.web.context.request.ServletRequestAttributes
org.springframework.web.servlet.FrameworkServlet.buildRequestAttributes(FrameworkServlet.java:996)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:923)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:822)
javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:807)
javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
note The full stack trace of the root cause is available in the Apache Tomcat/7.0.56 logs.
I'm using those version in my pom.xml
<!-- Web -->
<jsp.version>2.2</jsp.version>
<jstl.version>1.2</jstl.version>
<servlet.version>2.5</servlet.version>
<!-- Spring -->
<spring-framework.version>4.0.0.RELEASE</spring-framework.version>
<!-- spring-web -->
<spring-web.version>4.1.2.RELEASE</spring-web.version>
<!-- Spring data for MongoDB -->
<springframework.data-version>1.6.1.RELEASE</springframework.data-version>
here is the controller class that'm using :
#RestController
#RequestMapping("/rest/user")
public class UserContoller {
#Autowired
UserServices userServices;
#RequestMapping(value = "/{username}", method = RequestMethod.GET)
public #ResponseBody User findUserByUsername(#PathVariable ("username") String username){
return userServices.findUserByUsername(username);
}
}
would you please help me?
thank you in advance
I fixed it this way:
#RequestMapping(value = "/user", method = RequestMethod.GET, produces = "application/json")
#ResponseBody
public User findUsername(#RequestParam("username") String username) {
logger.info("Searcing for user using his username");
return userServices.findUserByUsername(username);
}
I had a similar issue and I believe a combination of things resolved this issue:
Make sure that you have the following two lines in your servlet.xml and in this order(meaning annotation-driven must be listed before the default-servlet-handler)
<mvc:annotation-driven />
<mvc:default-servlet-handler />
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
*Any equivalent viewResolver bean is fine.
Make sure this is in your web.xml:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
I see you dont mention what you're GET will produce. For Ex: I have this attribute in my #RequestMapping produces = MediaType.APPLICATION_JSON_VALUE
Finally, I'm not sure why but each time I add a new controller mapping, I need to run the Maven Install lifecycle or it doesn't see the new mapping. This issue i'm still trying to figure out.

Lazy loading of #ManyToOne relation fails with GlassFish 4 / EclipseLink

GlassFish 4 (actually its JPA implementation, i.e. EclipseLink) fails to lazy load a #ManyToOne JPA relation from our Java EE 7 application. Default/eager loading is ok, but not lazy loading.
The relation in the 'Student' entity is:
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "addr_id")
private Address address;
The (simplified) persistence.xml looks like:
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
version="2.1">
<persistence-unit name="foo-PU" transaction-type="JTA">
<jta-data-source>jdbc/foo-DS</jta-data-source>
<class>foo.domain.Student</class>
<class>foo.domain.Address</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="eclipselink.target-database" value="PostgreSQL"/>
<property name="eclipselink.logging.level" value="FINE"/>
</properties>
</persistence-unit>
</persistence>
The application uses several API: PrimeFaces, JSF 2.2, CDI 1.1, JPA 2.1.
Also note that the EntityManager are not obtained by injection into session EJB, but manually created using Persistence.createEntityManagerFactory(...) then emf.createEntityManager(...).
The error message is:
WARNING: Reverting the lazy setting on the OneToOne or ManyToOne attribute [address] for the entity class [class foo.domain.Student] since weaving was not enabled or did not occur.
My understanding is that, for some reason, the dynamic weaving of entities is not enabled. For a Java EE application it should be, as suggested by http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Advanced_JPA_Development/Performance/Weaving.
For the record, if we try to force the weaving using this:
<property name="eclipselink.weaving" value="true"/>
in the persistence.xml, then we get another error message:
SEVERE: Error Rendering View[/student/studentList.xhtml]
javax.el.ELException: /student/studentList.xhtml #24,81 value="#{studentController.selectedCode}": Exception [EclipseLink-30005] (Eclipse Persistence Services - 2.5.0.v20130507-3faac2b): org.eclipse.persistence.exceptions.PersistenceUnitLoadingException
Exception Description: An exception was thrown while searching for persistence archives with ClassLoader: WebappClassLoader (delegate=true; repositories=WEB-INF/classes/)
Internal Exception: javax.persistence.PersistenceException: Exception [EclipseLink-28022] (Eclipse Persistence Services - 2.5.0.v20130507-3faac2b): org.eclipse.persistence.exceptions.EntityManagerSetupException
Exception Description: Value [true] for the property [eclipselink.weaving] is incorrect when global instrumentation is null, value should either be null, false, or static.
at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:114)
at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:194)
at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:182)
at javax.faces.component.UIOutput.getValue(UIOutput.java:174)
at javax.faces.component.UIInput.getValue(UIInput.java:291)
at com.sun.faces.renderkit.html_basic.HtmlBasicInputRenderer.getValue(HtmlBasicInputRenderer.java:205)
(...)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673)
Any idea how to fix this lazy-loading issue? Why is the dynamic weaving not enabled by default ?
Thanks.
If you set eclipselink.weaving to true it means that you want to weave an entity classes dynamically. To make this work you need to run a jvm with a proper javaagent. First download an agent
wget -O /tmp/eclipselink.jar \
https://repo1.maven.org/maven2/org/eclipse/persistence/eclipselink/2.7.7/eclipselink-2.7.7.jar
and then run your app using following snippet
java -javaagent:/tmp/eclipselink.jar ....
But if you set eclipselink.weaving to static then you inform jpa that you want to weave the entity classes statically. Of course you have to trigger the waving by your own for example using this maven plugin https://github.com/craigday/eclipselink-staticweave-maven-plugin