Drools 6.1.0 DefaultFactHandle NotSerializable exception - weblogic

We are running drools 6.1.0 on Weblogic 12.1.2 as a stateless EJB 3.0 Bean. The bean returns the following exception when there is more load on the server during the initialization process when it is creating new instances in the pool.
EJB Exception: : java.lang.RuntimeException: java.io.NotSerializableException: org.drools.core.common.DefaultFactHandle
at org.drools.core.util.ClassUtils.deepClone(ClassUtils.java:514)
at org.drools.core.definitions.impl.KnowledgePackageImpl.deepCloneIfAlreadyInUse(Kn owledgePackageImpl.java:770)
at org.drools.core.definitions.impl.KnowledgePackageImpl.deepCloneIfAlreadyInUse(KnowledgePackageImpl.java:66)
at org.drools.core.impl.KnowledgeBaseImpl.addPackages(KnowledgeBaseImpl.java:722)
at org.drools.core.impl.KnowledgeBaseImpl.addKnowledgePackages(KnowledgeBaseImpl.java:266)
at org.drools.compiler.kie.builder.impl.KieContainerImpl.createKieBase(KieContainerImpl.java:412)
at org.drools.compiler.kie.builder.impl.KieContainerImpl.getKieBase(KieContainerImpl.java:346)
at org.drools.compiler.kie.builder.impl.KieContainerImpl.newKieSession(KieContainerImpl.java:498)
at org.drools.compiler.kie.builder.impl.KieContainerImpl.newKieSession(KieContainerImpl.java:443)
at org.drools.compiler.kie.builder.impl.KieContainerImpl.newKieSession(KieContainerImpl.java:425)
The code we have to initialize a new stateful session is as below:
protected KieSession kieSession= null;
protected ReleaseId releaseId = null; //fetched by logic to identify the release id>
if(kieSession != null){
kieSession.dispose();
kieSession = null;
}
KieServices kServices = KieServices.Factory.get();
KieContainer container = kServices.newKieContainer(this.releaseId);
kieSession = container.newKieSession();
This is happening in the constructor of the Stateless Bean.
Could you help us with any suggestions on resolving this issue?

Related

How to configure CXF servlet in Springboot 2.1.1 Final?

PLease find the error I am facing :
In springboot 2.1.1 I am getting below error :
APPLICATION FAILED TO START
Description: Parameter 1 of constructor in
org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration
required a bean of type
'org.springframework.boot.autoconfigure.web.servlet.DispatcherServletPath'
that could not be found.
The following candidates were found but could not be injected:
- Bean method 'dispatcherServletRegistration' in 'DispatcherServletAutoConfiguration.DispatcherServletRegistrationConfiguration'
not loaded because DispatcherServlet Registration found non dispatcher
servlet dispatcherServlet
Action:
Consider revisiting the entries above or defining a bean of type
'org.springframework.boot.autoconfigure.web.servlet.DispatcherServletPath'
in your configuration.
My configuration:
#Configuration
public class CXFConfig {
#Bean
public ServletRegistrationBean dispatcherServlet() {
final ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new CXFCdiServlet(), "/services/*");
servletRegistrationBean.setLoadOnStartup(1);
return servletRegistrationBean;
}
#Bean(name = Bus.DEFAULT_BUS_ID)
public SpringBus springBus() {
SpringBus springBus = new SpringBus();
springBus.getInInterceptors().add(new AppInboundInterceptor());
springBus.getOutInterceptors().add(new AppOutboundInterceptor());
return springBus;
}
}
Please confirm how to do the configuration?
dispatcherServlet() method doesn't work in Springboot 2.1.1
I solved this problem by change the method name from dispatcherServlet to disServlet.
Maybe you can try.

jax-rs sse client with Singleton in Glassfish/Payara

About jax-rs client with SSE in EJB Singleton, I've tried with Payara server full-5.183 (without docker) for this example, [https://abhirockzz.wordpress.com/2017/07/27/jax-rs-2-1-sse-client-api-example-using-glassfish-5-on-docker/], but failed. Error shown at line eventSource = SseEventSource.target(target).build();
#PostConstruct
public void init() {
this.sseClient = ClientBuilder.newClient();
this.target = this.sseClient.target("https://sse.now.sh");
tsvc.createSingleActionTimer(15000, null);
System.out.println("SSE client timer created");
eventSource = SseEventSource.target(target).build();
System.out.println("SSE Event source created........");
}
Error message: "java.lang.IllegalArgumentException: Argument fish.payara.requesttracing.jaxrs.client.decorators.JaxrsWebTargetDecorator#23112ded is not a valid JerseyWebTarget instance. SseEventSource does not support other WebTarget implementations."
Can anyone give me an idea?

Quartz scheduled jobs could not access datasource in Websphere

I am developing a web app where batch programs need to run for specific times. I used Quartz library to schedule the jobs. The web app is deployed on Websphere 8.5.5 and its working fine, accessing the tables through datasources (Datasource given in code is java:comp/env/jdbc/db_datasource). The job is also triggered at the mentioned times.
I am getting an error when the scheduled job makes a DB connection through the datasource and the error is:
javax.naming.ConfigurationException: A JNDI operation on a "java:" name cannot be completed because the server runtime is not able to associate the operation's thread with any J2EE application component. This condition can occur when the JNDI client using the "java:" name is not executed on the thread of a server application request. Make sure that a J2EE application does not execute JNDI operations on "java:" names within static code blocks or in threads created by that J2EE application. Such code does not necessarily run on the thread of a server application request and therefore is not supported by JNDI operations on "java:" names. [Root exception is javax.naming.NameNotFoundException: Name comp/env/jdbc not found in context "java:".]
at com.ibm.ws.naming.java.javaURLContextImpl.throwExceptionIfDefaultJavaNS(javaURLContextImpl.java:522)
at com.ibm.ws.naming.java.javaURLContextImpl.throwConfigurationExceptionWithDefaultJavaNS(javaURLContextImpl.java:552)
at com.ibm.ws.naming.java.javaURLContextImpl.lookupExt(javaURLContextImpl.java:481)
at com.ibm.ws.naming.java.javaURLContextRoot.lookupExt(javaURLContextRoot.java:485)
at com.ibm.ws.naming.java.javaURLContextRoot.lookup(javaURLContextRoot.java:370)
I understand from the error message is that the job is running outside the J2ee container and so the datasource is not available for the Job to make the connection, which I cannot agree as the Quartz is implemented as the ServletContextListener and the same is mentioned in web.xml.
Web.xml
<listener>
<listener-class>com.ehacampaign.helper.EHAJobSchedulerListener</listener-class>
</listener>
EHAJobSchedulerListener.java
public class EHAJobSchedulerListener implements ServletContextListener {..}
As you can see the code, the class is registered in the web and I do not understand why it cannot use the datasource in the J2EE container.
Questions are:
Why servlet registered class cannot access the datasource in J2EE
container?
If datasource in container cannot be used, then how to make a
connection to the DB while executing the job?
NOTE: I have the same setup in JBoss AS 7.1 and the jobs are running smoothly accessing the datasource configured in JBoss AS 7.1. I have to develop this in Websphere as the customer demands it.
UPDATED
I have attached the modified quartz property file. Even after adding the workmanagerthread, I am getting the same error.
org.quartz.threadPool.threadCount=1
org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
org.quartz.jobStore.class=org.quartz.simpl.RAMJobStore
org.quartz.threadExecutor.class=org.quartz.commonj.WorkManagerThreadExecutor
org.quartz.threadExecutor.workManagerName=wm/default
In order to perform JNDI lookups in WebSpehre, your code must be running on a managed thread. In order to have Quartz run on one of WebSphere's managed threads, you must set the following 2 properties in your quartz.properties (as Alasdair mentioned in the comments):
org.quartz.threadExecutor.class=org.quartz.commonj.WorkManagerThreadExecutor
org.quartz.threadExecutor.workManagerName=wm/default
The name for org.quartz.threadExecutor.workManagerName can be the JNDI name of any Work Manager that you have configured in WebSphere. I recommend simply using wm/default because it is in your configuration by default.
With all the help provided by aguibert and Alasdair and reference from here, I am able to fix the issue.
The Quartz property file is:
org.quartz.threadPool.threadCount=1
org.quartz.jobStore.class=org.quartz.simpl.RAMJobStore
org.quartz.threadExecutor.class=org.quartz.commonj.WorkManagerThreadExecutor
org.quartz.threadExecutor.workManagerName=wm/default
The database connection or JNDI lookup should happen within the empty constructor of the JOB Implemented class. For ex,
public class ContractIdFromPartyServiceJob implements Job {
private DataSource ds;
public ContractIdFromPartyServiceJob() {
try {
Logger.info("Gets the data source");
Context context = new InitialContext();
ds = (DataSource) context.lookup(ApplicationConstants.RESOURCE_REFERENCE_JDBC);
} catch (RException e) {
e.printStackTrace();
}
}
#Override
public void execute(JobExecutionContext arg0) throws JobExecutionException
{
EHAMarsDAO marsDao = new EHAMarsDAO();
Connection con = getConnection();
try {
marsDao.callDBMethod(con);
} finally {
con.close();
}
}
public Connection getConnection() throws RACVException
{
Connection con = null;
try {
con = ds.getConnection();
con.setAutoCommit(false);
con.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
} catch (SQLException e) {
throw new RException(Constants.ERROR_CODE_002, Constants.E012_DB_CONNECTION_ERROR, e);
}
return con;
}
}

spring data elasticsearch Invocation of init method failed; nested exception is java.lang.AbstractMethodError

I have problem with Spring Data Elasticsearch. I configure elasticsearch like this:
#Configuration
#EnableJpaRepositories(basePackages = {"org.project.repositories"})
#EnableElasticsearchRepositories(basePackages = "org.project.repositorieselastic")
#EnableTransactionManagement
public class PersistenceContext {
#Bean
public ElasticsearchOperations elasticsearchTemplate() {
return new ElasticsearchTemplate(client());
}
#Bean
public Client client(){
Settings settings = ImmutableSettings.settingsBuilder()
// Setting "transport.type" enables this module:
.put("cluster.name", "elasticsearch")
.put("client.transport.ignore_cluster_name", false)
.build();
TransportClient client= new TransportClient(settings);
TransportAddress address = new InetSocketTransportAddress("127.0.0.1", 9300);
client.addTransportAddress(address);
return client;
}
}
My repo looks like.
#Repository()
public interface UserFavoriteElasticRepo extends ElasticsearchRepository<UserFavorite, Long> {
}
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: org.project.repositorieselastic.UserFavoriteElasticRepo org.project.services.elastic.FavoriteIndexerService.elasticRepo; nested exception
is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userFavoriteElasticRepo': Invocation of init method failed; nested exception is java.lang.AbstractMethodError
It's look like the implementation is not generated. But I don't know where to investigate. I tried to use one package and use this - https://github.com/izeye/spring-boot-throwaway-branches/commit/874ccba09189d6ef897bc430c43b6e3705404399 but with no success.
I solved the problem adding this in pom file
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-commons</artifactId>
<version>1.12.2.RELEASE</version>
</dependency>
I've got same exception using spring-data-elasticsearch.
But exception was thrown when I declared new methods in repository:
ex.:
public interface UserFavoriteElasticRepo extends ElasticsearchRepository<UserFavorite, Long> {
Page<UserFavorite> findBySomeProperty(String propertyValue, Pageable pageable);
}
It was casued due to spring-data-elasticsearch, spring-data-commons versions. Function declarations have changed: org.springframework.data.repository.query.QueryLookupStrategy.resolveQuery - it caused the exception.
For spring-data-elasticsearch version 2.0.0.RELEASE you have to use spring-data-commons with version 1.12.0.
If you have spring-data-jpa in your project it also uses spring-data-commons. For spring-data-jpa v1.9.0.RELEASE, spring-data-commons is v1.11.0.RELEASE
Could you provide what frameworks and versions of spring you are using? Also If you could put whole stacktrace, it will be helpfull?

Spring boot JNDI datasource lookup failure - Name comp/env/jdbc not found in context "java:"

I have setup a spring boot (v 1.1.9) application to deploy as a WAR file. And I'm trying to integrate this web application with an existing data service module (added as a maven dependency).
Environment trying to deploy: WebSphere Application Server 8.5.5.4
The issue I'm facing is an application start-up failure when try to look-up a JNDI dataSource (jdbc/fileUploadDS) as below within the dependent data service module.
#Configuration
#Profile("prod")
public class JndiDataConfig implements DataConfig {
#Bean
public DataSource dataSource() throws NamingException {
Context ctx = new InitialContext();
return (DataSource) ctx.lookup("java:comp/env/jdbc/fileUploadDS");
}
}
My Spring Boot configuration:
#Configuration
#ComponentScan(basePackages = { "au.com.aiaa.fileupload.data.*", "demo" })
#EnableAutoConfiguration(exclude = { HibernateJpaAutoConfiguration.class, DataSourceAutoConfiguration.class })
public class SampleApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(applicationClass, args);
}
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(applicationClass);
}
private static Class<SampleApplication> applicationClass = SampleApplication.class;
#Bean
public static Properties fileUploadJndiProperties() throws NamingException {
JndiObjectFactoryBean jndiFactoryBean = new JndiObjectFactoryBean();
jndiFactoryBean.setJndiName("props/FileUploadProperties");
jndiFactoryBean.setExpectedType(Properties.class);
jndiFactoryBean.setLookupOnStartup(true);
jndiFactoryBean.afterPropertiesSet();
return (Properties) jndiFactoryBean.getObject();
}
}
Note that I'm able to lookup props/FileUploadProperties successfully. But failing to do the same for a datasource.
My doubt is it is trying to load a EmbeddedWebApplicationContext which is not what I want.
The stack trace is:
Instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public javax.sql.DataSource au.com.aiaa.fileupload.data.dao.configuration.JndiDataConfig.dataSource() throws javax.naming.NamingException] threw exception; nested exception is **javax.naming.NameNotFoundException: Name comp/env/jdbc not found in context "java:".**
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:301)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1186)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:706)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:762)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
at **org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:109)**
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:691)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:142)
at org.springframework.boot.context.web.SpringBootServletInitializer.createRootApplicationContext(SpringBootServletInitializer.java:89)
at org.springframework.boot.context.web.SpringBootServletInitializer.onStartup(SpringBootServletInitializer.java:51)
at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:175)
..................
Caused by: org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public javax.sql.DataSource au.com.aiaa.fileupload.data.dao.configuration.JndiDataConfig.dataSource() throws javax.naming.NamingException] threw exception; nested exception is **javax.naming.NameNotFoundException: Name comp/env/jdbc not found in context "java:".**
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:188)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:586)
... 132 common frames omitted
Caused by: javax.naming.NameNotFoundException: Name comp/env/jdbc not found in context "java:".
at com.ibm.ws.naming.ipbase.NameSpace.getParentCtxInternal(NameSpace.java:1970)
at com.ibm.ws.naming.ipbase.NameSpace.retrieveBinding(NameSpace.java:1377)
at com.ibm.ws.naming.ipbase.NameSpace.lookupInternal(NameSpace.java:1220)
at com.ibm.ws.naming.ipbase.NameSpace.lookup(NameSpace.java:1142)
at com.ibm.ws.naming.urlbase.UrlContextImpl.lookupExt(UrlContextImpl.java:1436)
at com.ibm.ws.naming.java.javaURLContextImpl.lookupExt(javaURLContextImpl.java:477)
at com.ibm.ws.naming.java.javaURLContextRoot.lookupExt(javaURLContextRoot.java:485)
at com.ibm.ws.naming.java.javaURLContextRoot.lookup(javaURLContextRoot.java:370)
at org.apache.aries.jndi.DelegateContext.lookup(DelegateContext.java:161)
at javax.naming.InitialContext.lookup(InitialContext.java:436)
at au.com.aiaa.fileupload.data.dao.configuration.JndiDataConfig.dataSource(JndiDataConfig.java:41)
at au.com.aiaa.fileupload.data.dao.configuration.JndiDataConfig$$EnhancerBySpringCGLIB$$8001dbbe.CGLIB$dataSource$0(<generated>)
at au.com.aiaa.fileupload.data.dao.configuration.JndiDataConfig$$EnhancerBySpringCGLIB$$8001dbbe$$FastClassBySpringCGLIB$$3c9e0518.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:312)
at au.com.aiaa.fileupload.data.dao.configuration.JndiDataConfig$$EnhancerBySpringCGLIB$$8001dbbe.dataSource(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:60)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
at java.lang.reflect.Method.invoke(Method.java:611)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:166)
What am I missing here? Even when I try to explicitly define the dataSource bean method in SampleApplication.java like below it fails with the same error.
#Bean
public static DataSource dataSource() throws NamingException {
JndiObjectFactoryBean jndiFactoryBean = new JndiObjectFactoryBean();
jndiFactoryBean.setJndiName("java:comp/env/jdbc/fileUploadDS");
jndiFactoryBean.setExpectedType(DataSource.class);
jndiFactoryBean.setLookupOnStartup(true);
jndiFactoryBean.setResourceRef(true);
jndiFactoryBean.afterPropertiesSet();
return (DataSource) jndiFactoryBean.getObject();
}
I referred this and it says we need to set enableNaming() on servlet container? Can I do something similar for non-embedded web application context? Or is it purely a WAS 8.5 issue??
You need to have resource reference with jdbc/fileUploadDS name in your web.xml. And make sure it is bound to actual datasource name during installation or via ibm-web-bnd.xml file.
Definition in web.xml:
<resource-ref>
<description />
<res-ref-name>jdbc/fileUploadDS</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
If you dont want to use web.xml, then in normal Java EE app you could just add in web component (servlet, filter) the following class annotation:
#Resource(name="jdbc/fileUploadDS", type=javax.sql.DataSource.class, lookup="jdbc/fileUploadDS")
but I'm not Spring-boot expert, so don't know, if it will work or is possible there.
I am able to connect my Spring-Boot application (deployed in Websphere Application Server 9) to WAS datasource.
The following code worked for me, for connecting to DataSource:
#Bean(name = "WASDataSource")
public DataSource WASDataSource() throws Exception {
JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
return dataSourceLookup.getDataSource("DSNAME");
}
#Bean(name = "WASDataSourceJdbcTemplate")
public JdbcTemplate jdbcTemplate_WASDS(#Qualifier("WASDataSource")
DataSource dsDB2) {
return new JdbcTemplate(dsDB2);
}
Note: The name of Datasource "DSNAME" is the name which appears on the UI of Websphere console.
You can see that via -> Select Resources > JDBC > Data Sources.
Then I created jdbc template:
#Autowired
#Qualifier("WASDataSourceJdbcTemplate")
private JdbcTemplate db2WASTemplate;`
And running query using the query method works fine :
db2WASTemplate.query()
I did not create any Web.xml or ibm-web-bnd.xml files
I just configured spring boot with my custom datasource as follows:
#Bean
#ConfigurationProperties("spring.datasource")
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
and inside the application.properties file I defined all datasource settings as usual
spring.datasource.driver-class-name= ***
spring.datasource.url= ***
spring.datasource.username= ***
spring.datasource.password= ***
spring.datasource.jndi-name=jdbc/myDB
It works nicely with #SpringBootApplication with all other default settings
I am facing the same problem. I don't know how to define tag in spring boot since there is no web.xml file in the spring boot.
So far what I came to know that we have to define it in the application file from where we start our spring application. I think we need to use this method to set the Datasource:
#Bean(destroyMethod="")
#ConfigurationProperties(prefix="datasource.mine")
public DataSource dataSource() throws Exception {
JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
return dataSourceLookup.getDataSource("java:jdbc/configurationFile");
}