Web Service Deployment Descriptor - java

What is the purpose of Web Service Deployment Descriptor (wsdd) configuration file.
If I didn't configure this file explicitly it doesn't create any issue in my application (as I am using a .jws file to do some web service related processes). But, for the first time the application runs, an error is logged in the error log file. The error is as follows:
"Unable to find config file. Creating new servlet engine config file: /WEB-INF/server-config.wsdd". And when the page refreshes or even the application is re-logged in (still the server is running), there won't be any such error log further times. When I use a sample wsdd file in my application, the error is not at all logged in the error log file. I want to know the purpose of this wsdd file and how to configure it based on our application.
Any suggestions would be appriciated.
Marshal.

Just do a google on "server-config.wsdd".
e.g. http://axis.apache.org/axis/java/integration-guide.html
It looks like your container or framework is generating a default file if you don't specify one, which is useful, but if you wish to add additional customisations such as handlers, security and logging (etc) then you can specify your own file.
It might be best to use a "bare minimum" file so you can customise it later.

Related

Can I update log4j 1.2 xml configuration file programmatically?

I know it is possible to reload log4j's xml configuration while the application is running, but the searching I've done only shows how to do this when the XML config file is edited manually via a text editor.
I want to be able to dynamically change the level of the root logger in my application via a web page and persist that change to the log4j XML configuration, so I won't have to change the log level again if I restart the application. Is it possible to do this, or can the log4j XML file only be updated manually?
I am using log4j 1.2 in my application.
Many thanks in advance!
for any chump who finds themselves stuck dealing with this, it is possible to write out the data as properties using
org.apache.log4j.config.PropertyPrinter;
You can acheive this by PropertyConfigurator configure and watch.
Read the configuration file configFilename if it exists. Moreover, a thread will be created that will periodically check if configFilename has been created or modified. The period is determined by the delay argument. If a change or file creation is detected, then configFilename is read to configure log4j.

Filter log4j 2.0 messages to separate log files per-webapp

Executive Summary
How do I filter by the servlet in which the log message was invoked? (presently using 2.0 beta8)
Why on earth I would want to do that...
I have several existing web applications. They were written to rely on a proprietary logging system. I have re-implemented a key class from the proprietary system from scratch and added it as a class the proprietary system as a jar and log4j 2.0 as jars in tomcat, thereby utilizing the class loading load order in tomcat to divert the proprietary system into log4j. This succeeds and my log4j config now controls everything (Yay!).
But... (There's always a "But"!)
I was very pleased until I discovered that with all 4 applications deployed in the same container, they were not coordinating their writes to the single log file in the single configuration I had placed in conf/log4j2.xml (and specifed by passing -Dlog4j.configurationFile=/mnt/kui/tomcat/conf/log4j2.xml on the command line). I found some log messages with much earlier time stamps (hours earlier) in the middle of the log file. Out of order logs (and possibly overwritten log lines?) are not desirable of course.
I actually don't want them all in one file anyway and would prefer a log per application controlled by a single config file. Initially I thought this would be easy to achieve since log4j automatically sets up a LoggingContext with the name of the web application.
However I can't seem to find a filter implementation that will allow me to filter on the LoggingContext. I understand that from each application's perspective there is only one logging context (I think), but the same config file is read by 4 applications so from the config perspective LoggingContext is not unique.
I'm looking for a way to route each application to it's own file without having a config file for every application, or having to add classes to all the applications or edit war files (including web.xml). I'm sooo... close but It's not working.
Just to complicate matters, there is a jar file we wrote that is shared among all 4 applications that uses this logging too and one application has converted to using log4j directly in it's classes (but it still uses proprietary classes that reference the proprietary logging class that I replaced).
I have already seen http://logging.apache.org/log4j/2.x/manual/logsep.html and my case seems closest to '"Shared" Web Applications and REST Service Containers' but that case doesn't seem very well covered by that page.
You may want to look at the RoutingAppender which can be used to separate log files based on data in your ThreadContextMap. You could use the web app name as a unique key.
About the out of order logs, there was an issue with FastFileAppender in older betas. If append was false, the old file was not truncated but new log events would start to overwrite the old file from the beginning. (So after your most recent log event you would see yesterday's log events, for example). What version are you using?

off-the-shelf web application working directory

I've just started working with Spring/java web. I'm wondering how to accomplish following scenario:
Let's say that I'm creating an application which supports file upload, uses a database connection and maybe a web service. This is an off-the-shelf system, so all the settings are customer specific and should be configured by customer's IT people on the deployment time.
More general in the web.xml file I would like to point the application working directory containing uploaded files, license key file, configuration files, other customer specific resources and maybe even fragments of spring context.
<context-param>
<param-name>workdir</param-name>
<param-value>/var/r2/</param-value>
</context-param>
In my application I would like use the workdir value in order to include configuration files ...
<import resource="wordir_param_value/settings.properties" />
context config fragments
<import resource="wordir_param_value/security.xml"/>
And how may I later use these values in the java code? What is "the best" approach in case like this anyway (off-the-shelf application config)?
Best Regards,
Alek
You can use Spring's property support for that. This allowed two different approaches:
Having a property file outside the application (at a fixed location), the admin can edit it, and the application loads it
In a Tomcat you can write properties in the application specific context.XML file
In the code use #value annotation to inject the properties in a variable.
In the spring XML file you use it with ${name}
Of course you need to configure the proprtyPlaceholderConfigurer

JBoss automatic redeploying

As I understand it, JBoss* monitors a variety of file types in /deploy and performs certain actions when the file changes. For example, JBoss will redeploy an EAR when its last-modified time changes.
Therefore, I could use some really nasty code to make an EAR redeploy itself, like this:
URL url = this.getClass().getClassLoader().getResource("../RavenWeb.ear");
String path = url.getPath();
File ear = new File(path);
ear.setLastModified(System.currentTimeMillis());
But what I really want to do is just have JBoss redeploy the webapp when an external config file changes. Say the config file lives at C:/foo/bar.properties.
Is there an MBean or some other way getting this done that won't get me mauled by velociraptors?
*I'm using JBoss 5.1.0, if it matters.
I think your best shot is having a MBean that will reload your config file whenever you call a function on it. If you wan't this to happen automatically, you can also consider having a MBean handling the configuration file for you. This way, you can just update MBean properties instead of changing a configuration file.
I've copied the Log4JService implementation and put it in a .sar.
It just simply polls the configuration file, parse it and put a Configuration object in the JNDI, so that I can retrieve it in my application. In this way you don't have to redeploy the entire application, and you can use the new configuration in the app.
If you have to do something else than simply reloading the app, you can do it in this service.

Logging Java web applications?

I am planning to implement logging into a web application that I am currently working on but I am struggling with some of the details. What is the best way to go about logging a Java web application?
Specifically;
Where does the configuration file go in .war package file?
Where do people log to, relative or absolute path flat file, or a database?
Does Log4J logging go directly into the application server log file automatically or is that something you have to set up? In this case I am using Tomcat, but I often use Jrun.
Any other gotchas I should be aware of for web application logging?
Currently I am using Log4J but I imagine that the best practices would apply universally to all logging implementations.
EDIT:
One addition to the questions up top.
Where do you initilize the log
configuration?
In a traditional app, I do this at the entry point;
DOMConfigurator.configureAndWatch("log4j.xml");
What would the web application equivalent be?
I would recommend you to use SLF4J. This is simple logging facade which supports most of popular logging systems (Log4j, commons-logging, Java Logging API and Logback).
Using it, you will able to replace your underline logging system to any other, by simple CLASSPATH update.
The other benefit of SLF4J are parameterized calls, which reduces ugly logging code.
Actually, they recommends to use SLF4J with Logback.
Logback is a successor of Log4J. And it was designed by the same author.
Where does the configuration file go in .war package file?
Root of the classpath.
Where do people log to, relative or absolute path flat file, or a database?
Depends on the need. It's always better to use relative paths. Databases are good if you implement another application which will fetch logs from it and send them using email/sms
Does Log4J logging go directly into the application server log file automatically or is that something you have to set up? In this case I am using Tomcat, but I often use Jrun.
If you use Console appender, yes, it's going to be logged in your servlet container log file.
Any other gotchas I should be aware of for web application logging?
If you are logging from different threads use logback, it's thread-safe and it exposes parameterized log messages.
Logging to a DB adds another failure point. We had a situation where the prod servers logged to a DB and someone ran an expensive query on that DB that slowed it so much that the prod servers got very, very slow. Logging to a file can cause issues if you run out of space but it seems less likely to slow down the whole app.
I place my configuration on the default package: src/
and log to files using the ${catalina.home} system property:
log4j.appender.???.file=${catalina.home}/logs/system.log
It might be a good idea to place the config file somewhere where an admin can modify it without rebuilding your web app (e.g., so they can turn on detailed logging without waking you up in the middle of the night).
Unfortunately, there's no "official" way for locating externalized resources from a web app (correct me if I'm wrong). The most common way of doing it I've seen is to look through the directories in the classpath.
The excellent paper How to Do Application Logging Right has a bunch of gotchas.
I believe that your other questions have been answered by other people on this page.
I also recommend that you use SLF4J.
One last thing: having speakable representations of objects can save some time.
I recommend to call log API (log4j) via slf4j. Even if you use log4j, web container or depending modules may use different log API such as Java.util.logging or Jakarta commons logging. Slf4j provides bridge modules that redirect them to slf4j API. As a result, all log messages are written by log4j in that case.
put the log4j in the container (server) and create proper appenders per application
relative to server path, but that depends on your needs
we use appenders which log to different files, depends on your needs, e.g. one file for hibernate info/statistics, one for application only, etc.
don't log to much, it slows the application down
Personally I put the log4j.properties in the WEB-INF directory and use an init servlet with the following code :
public class InitServlet extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {
private static final String LOG4J_FILE = "WEB-INF/log4j.properties";
public InitServlet() {
super();
}
#Override
public void init() throws ServletException {
super.init();
PropertyConfigurator.configure(getServletContext().getRealPath(LOG4J_FILE));
LogFactory.getLog(InitServlet.class).info("LOG 4J configured");
}
}
Where does the configuration file go in .war package file?
At the root of the classpath but... Don't put the configuration file in the war package. You don't want to repackage and redeploy the application if you change the logging configuration, do you ? A better practice would be to put the configuration file somewhere in the classpath outside the war.
Where do people log to, relative or absolute path flat file, or a database?
I usually log to the file system on a separate partition (log files can grow very fast and should never block the application or the operating system if they become too big). I use most of time an absolute path based on the following model: /var/projects/<PROJECT_NAME>/<PRODUCT>/<CLUSTER_NAME>/logs/<INSTANCE_NAME>.log where <PROJECT_NAME> is the project name, <PRODUCT> can be Apache, Tomcat, Weblogic,..., <CLUSTER_NAME> the name of the cluster and <INSTANCE_NAME> the name of the instance inside the cluster. Logging to the file system is faster than in a database. The drawback is that logs aren't centralized if you are using several instances and physical machines. But merging can easily be done with a script.
Does Log4J logging go directly into the application server log file automatically or is that something you have to set up? In this case I am using Tomcat, but I often use Jrun.
Application server logs are application server logs, not application logs. Don't write to them but set up a logger tool (e.g. log4j) and write to application logs (understand dedicated).
Any other gotchas I should be aware of for web application logging?
If you are using log4j, don't forget to use the isDebugEnabled() before to log:
if(logger.isDebugEnabled()) {
logger.debug("Bla Bla Bla");
}
Where does the configuration file go in .war package file?
Usually, I do not place any logging configuration into the application, rather leaving that to the appserver admins to configure logging server-wide. In the rare cases I want the log4j configuration deployed with a webapp, WEB-INF is the usual path.
Where do people log to, relative or absolute path flat file, or a database?
Again, depends on appserver settings. One common log file for a appserver and rotating on a daily basis is the usual setup. If there are any app-specific needs, the admin may configure a separate logfile for an app (distinguished by package / class names).
Does Log4J logging go directly into the application server log file automatically or is that something you have to set up? In this case I am using Tomcat, but I often use Jrun.
See above. For tomcat used for development purposes, I'd just look for its logging (log4j) configuration and add app-specific specific there.
Any other gotchas I should be aware of for web application logging?
Performance. Limit the ,log level to a minimum (i.e. WARN or ERROR) once you go live. Use
if (log.isDebugEnabled()) { log.debug("..."); } and alike constructs in your code.
Note that if you just need a bit of logging, the servlet standard specifies that you can get the ServletContext and use the log methods there. That is the generic servlet equivalent of System.out.println.

Categories