How do you override a log4j2 configuration file with another log4j2 configuration file? - log4j

My current web application uses log4j 1.2, and I'd like to migrate to log4j2, but I haven't been able to figure out how to handle my particular use case.
In my web app's war file, I store a log4j configuration file which has reasonable defaults. My design is to search for a configuration file external to the war file which would override the configuration bundled with the war. That way logging configuration is configured at deployment time and can be different for each server.
Using log4j 1.2, this is accomplished via a ServletContextListener with the following method and it works great:
/**
* Configures system-wide log4j logging system with log4j.xml from the
* class path. This overrides configuration from the default location in
* Tomcat: WEB-INF/classes
*/
private void configureLog4J() {
URL url = ClassLoader.getSystemResource("log4j.xml");
if (url != null) {
DOMConfigurator.configure(url);
log = org.apache.log4j.LogManager.getLogger(LDSContextListener.class);
log.info("log4j.xml loaded from " + url);
}
}
If I'm going to migrate to log4j2, how can I override the internal file with configuration from an external file? log4j2 doesn't have DOMConfigurator in its API.

I found a solution that doesn't exactly replicate what I had before, but comes close enough.
Instead of programmatically configuring log4j, I add log4j-web-2.0.jar to my classpath and add the following to my web.xml:
<context-param>
<param-name>isLog4jAutoInitializationDisabled</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>log4jConfiguration</param-name>
<param-value>file:///usr/jboss/ldsconf/log4j2.xml</param-value>
</context-param>
<listener>
<listener-class>org.apache.logging.log4j.web.Log4jServletContextListener</listener-class>
</listener>
<filter>
<filter-name>log4jServletFilter</filter-name>
<filter-class>org.apache.logging.log4j.web.Log4jServletFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>log4jServletFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
<dispatcher>ERROR</dispatcher>
<dispatcher>ASYNC</dispatcher><!-- Servlet 3.0 w/ disabled auto-initialization only; not supported in 2.5 -->
</filter-mapping>
where the log4jConfiguration context-param specifies where my external configuration file is. This isn't the same as the ClassLoader searching the classpath for the configuration file, but it still allows me to reference an external configuration file. Also, if this file isn't present, the system falls back to the internal configuration file, which is exactly what I wanted.
Reference: http://logging.apache.org/log4j/2.x/manual/webapp.html

You can add an environment variable called LOG4J_CONFIGURATION_FILE while you start the application.

I suggest you create a feature request on the Log4j2 Jira issue tracker.

Related

Why uploading file with tomahawk is not working?

I have an Icefaces 3.x + JSF 2.1 app where I tried to integrate upload file solution from here but I receive
14:31:24,506 WARN
[org.apache.myfaces.custom.fileupload.HtmlFileUploadRenderer]
(http-localhost-127.0.0.1-8080-3) t:inputFileUpload requires
ExtensionsFilter or TomahawkFacesContextFactory configured to handle
multipart file upload, and any of them has been detected. Please read
the instructions on
http://myfaces.apache.org/tomahawk/extensionsFilter.html for more
information about how to setup your environment correctly. Please be
sure ExtensionsFilter is the top most filter if you are using multiple
jsf libraries. 14:31:24,507 WARN
[org.apache.myfaces.custom.fileupload.HtmlFileUploadRenderer]
(http-localhost-127.0.0.1-8080-3) t:inputFileUpload requires the
current request be intercepted by the filter in order to handle forms
with multipart encode type. ExtensionsFilter was initialized but the
current request was not intercepted. Please add a filter-mapping entry
to intercept jsf page requests.
which is pretty strange because I added:
<filter>
<filter-name>MyFacesExtensionsFilter</filter-name>
<filter-class>org.apache.myfaces.webapp.filter.ExtensionsFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>MyFacesExtensionsFilter</filter-name>
<servlet-name>Faces Servlet</servlet-name>
</filter-mapping>
into my web.xml but still the uploaded file is null.
Any clue to what I do wrong?

Expose and access static XSD schema in Spring WS 2

I can't reach XSD schema. Here is my configuration:
web.xml
<servlet>
<servlet-name>spring-ws</servlet-name>
<servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class>
<init-param>
<param-name>transformWsdlLocations</param-name>
<param-value>true</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>spring-ws</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
spring-ws-servlet.xml
<sws:annotation-driven/>
<context:component-scan base-package="example.ws.endpoint"/>
<sws:dynamic-wsdl id="boo"
portTypeName="BooResource"
locationUri="/services/">
<sws:xsd location="classpath:example/ws/schema/Boo.xsd"/>
</sws:dynamic-wsdl>
WSDL is accessible on [http://localhost:port/spring-ws-server-0.1-SNAPSHOT/services/boo.wsdl], but how can I expose XSD and what will be the URL?
I've been able to expose my XSD's without using Spring-MVC for it by defining something like this in my #Configuration class:
private ClassPathResource messagesXsdResource = new ClassPathResource("messages.xsd");
#Bean
public SimpleXsdSchema messages() {
return new SimpleXsdSchema(messagesXsdResource);
}
You should take a look at this question as well, that explains how to do this in XML.
I'm afraid this is not possible, at least not automatically like your WSDLs are exposed. Spring WS doesn't intend to make your XSDs available like it does with the static and generated WSDLs. Of course, you can make your XSDs available through a simple servlet or through MVC (if you're using MVC as well).
If you're using Spring Boot, whatever you put under the public folder which you can create under resources, will be publicly available.
You can put your xsd there and point your wsdl to that definition:
<xsd:schema>
<xsd:import namespace="http://jaxws.com.your.ns" schemaLocation="/your.xsd"/>
</xsd:schema>
Now this will make your xsd available at http://localhost:8080/your.xsd

Configure web service in seam ("no active application context")

I am building a web service using seam 2.0.1 and deploying it on jboss 4.2.2 GA. I have my web service class which access another class (updates stuff in data base).
I have standard-jaxws-endpoint-config.xml in META-INF folder.
#Name("pluginHandler")
#Scope(ScopeType.APPLICATION)
#Install(precedence = Install.BUILT_IN)
#Startup(depends = "someclass")
#Stateless
#WebService(name = "Plugin", serviceName = "PluginService")
public class PlugInHandler {
#WebMethod
public int processRequest(Account account)
{
Workbench wb = Component.getInstance("Workbench");
//above line keeps throwing exception "No application context active"
}
}
I have been looking all over different forums, but I cannot find a solution. I tried using Lifecycle.begincall() and Lifecycle.endCall() but nothing worked.
Do I need web.xml as well? If yes what information should web.xml contain?
Any help would be highly appreciated.
I recognize that this is question is rather dated, but to those few poor souls out there that still share your (and, currently my) predicament, here are a few pointers (dragged together from various sources but mainly from https://community.jboss.org/thread/192046):
Java EE WebService
First, using JBoss 4.2.2 likely means using Java EE5. WebServices there (with or without SEAM 2) can only be created on top of Stateless Session Beans. Stateless Session Beans in Java EE 5 need to implement a Service Endpoint Interface annotated with #Local or #Remote. While this has become optional in Java EE6, it is still mandatory here.
So:
#Local
public interface PluginHandlerInterface {
int processRequest(Account account);
}
#WebService
#Stateless
public PluginHandler implements PluginHandlerInterface { }
POJO WebService
If, in seam, you want to use a regular POJO as web-service, your class has to have another special annotation defining a Handler chain:
#WebService
// This here makes all the difference!
#HandlerChain(file = "web-service-handler-chain.xml")
public class PluginHandler {
...
}
This is the handler chain you put in /WEB-INF/classes/web-service-handler-chain.xml:
<?xml version="1.0" encoding="UTF-8"?>
<handler-chains xmlns="http://java.sun.com/xml/ns/javaee">
<handler-chain>
<handler>
<description>seam request handler</description>
<!-- probably not necessary
<handler-name>org.jboss.seam.webservice.SOAPRequestHandler</handler-name>
-->
<handler-class>org.jboss.seam.webservice.SOAPRequestHandler</handler-class>
</handler>
</handler-chain>
</handler-chains>
And you have to announce your service class to the war files web.xml like so:
<listener> <!-- this might already be present in your web.xml -->
<listener-class>org.jboss.seam.servlet.SeamListener</listener-class>
</listener>
<servlet> <!-- Which class is to be used? -->
<servlet-name>PluginHandler</servlet-name>
<servlet-class>your.package.name.PluginHandler</servlet-class>
</servlet>
<servlet-mapping>
<!-- you'll find it under http://localhost:8080/your-war/PluginHandler?wsdl-->
<servlet-name>PluginHandler</servlet-name>
<url-pattern>/PluginHandler</url-pattern>
</servlet-mapping>
So these three steps, creating the handler chain, adding the annotation and announcing your service to the web.xml, should do the trick for you in SEAM: You'll have a web-service and the SEAM Context available right in it.

Oracle WebLogic GroovyServlet Error

We have a J2EE app running beautifully on tomcat-based app servers, but all groovy scripts seem to fail on weblogic (10.3.5.0) and also IBM WebSphere. It seems the script processing, not the content of the scripts are the issue. The app itsells is a spring MVC web app and the GroovyServlet is part of the web.xml descriptor:
<!-- Servlets -->
<servlet>
<servlet-name>Groovlet</servlet-name>
<servlet-class>groovy.servlet.GroovyServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Groovlet</servlet-name>
<url-pattern>*.groovy</url-pattern>
</servlet-mapping>
Calling a simple executor.groovy file results in an exception. My test script is small:
response.contentType = "application/json"
out.println "test"
But fails:
GroovyServlet Error: script: '/executor.groovy': Script processing failed.null
java.lang.NullPointerException
Anyone has a solution? Are there general issues with Groovy on weblogic or websphere?
Don't know if you're still having this issue :)
I had the same problem - the NullPointerException is caused by ServletContext.getRealPath(...) returning null.
There is a setting in Weblogic admin console which controls whether getRealPath() can be used.
It can also be configured in your weblogic.xml file by inserting the following (not sure how to deal with this in Websphere).
<container-descriptor>
<show-archived-real-path-enabled>true</show-archived-real-path-enabled>
</container-descriptor>
Sounds like response or out are not properly binded in weblogic. Did you try your servlet on another container. Also publishing more about the stacktrace and the web.xml could help

How to upload files in JSF 1.1?

I want to upload files in a JSF 1.1 project. JSF 1.1 doesn't support RichFaces file upload. I looked at Tomahawk, but I don't know how to use Tomahawk. Can anybody explain for me?
Which JARs do I have to use?
And taglibs?
And web.xml configuration?
And faces-config.xml configuration?
Or are there alternatives to Tomahawk?
Which JARs do I have to use?
The following ones:
tomahawk
commons-fileupload
commons-io
commons-logging
commons-el
I assume that you already have the JSF 1.1 JARs jsf-api and jsf-impl.
And taglibs?
Just the Tomahawk one, next to the two usual core/html tags:
<%# taglib uri="http://myfaces.apache.org/tomahawk" prefix="t" %>
And web.xml configuration?
You need the ExtensionsFilter. This filter will take care that JSF gets the right parameters out of a multipart/form-data request body.
<filter>
<filter-name>Extensions Filter</filter-name>
<filter-class>org.apache.myfaces.webapp.filter.ExtensionsFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>Extensions Filter</filter-name>
<servlet-name>Faces Servlet</servlet-name>
</filter-mapping>
And faces-config.xml configuration?
Nothing special. Just create a managed bean the usual way with a UploadedFile property which you bind to the value attribute of <t:inputFileUpload>.
See also:
How to upload files in JSF? (yes, it's targeted on JSF 1.2, but should work equally good in JSF 1.1).

Resources