Infinispan cache returning null object - caching

Getting NullPointer exception while put the values into cache using cache.put() method.
Environment:
Jboss 7.2
Here is the sample code I've written to reproduce the issue.
Configuration form standalone.xml file:
`<cache-container name="sampleCache" default-cache="default">
<local-cache name="default"/>
</cache-container>`
Added dependencies in deploy descriptor file like
`<jboss-deployment-structure>
<deployment>
<dependencies>
<module name="org.infinispan.commons" />
<module name="org.infinispan" />
</dependencies>
</deployment>
</jboss-deployment-structure>`
Getting the cache object via #Resource from Java code
`import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import org.infinispan.Cache;
/**
* InfiniSpanJbossCache Implementation
*
*/
#Startup
#Singleton
public class InfiniSpanJbossCacheExample {
#Resource(lookup="java:/jboss/infinispan/cache/sampleCache/default")
private static Cache<String, String> cache;
#PostConstruct
public static void deploy(){
cache.put("test","inserted1element");
}
}`
While trying to insert some values into cache(cache.put("","")) I'm getting the error, Did I miss any configs????

Related

Spring Data JDBC + Querydsl: error "JdbcRepositoryFactory does not support Querydsl"

I want to use Spring Data JDBC with QueryDSL support. According to Spring documentation (https://docs.spring.io/spring-data/jdbc/docs/current/reference/html/#core.extensions.querydsl) it is supported, but I couldn't make it working.
I use MariaDB as database and my version of SpringBoot is 2.6.0.
My dependencies in pom.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-sql-spring</artifactId>
</dependency>
Configuration:
#Configuration
#EnableJdbcRepositories
#EnableTransactionManagement
public class DBConfig {
}
My entity class:
package com.test.model.metadata;
import org.springframework.data.annotation.Id;
import org.springframework.data.relational.core.mapping.Table;
#Table
public class Action {
#Id
private long id;
private String name;
...
}
My repository class:
package com.test.repository;
import java.util.List;
import org.springframework.data.querydsl.QuerydslPredicateExecutor;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.stereotype.Repository;
import com.test.model.Action;
import com.querydsl.core.types.Predicate;
#Repository
public interface ActionRepository extends PagingAndSortingRepository<Action, Long>, QuerydslPredicateExecutor<Action> {
#Override
List<Action> findAll(Predicate predicate);
}
QueryDSL predicate usage:
QAction action = QAction.action;
Predicate predicate = action.name.like("%Accept%");
List<Action> actions = actionRepository.findAll(predicate);
Q-classes are generated properly by preprocessor, compilation suceeds but during application startup I am getting error:
org.springframework.data.repository.core.support.UnsupportedFragmentException: Repository com.atende.db.metadata.jdbcrepository.ActionRepository implements org.springframework.data.querydsl.QuerydslPredicateExecutor but JdbcRepositoryFactory does not support Querydsl!
What yet could be missing in my solution?
When I am using QueryDSL directly with JdbcTemplate it works:
QAction action = QAction.action;
SQLTemplates dialect = new MySQLTemplates();
Connection connection = DataSourceUtils.getConnection(jdbcTemplate.getDataSource());
SQLQuery<String> query = new SQLQuery<>(connection, dialect);
List<Tuple> actions = query.select(action.id, action.name)
.from(action)
.where(action.name.like("%Action%"))
.fetch();
I also tried to use infobip querydsl library (https://github.com/infobip/infobip-spring-data-querydsl) but got the same error.
This is a misinterpretation of the documentation (not your fault, it is structured in an unfortunate way).
You are looking at the preface which describes the general way to work with Spring Data modules.
This does not indicate that the module at hand (JDBC in this case) supports all the features mentioned.
Spring Data JDBC does not provide Querydsl support.
That means that the #EnableJdbcRepositories which activates spring-data-jdbc repository implementation does not provide Querydsl support.
If you have infobip-spring-data-jdbc-querydsl-boot-starter on classpath and remove #EnableJdbcRepositories it should work.
QuerydslJdbcPredicateExecutor is the fragment implementation.

Spring Cucumber ActiveProfiles annotation not working with CucumberContext

I'm working on a project where we have a component which consists:
core
connector to external system 1
connector to external system 2
The connectors are mutually exlusive (if connector1 is active, connector2 is always inactive and vice versa). The core and a single connector are autowired on startup of the ApplicationContext. Which connector is instantiated is based on a value in the spring application properties.
We're writing integration tests using spring-cucumber (v6.2.2). For each external system, I want to run a set of cucumber tests. I've created 2 testsets using annotations on the cucumber scenario's which allows me to seperate the tests for connector1 and connector2.
The problem I'm having is that I need both testsets to run with a different spring profile, so I can use a different configuration. I can't find how to do this.
Current implementation (with a single profile):
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.3.4.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-java</artifactId>
<version>6.2.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-junit</artifactId>
<version>6.2.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-spring</artifactId>
<version>6.2.2</version>
<scope>test</scope>
</dependency>
CucumberConnector1IT.java
package omitted.for.company.rules;
import io.cucumber.junit.Cucumber;
import io.cucumber.junit.CucumberOptions;
import org.junit.runner.RunWith;
#RunWith(Cucumber.class)
#CucumberOptions(
features = { "classpath:feature/" },
glue = { "omitted.for.company.rules.cucumber.step" },
plugin = { "pretty", "json:target/cucumber-report/cucumber.json",
"html:target/cucumber-report/cucumber.html" },
tags = "#Connector1 and not #ignore" // tags make sure only applicable tests are run
)
public class CucumberConnector1IT {
}
CucumberConnector2IT.java
package omitted.for.company.rules;
import io.cucumber.junit.Cucumber;
import io.cucumber.junit.CucumberOptions;
import org.junit.runner.RunWith;
#RunWith(Cucumber.class)
#CucumberOptions(
features = { "classpath:feature/" },
glue = { "omitted.for.company.rules.cucumber.step" },
plugin = { "pretty", "json:target/cucumber-report/cucumber.json",
"html:target/cucumber-report/cucumber.html" },
tags = "#Connector2 and not #ignore" // tags make sure only applicable tests are run
)
public class CucumberConnector2IT {
}
StepInitializer.java
package omitted.for.company.rules.steps;
import io.cucumber.java.Before;
import io.cucumber.spring.CucumberContextConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.context.ActiveProfiles;
#SpringBootTest
#ActiveProfiles("test") // I can only get this to work if the #ActiveProfiles and #CucumberContextConfiguration annotations are on the same class
#CucumberContextConfiguration
public class StepInitializer {
// mock some beans to use in cucumber test
#MockBean
private EventProducer eventProducer;
#MockBean
private RestInterface restInterface;
#Before
public void setup() {
}
}
So far everything works. But what I need now is to put the #ActiveProfiles() annotation on a different class than the #CucumberContextConfiguration. If I can do this then I can annotate the correct step classes with the required profiles.
Problem is that I don't understand the spring annotations well enough to know which ones I can move and which ones I cannot. I found this example of exactly what I'm trying to do (spring-cucumber-profiles repo, notice the location of the #ActiveProfiles annotation here) . Unfortunately, it uses an older version of cucumber-spring (v5.6.0). That version doesn't yet have the #CucumberContextConfiguration annotation and does some magic with the spring context according to the documentation (Release notes of cucumber-spring). I tried to checkout the example repo and upgrade it to v6.2.2 but couldn't get it working with the new version.
If anyone spots what I'm doing wrong in my own examples, or has the possibility to get the example repo working with version 6.2.2 of cucumber-spring that would be much appreciated.
Thanks in advance! :)
I've solved the issue by separating the packages a bit, and creating separate StepInitializer classes for both testsets.
Current setup:
Test runner:
package omitted.for.company.rules;
import io.cucumber.junit.Cucumber;
import io.cucumber.junit.CucumberOptions;
import org.junit.runner.RunWith;
#RunWith(Cucumber.class)
#CucumberOptions(
features = { "classpath:feature/" },
extraGlue = { "omitted.for.company.rules.cucumber.step.common" }, // used extraGlue instead of glue
plugin = { "pretty", "json:target/cucumber-report/cucumber.json",
"html:target/cucumber-report/cucumber.html" },
tags = "#Connector1 and not #ignore" // tags make sure only applicable tests are run
)
public class CucumberConnector1IT {
}
Context Configuration:
package omitted.for.company.rules.steps;
import io.cucumber.java.Before;
import io.cucumber.spring.CucumberContextConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.context.ActiveProfiles;
#SpringBootTest
#ActiveProfiles({ "test", "test-connector1" })
#CucumberContextConfiguration
public class Connector1StepInitializer {
// mock some beans to use in cucumber test
#MockBean
private EventProducer eventProducer;
#MockBean
private RestInterface restInterface;
#Autowired
private ApplicationContext applicationContext;
#Autowired
private Environment environment;
#Before
public void setup() {
assertThat(applicationContext).isNotNull();
assertThat(environment.getActiveProfiles()).containsOnly("test","test-connector1");
}
}
Both connectors/test runners have their own runner class and their own ContextConfiguration class.
It's very important that the classes containing the #CucumberContextConfiguration annotation are not in the shared glue package (as provided in the extraGlue property in the #CucumberOptions annotation).
Package structure looks like this:
├───common
│ └───step // Contains shared steps. This path should be in the 'extraGlue' field of the runner classes
├───connector1
│ │ CucumberConnector1IT.java // Runner 1
│ └───step
│ Connector1Steps.java // Specific steps
│ Connector1StepInitializer.java // has #ActiveProfiles and #CucumberContextConfiguration annotations, use to mock beans
└───connector2
│ CucumberConnector1IT.java // Runner 2
└───step
Connector2Steps.java // Specific steps
Connector2StepInitializer.java // has #ActiveProfiles and #CucumberContextConfiguration annotations, use to mock beans
This way I can still use different spring profiles :).

Tomee - slf4j create logs file but not writing on them

I want to use log4j for my app (I don't need to handle the server logs for now). I searched for a solution but all post are related with server logs. When I run the app, the log4j.properties is read and the logs file are created but it didn't write on them.
I'm using Tomee as server. I have other project with Wildfly using the same solution for log4j and it works.
log4j.properties:
log4j.appender.TEST = org.apache.log4j.DailyRollingFileAppender
log4j.appender.TEST.File = /opt/share/test-project/logs/test.log
log4j.appender.TEST.DatePattern = '.'yyyy-MM-dd
log4j.appender.TEST.layout = org.apache.log4j.PatternLayout
log4j.appender.TEST.layout.ConversionPattern = [%d{ISO8601}] %5p - %x - %c.%M(%L): %m%n
# Define the types of logger and level of logging
#log4j.rootLogger.org = DEBUG,CONSOLE
log4j.logger.com.test=DEBUG, TEST
Log4jConfig class which is initialized:
import java.io.File;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.log4j.PropertyConfigurator;
#WebListener
public class Log4jConfig implements ServletContextListener {
private final static String LO4G_FILENAME="/opt/share/test-project/config/log4j.properties";
private static final Logger LOGGER = LoggerFactory.getLogger(Log4jConfig.class);
...
...
public void contextInitialized(ServletContextEvent arg0)
{
try{
File file = new File(LO4G_FILENAME);
if (file.exists())
{
PropertyConfigurator.configure(LO4G_FILENAME);
LOGGER.info("[Log4JInitServlet - contextInitialized] - Log4J configured:"+LO4G_FILENAME);
}
}catch (Exception e) {
LOGGER.error("[Log4JInitServlet - contextInitialized] - Exception >>",e);
}
}
}
Test.java:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.gson.Gson;
#Path("/test")
public class TestWs {
private static final Logger LOGGER = LoggerFactory.getLogger(TestWs.class.getName());
//here LOGGER is null. If I put it into test() is not null but not write on the log either.
#GET
#Path("/")
#Produces(MediaType.APPLICATION_JSON)
public Response test(){
LOGGER.debug("[TestWs - init] - init");
long currentSystemTime = System.currentTimeMillis();
LOGGER.error("[TestWs - test] - Error: TEST");
LOGGER.debug("[TestWs - test] - Finish Timing:"+(System.currentTimeMillis()-currentSystemTime));
return Response.ok().build();
}
}
POM.xml:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.12</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
<version>1.7.12</version>
</dependency>
Any idea?
upgrade dependency of slf4f :
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.22</version>
</dependency>
use private static final Logger logger = LoggerFactory.getLogger(class-name.class); into class in which you want to create logs.
use bellow log4j configuration :-
Root logger option
log4j.rootLogger=INFO, file
Direct log messages to a log file
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=./logs/log.log
log4j.appender.file.MaxFileSize=10MB
log4j.appender.file.MaxBackupIndex=10
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
log4j.logger.org.springframework=WARN
log4j.logger.com.amstech=DEBUG
I'm not sure of all the setup but if you put log4j lib/config in the container you can need to set in conf/system.properties:
openejb.logger.external=true
otherwise (for legacy reasons), tomee will setup log4j in a custom way making your configuration not respected. This property just means "use normal log4j behavior".

How to start HSQLDB in server mode from Spring boot application

I have a Spring boot application, running with jpa data and hsqldb 2.3.3 (in Centos 7), the application runs fine but I would like to use HSQLDB database manager to check the data status, however it failed:
application.properties:
spring.datasource.url=jdbc:hsqldb:mem:testdb
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.database-platform=org.hibernate.dialect.HSQLDialect
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=create
Command to start HSQLDB:
java -cp /home/mycentos/.m2/repository/org/hsqldb/hsqldb/2.3.3/hsqldb-2.3.3.jar org.hsqldb.util.DatabaseManagerSwing
If I tried to log in with HSQLDB server mode, it pops Connection refused error
jdbc:hsqldb:hsql://localhost/testdb
If I tried to log in in-memory db, I can log in but no table and data showing up
jdbc:hsqldb:hsql:testdb
Question:
How to make it works?
Do I have to refer to the hsqldb.jar from tomcat deployment folder because that is the one using by the application?
Any configuration difference to configure hsqldb in server mode or in-memory mode from Spring application?
Can any method make in-memory mode working in such situation (to check data by db created Spring boot)?
To access the HSQL DB created by Spring boot app, you have to start HSQL server. For example, create a XML configuration file hsql_cfg.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="hqlServer" class="org.hsqldb.server.Server" init-method="start" destroy-method="stop">
<property name="properties"><bean class="org.hsqldb.persist.HsqlProperties">
<constructor-arg><props>
<prop key="server.database.0">mem:testdb</prop>
<prop key="server.dbname.0">testdb</prop><!--DB name for network connection-->
<prop key="server.no_system_exit">true</prop>
<prop key="server.port">9001</prop><!--default port is 9001 -->
</props></constructor-arg>
</bean></property>
</bean>
</beans>
Here is a example to import the XML configuration in main application class.
#SpringBootApplication
#ImportResource(value="classpath:/package/hsql_cfg.xml")
public class MyApplication {
}
The HSQL server will start with Spring boot app. Other applications could connect to the HSQL server using JDBC url
jdbc:hsqldb:hsql://ip_address:port/testdb
Of course, hsqldb.jar is required for loading JDBC driver class.
Just to add to beckyang's answer, here is my approach.
Includes a hack to redirect logs to slf4j.
Includes specifying a corresponding datasource.
import org.hsqldb.jdbc.JDBCDataSource;
import org.hsqldb.server.Server;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import javax.sql.DataSource;
import java.io.ByteArrayOutputStream;
import java.io.PrintWriter;
#Configuration
public class DataSourceConfiguration {
private final Logger log = LoggerFactory.getLogger(getClass());
#Bean(initMethod = "start", destroyMethod = "stop")
#ConfigurationProperties//(prefix = "alarms.idempotent.server")
public Server idempotentServer(#Value("${alarms.idempotent.server.path}") String path, #Value("${alarms.idempotent.port}") int port, #Value("${alarms.idempotent.name}") String name) {
Server server = new Server();
server.setDatabaseName(0, name);
server.setDatabasePath(0, path);
server.setPort(port);
server.setLogWriter(slf4jPrintWriter());
server.setErrWriter(slf4jPrintWriter());
return server;
}
#Bean("idempotentDataSource")
#Primary
#ConfigurationProperties
public DataSource idempotentDataSource(#Value("${alarms.idempotent.datasource.url}") String urlNoPath, #Value("${alarms.idempotent.name}") String name) {
JDBCDataSource jdbcDataSource = new JDBCDataSource();
String url = urlNoPath;
if (!url.endsWith("/")) {
url += "/";
}
url += name;
jdbcDataSource.setUrl(url);
jdbcDataSource.setUser("sa");
return jdbcDataSource;
}
private PrintWriter slf4jPrintWriter() {
PrintWriter printWriter = new PrintWriter(new ByteArrayOutputStream()) {
#Override
public void println(final String x) {
log.debug(x);
}
};
return printWriter;
}
}

Spring Inject PersistenceContext

Trying to implement a DDD architecture with aspect oriented tests that access a database and check if user exists, using AspectJ LTW...
Currently I am faces with two issues, I don't know if this class is being injected in a Spring context. I have tried to add the
//#RunWith(SpringJUnit4ClassRunner.class)
//#ContextConfiguration(locations = {"classpath*:EntityTest-context.xml"})
With no sucess. Here is the test that I am trying to run. If you notice I am creating the EntityManager on the #Before I don't know if this is a proper usage, because when I try to find the object that is created I get returned null.
package ienterprise.common.aspects;
import ienterprise.common.model.CompanyPosition;
import ienterprise.common.model.InternalUser;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.PersistenceContext;
import static org.junit.Assert.assertEquals;
import org.springframework.test.context.ContextConfiguration;
//#RunWith(SpringJUnit4ClassRunner.class)
//#ContextConfiguration(locations = {"classpath*:EntityTest-context.xml"})
public class EntityTest {
private static final Logger logger = LoggerFactory.getLogger(EntityTest.class);
// #PersistenceContext(unitName="mysql") // FIXME inject this in unit tests
private static EntityManager manager;
#Before
public void setUp(){
EntityManagerFactory mngFactory = Persistence.createEntityManagerFactory("mysql");
manager = mngFactory.createEntityManager();
}
#Test
public void createUser(){
InternalUser someGuy = new InternalUser();
someGuy.setName("Adam");
someGuy.setUser("Engineer");
someGuy.create();
logger.debug("created user: {}", someGuy);
//FIXME: Can't find the user in the database.
InternalUser foundUser = manager.find(InternalUser.class, 1L);
logger.debug("fetched user: {}",foundUser);
assertEquals( someGuy, foundUser);
}
}
Our 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"
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:load-time-weaver/>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" >
<property name="persistenceXmlLocation" value="classpath*:META-INF/persistence.xml"></property>
</bean>
</beans>
How can I remove the #Before and inject a PersistenceContext?
How can I make sure that my class has a Spring Context?
This is all new stuff for me, and I would appreciate some links to github repositories if there are any with this kind of Spring+Hibernate+AspectJ+JUnit setup.
Let me know if something is not clear or additional detail is necessary.

Resources