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

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.

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"/>

JPA Exception : No externally managed transaction is currently active for this thread

Exception is thrown when trying to Insert/Update/Delete with executeUpdate(). Select query works fine.I have tried all the suggestions from previous similar error mentioned in stack-overflow. Appreciate any guidance.
Environment : Websphere Liberty : 17.0.0.2, Eclipselink 2.6.4, JPA 2.1
Features enabled on Liberty server
<featureManager>
<feature>adminCenter-1.0</feature>
<feature>beanValidation-1.1</feature>
<feature>cdi-1.2</feature>
<feature>concurrent-1.0</feature>
<feature>ejbLite-3.2</feature>
<feature>el-3.0</feature>
<feature>jsf-2.2</feature>
<feature>jsp-2.3</feature>
<feature>localConnector-1.0</feature>
<feature>servlet-3.1</feature>
<feature>jpa-2.1</feature>
<!--The following features are available in Liberty base and above. -->
<feature>jaxb-2.2</feature>
</featureManager>
Peristence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1"
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">
<persistence-unit name="BlueeCron" transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>jdbc/BlueeUPMDataSource</jta-data-source>
<mapping-file>META-INF/queries.xml</mapping-file>
<class>com.bcbsnc.providers.models.BlueEReqst</class>
<class>com.bcbsnc.providers.models.BlueERespn</class>
<properties>
<property name="eclipselink.logging.level" value="ALL" />
<property name="eclipselink.logging.level.sql" value="FINE" />
<property name="eclipselink.logging.parameters" value="true" />
</properties>
</persistence-unit>
#Stateless
#Repository("emJPADao")
public class JPADao {
EntityManager entityManager = Persistence.createEntityManagerFactory("BlueeCron").createEntityManager();
public Integer purgeBxTables() {
Integer rowsDeleted = 0;
try {
Integer noOfDays = Integer.parseInt(this.getConfigurationData("PurgeBXTablesPeriod"));
rowsDeleted = entityManager.createNamedQuery("PURGE_BX_TABLES").setParameter("noOfDays", getTimeStamp(noOfDays, false)).executeUpdate();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
if(entityManager.isOpen())
entityManager.close();
}
}
}
Logs at server startup
Launching defaultServer (WebSphere Application Server 17.0.0.2/wlp-1.0.17.cl170220170523-1818) on IBM J9 VM, version pwa6480sr4fp5-20170421_01 (SR4 FP5) (en_US)
[AUDIT ] CWWKF0012I: The server installed the following features: [jsp-2.3, ejbLite-3.2, servlet-3.1, jsf-2.2, beanValidation-1.1, ssl-1.0, jndi-1.0, jca-1.7, jdbc-4.2, localConnector-1.0, appSecurity-2.0, jaxrs-2.0, restConnector-1.0, el-3.0, jaxrsClient-2.0, concurrent-1.0, wmqJmsClient-2.0, jaxb-2.2, json-1.0, jpaContainer-2.1, adminCenter-1.0, cdi-1.2, distributedMap-1.0, jpa-2.1].
[AUDIT ] CWWKF0011I: The server defaultServer is ready to run a smarter planet.
[EL Info]: server: 2017-10-19 10:23:13.215--ServerSession(1864654006)--Detected server platform: org.eclipse.persistence.platform.server.was.WebSphere_Liberty_Platform.
S
Exception :
[err] javax.persistence.TransactionRequiredException:
Exception Description: No externally managed transaction is currently active for this thread
[err] at org.eclipse.persistence.internal.jpa.transaction.JTATransactionWrapper.throwCheckTransactionFailedException(JTATransactionWrapper.java:94)
[err] at org.eclipse.persistence.internal.jpa.transaction.JTATransactionWrapper.checkForTransaction(JTATransactionWrapper.java:54)
[err] at org.eclipse.persistence.internal.jpa.EntityManagerImpl.checkForTransaction(EntityManagerImpl.java:2054)
[err] at org.eclipse.persistence.internal.jpa.QueryImpl.executeUpdate(QueryImpl.java:291)
[err] at com.bcbsnc.providers.dao.JPADao.purgeBxTables(JPADao.java:49)
The executeUpdate() method requires for the EntityManager to be enlisted with a transaction - a global transaction in this case since you have defined a JTA-type persistence unit. You have chosen to use JPA's JSE bootstrapping approach (using Persistence.createEntityManagerFactory() instead of injection via #PersistenceContext or #PersistenceUnit) -- while I don't endorse using the JSE bootstrapping method in an EE application, it's not dis-allowed by the spec.
However, I believe the problem you are hitting is the fact that what you have effectively here is an application-managed persistence context, and thus your application is responsible for its enlistment with the global transaction (which would have been begun automatically by the EJB container when purgeBxTables() was called, as I do not see any annotations declaring it as a bean-managed-transaction session bean) which requires calling EntityMangager.joinTransaction().
An application-managed EntityManager will only join the global transaction automatically when the EntityManager is first created. Which is not the case for your application since the EntityManager is created when the bean class is constructed. Otherwise, the joinTransaction() method invocation is required in order for an EntityManager to join a new transaction.
Your application will need to call em.joinTransaction() before you call executeUpdate().
Using a container managed persistence context (using #PersistenceContext to inject an EntityManager) would have had the EntityManager automatically join the global transaction (unless you override the default Transaction SynchronizationType to UNSYNCHRONIZED.)

drools #KSession throws exception when using kmodule in separate jar

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

Apache Camel + Spring (war) + Tomcat + REST

I am trying to develp a rest service using apache camel. My project is a spring mvc war deployed on tomcat.
I dont want to use apache cxf (cxf servlet).
public class SampleRouter extends RouteBuilder {
#override
public void configure() throws Exception {
from("cxfrs://http://localhost:1234/sample")
.process (new Processor() {
public void process(Exchange exchange) throws Exception {
System.out.println("test");
}
})).setBody(constant("SUCCESS"));
}
}
#Path("/sample")
public class SampleResource {
#GET
public void test() {
}
}
web.xml has dispatcherservlet, contextloaderlistener.
dispatcher-servlet.xml has mvc:annotation-drivem, context:component-scan,
<camelContext id="server" trace="true" xmlns="http://camel.apache.org/schema/spring">
<contextScan />
</camelContext>
pom.xml has camel-core, camel-cxf, camel-stream, cxf-rt-transports-http-jetty, cxf-rs-frontend-jaxrs, camel-spring, spring-webmvc, spring-web, spring-context.
Tomcat runs on 8080, there seems to be no exception when server comes up. But, I tried hitting the url (http://localhost:1234/sample), nothing seems to be happening.
What am i missing? I would eventually extend this to REST to Spring DSL or REST to Java DSL with authentication, filters and interceptors.
I also tried cxf:rsServer and referred that in router class.
Also, in the future if i have to use https instead of http? or how do i have the url not hard-coded?
It may be too late, but to consume HTTP requests, one may use Apache Camel Servlet component
http://camel.apache.org/servlet.html
You need to setup the resourceClass option on the cxfrs endpoint. Here is an example
from("cxfrs://http://localhost:1234/sample?resourceClasses=my.pachage.SampleResource")
You can find some example in camel-cxfrs component page.
If you want to export a CXF service through servlet transport, you need to do some work as it said.
If you want to change the address dynamically, you can take look at the camel properties component.
If you are looking to start a camel route by a consuming cxf rest service which uses the servlet transport then you need to :
Clean up your pom.xml and remove any references to jetty.
Add the CXF servlet to your web.xml
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- all our webservices are mapped under this URI pattern -->
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
Add the servlet-transport dependency:
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>${cxf-version}</version>
</dependency>
In your spring/camel configuration
<import resource="classpath:META-INF/cxf/cxf.xml"/>
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<cxf:rsServer id="rsServer" address="/restService"
serviceClass="com.something.test.SimpleServiceImpl"
loggingFeatureEnabled="true" loggingSizeLimit="20" />
Build a route from this consumer endpoint as:
from("cxfrs:bean:rsServer?bindingStyle=SimpleConsumer")
.to("log:TEST?showAll=true")
You can now view/(invoke with a method) the endpoint using : http://host:port/context/services/restService?_wadl