How to configure hibernate logging using log4j2.xml? - java

I recently switched to Apache log4j2, and still can not find a way to configure hibernate logging using log4j2.xml.
Because I can not find a way around this problem I still use log4j.properties file explicitly for hibernate. This is not the best solution since my log4j2.xml uses JPA appender (writes logs to db). I do not want to write separate logic for hibernate.
Is there a way to configure hibernate logging using log4j2?

As suggested in
https://issues.apache.org/jira/browse/LOG4J2-172
you can add system property to force hibernate use slf4j
-Dorg.jboss.logging.provider=slf4j
also log4j-slf4j-impl should be added to classpath
My custom solution:
with Spring you can place
org.jboss.logging.provider=slf4j
in property file
(envConfigLocation is file url)
<bean id="propertyConfigurer" class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
<property name="location" ref="envConfigLocation" />
<property name="order" value="1"/>
</bean>

I found an answer to this question at: How to redirect all logs from hibernate and spring to log4j2?
Basically log4j2 doesn't work with Hibernate so you have to use log4j. But you still use your log4j2 configuration. You need the following dependencies and then the magic happens in the background.
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-1.2-api</artifactId>
<version>2.1</version>
</dependency>
<dependency>
<!--HIBERNATE LOGGER (log4j)-->
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.6</version>
</dependency>

It is possible to redirect calls to the log4j-1.x API to the log4j-2.0 implementation. The FAQ about which jars to include explains how to do this. You probably need to remove the old log4j-1.x jar from the classpath when you do this.

Related

How to use log4j.xml for spring boot + log4j2 dependency

I have a log4j.xml with a customized appender like:
<appender name="console" class="com.example.MyAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%m (%c{1}:%L)"/>
</layout>
</appender>
Recently I upgraded log4j dependency to log4j2, but still using this log4j.xml and it works.
Now, I add a Spring Boot module in my project. Following Spring doc, I set my pom.xml as
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
<version>2.6.4</version>
</dependency>
And I also add arguments -Dlogging.config=log4j.xml -Dlog4j.configuration=log4j.xml -Dlog4j1.compatibility=true for it.
But my Spring application shows the error and no log output:
ERROR StatusLogger Unknown object "logger" of type org.apache.logging.log4j.core.config.LoggerConfig is ignored: try nesting it inside one of: ["Appenders", "Loggers", "Properties", "Scripts", "CustomLevels"].
Seems log4j2 lib cannot recognize log4j.xml, which means -Dlog4j1.compatibility=true does not work for Spring Boot I think.
Any related config can be utilized or any workaround? Thanks.
TL;DR: The problem is that Log4j2 has two XML configuration factories (for the Log4j 1.x and Log4j 2.x formats), with the 2.x format having higher priority. You need to explicitly set the ConfigurationFactory to use:
-Dlog4j2.configurationFactory=org.apache.log4j.xml.XmlConfigurationFactory
When a Spring Boot application starts Log4j2 is configured twice:
at the very beginning using Log4j2 automatic configuration. For this round you just need to set -Dlog4j1.compatibility=true and call the config file log4j.xml or call the file differently and set -Dlog4j.configuration.
when Spring's environment is ready, Spring reconfigures Log4j2 programmatically using only a subset of Log4j2 automatic configuration. That is why this phase requires many manual settings:
-Dlogging.config=log4j.xml: Spring does not look for a file named log4j.xml,
-Dlog4j1.compatibility=true to activate the Log4j 1.x configuration factories,
-Dlog4j2.configurationFactory=org.apache.log4j.xml.XmlConfigurationFactory to increase the priority of the Log4j 1.x XML configuration factory.
Remark: Using a native Log4j 1.x custom appender exposes you to all the problems (synchronization and performance) of the original Log4j 1.x. For example Log4j 1.x looses events during reconfiguration (as the one performed by Spring Boot), whereas Log4j 2.x does not.

camel cxf on wildfly

I'v created a SOAP webservice and I'd like to expose it with camel-cxf on wildfly.
When I want to deploy it I get the following error:
Apache CXF library (cxf-core-3.2.0.jar) detected in ws endpoint deployment; either provide a proper deployment replacing embedded libraries with container module dependencies or disable the webservices subsystem for the current deployment adding a proper jboss-deployment-structure.xml descriptor to it. The former approach is recommended, as the latter approach causes most of the webservices Java EE and any JBossWS specific functionality to be disabled.
Tried what was suggested here but didn't work. Tried to exclude the cxf dependencies from the caml-cxf include in my pom.xml:
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-cxf</artifactId>
<version>2.20.0</version>
<exclusions>
<exclusion>
<groupId>org.apache.cxf</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
That solved the error but produces new ones:
Failed to define class org.apache.camel.component.cxf.spring.AbstractCxfBeanDefinitionParser in Module "deployment.CamelCXF-1.0.war" from Service Module Loader: java.lang.NoClassDefFoundError: Failed to link org/apache/camel/component/cxf/spring/AbstractCxfBeanDefinitionParser
Failed to define class org.apache.camel.component.cxf.spring.CxfEndpointBeanDefinitionParser in Module "deployment.CamelCXF-1.0.war" from Service Module Loader: java.lang.NoClassDefFoundError: Failed to link org/apache/camel/component/cxf/spring/CxfEndpointBeanDefinitionParser
Context initialization failed: org.springframework.beans.factory.BeanDefinitionStoreException: Unexpected exception parsing XML document from ServletContext resource [/WEB-INF/camel.xml]; nested exception is org.springframework.beans.FatalBeanException: Invalid NamespaceHandler class [org.apache.camel.component.cxf.spring.NamespaceHandler] for namespace [http://camel.apache.org/schema/cxf]: problem with handler class file or dependent class; nested exception is java.lang.NoClassDefFoundError: Failed to link org/apache/camel/component/cxf/spring/CxfEndpointBeanDefinitionParser
Could you help me resolve these errors or provide a small working example that I can deploy on wildfly and extend? Much appreciated.
Defined these dependencies in my pom.xml:
<dependencies>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
<version>2.20.0</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-cxf</artifactId>
<version>2.20.0</version>
<exclusions>
<exclusion>
<groupId>org.apache.cxf</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.0.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.1.RELEASE</version>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-web-api</artifactId>
<version>8.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
And here's my camel.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:camel="http://camel.apache.org/schema/spring"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:cxf="http://camel.apache.org/schema/cxf"
xsi:schemaLocation="
http://camel.apache.org/schema/spring
http://camel.apache.org/schema/spring/camel-spring.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://camel.apache.org/schema/cxf
http://camel.apache.org/schema/cxf/camel-cxf.xsd">
<cxf:cxfEndpoint id="customerEndpoint"
address="http://localhost:8080/TestService/"
serviceClass="my.package.TestService"
wsdlURL="WEB-INF/CustomerService.wsdl"/>
<bean id="logBean" class="my.package.LogBean"/>
<camel:camelContext xmlns="http://camel.apache.org/schema/spring">
<route>
<from uri="cxf:bean:customerEndpoint" />
<to uri="bean:logBean" />
</route>
</camel:camelContext>
Follow-up question
I could set up a webservice with the links provided by #Tadayoshi Sato. The examples, however, only use one simple function with one processor. How do I know which function was called when I have several operations in a port definition?
Is it possible to have camel call the implementation of the provided interface that was called or do I have to map that myself?
As Claus pointed out, the most recommended approach to use Camel on WildFly is using WildFly Camel. You can find in the link below how to install the WildFly Camel subsystem to WildFly:
http://wildfly-extras.github.io/wildfly-camel/index.html
Once you've installed WildFly Camel, let's see this link, where you can find how to develop code using camel-cxf on WildFly:
http://wildfly-extras.github.io/wildfly-camel/index.html#_jax_ws
The point is that WildFly already has its own CXF libraries as a subsystem and you are required to use the built-in libraries as much as possible; otherwise, you may encounter awkward problems like those in the question. It's the WildFly Camel subsystem that lets you to use the underlying WildFly subsystems for your Camel applications.
UPDATE:
For camel-cxf consumers, the operation name which is called is available via CxfConstants.OPERATION_NAME message header. According to:
https://github.com/apache/camel/blob/master/components/camel-cxf/src/main/docs/cxf-component.adoc
The camel-cxf endpoint consumer POJO data format is based on the CXF invoker, so the message header has a property with the name of CxfConstants.OPERATION_NAME and the message body is a list of the SEI method parameters.
You may route a message based on this message header and change the implementations accordingly.

Arquillian TomEE tests performance

I'm using Arquillian and TomEE embedded adapter to test a WAR.
In my pom.xml I have the following entry
<dependency>
<groupId>org.apache.openejb</groupId>
<artifactId>arquillian-tomee-embedded</artifactId>
<version>1.7.2</version>
<scope>test</scope>
</dependency>
and in my arquillian.xml I have the following
<container qualifier="tomee" default="true">
<configuration>
[...]
<property name="javaVmArguments">-Xms2048m -Xmx2048m</property>
<property name="singleDumpByArchiveName">true</property>
<!--<property name="singleDeploymentByArchiveName">true</property>-->
[...]
</configuration>
</container>
Adding the property singleDumpByArchiveName I expected that, dumping only once the web archive for all the tests, there would be an improvement in terms of execution time, but that did not happen.
I also tried to add the Arquillian Suite Extension with the same goal
<dependency>
<groupId>org.eu.ingwar.tools</groupId>
<artifactId>arquillian-suite-extension</artifactId>
<version>1.1.2</version>
<scope>test</scope>
</dependency>
but I get the following error
java.lang.NoSuchMethodError: org.jboss.arquillian.test.spi.TestResult.setEnd(J)V
Do you have any tip on how to make these solutions work or can you suggest others to speed up the tests execution time?
first of all:
<property name="javaVmArguments">-Xms2048m -Xmx2048m</property>
is not a tomee configuration since tomee embedded doesn't fork a JVM, probably something copied/pasted from the net.
Then your error probably just means you have a dependency conflict (tomee brings an older version of arquillian). You need to fix that. You can need to use tomee 1.7.4 (or 7.x) which is compatible with arquillian > 1.1.11

Testing Jersey endpoints with members annotated with springs #Value

I'm trying to use Jersey and it's integration with Spring, in order to have jax-rs endpoints in our spring web-app.
The problem I have is that members of the application that are annotated with #Value isn't populated in our unit tests.
The ones that are populated with #Autowired works fine, and if I create a setter method for the string and annotate that with #Value that also works.
What annoys me is that members annotated directly with #Value doesn't work in the test, but work when deployed in our tomcat.
Is this a problem with our test configuration somehow? Or is this a known issue somewhere?
These are the relevant dependencies I think:
<dependency>
<groupId>org.glassfish.jersey.ext</groupId>
<artifactId>jersey-spring3</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.test-framework</groupId>
<artifactId>jersey-test-framework-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
<artifactId>jersey-test-framework-provider-jetty</artifactId>
<scope>test</scope>
</dependency>
A small project that examplifies the problem here:
https://github.com/alexanderkjall/jersey-jetty-interaction-example/blob/master/src/main/java/no/hackeriet/bugs/SpringRequestResource.java
Seems to be you might be missing component-scan, After adding it worked fine for me.
<context:component-scan base-package="no.hackeriet.bugs" />
but I am not sure how it still worked in tomcat without component-scan, which quite puzzles me.

Spring - Build path is incomplete. Cannot find class file for org/springframework/beans/factory/Aware in dispatcher-servlet.xml

I installed Spring Tool Suite and am now using it for a little sample project. However I keep having an error in my dispatcher-servlet.xml file:
Build path is incomplete. Cannot find class file for org/springframework/beans/factory/Aware
This error is highlighted here:
<bean
**class="org.springframework.web.servlet.view.InternalResourceViewResolver">**
<property name="prefix">
<value>/WEB-INF/pages/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
Any thought?
I think you may have some old jar files in your configuration. Try using the most current spring libraries.
I found my self in exactly the same case when I used incompatible maven spring-dependencies i.e check Spring Security Site on the right side where it explains what spring version should be used with what spring security version.
The project is missing the servlet-api jar and the error can be resolved by adding the dependency in the maven pom file
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
you can put this dependency with your spring version :
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring-version}</version>
<scope>compile</scope>
</dependency>
If you are using eclipse:
Right click on root project -> properties.
Click on Deployment Assembly.
Click add button.
Double click on Java Build Path Entries and Select build path
entries to include. (maybe if you are using maven, you need also
include those dependencies).
Finally clean and build.
This worked for me.

Categories

Resources