og4j:WARN No appenders could be found for logger (org.geotools.factory).
log4j:WARN Please initialize the log4j system properly.
This is part of a general problem of a number of warning messages being issued as various open source projects start up.
The following clarification was offered on the user list
Hi Donovan,
This is related to the way that log4j uses reflection to find the appender.
I haven't looked deeply within the new udig 1.3.0 code base yet so I am not sure where things have moved and indeed if there is a log appender, but I did notice that there is a bundled org.apache.log4 library.
I have been running with SLF and log4j logging in my RCP plugins for some time and there are a couple of things that need to be done to permit log4j to work from plugins, please view the notes below:
- The bundled org.apache.log4j library provided in the udig code base doesn't have the correct directive in it to enable log4j to work, you need an Eclipse-BuddyPolicy: registered directive in the manifest of org.apache.log4j as follows:
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: org.apache.log4j
Bundle-SymbolicName: org.apache.log4j
Bundle-Version: 9.0.1.20110423
Bundle-Vendor: Apache Log4j
Export-Package: org.apache.log4j,
org.apache.log4j.chainsaw,
org.apache.log4j.config,
org.apache.log4j.helpers,
org.apache.log4j.jdbc,
org.apache.log4j.jmx,
org.apache.log4j.lf5,
org.apache.log4j.lf5.config,
org.apache.log4j.lf5.util,
org.apache.log4j.lf5.viewer,
org.apache.log4j.lf5.viewer.categoryexplorer,
org.apache.log4j.lf5.viewer.configure,
org.apache.log4j.lf5.viewer.images,
org.apache.log4j.net,
org.apache.log4j.nt,
org.apache.log4j.or,
org.apache.log4j.or.jms,
org.apache.log4j.or.sax,
org.apache.log4j.spi,
org.apache.log4j.varia,
org.apache.log4j.xml
Eclipse-BuddyPolicy: registered
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
- You will need to place a PluginLogAppender class in one or more plugins - see http://www.eclipsezone.com/eclipse/forums/t55300.html - http://www.eclipsezone.com/eclipse/forums/t55300.html. The example I use follows:
/*******************************************************************************
Copyright (c) 2005 John J. Franey
All rights reserved. This program and the accompanying materials
are made available under the terms of the Eclipse Public License v1.0
which accompanies distribution, and is available at
http://www.eclipse.org/legal/epl-v10.html
*
*******************************************************************************/
IR_GIS;
java.text.MessageFormat;
org.apache.log4j.AppenderSkeleton;
org.apache.log4j.Level;
org.apache.log4j.spi.LoggingEvent;
org.eclipse.core.runtime.ILog;
org.eclipse.core.runtime.IStatus;
org.eclipse.core.runtime.Platform;
org.eclipse.core.runtime.Status;
org.osgi.framework.Bundle;
/**
log4j appender to an eclipse plugin's Ilog.
@author John J. Franey
*
*/
AppenderSkeleton
{
symbolicName;
/* (non-Javadoc)
@see org.apache.log4j.AppenderSkeleton#append(org.apache.log4j.spi.LoggingEvent)
*/
void append(LoggingEvent event)
Unknown macro: { event is not severe enough. ; ILog log = getBundleILog(); ; throwable information is available, extract it. Throwable t = ; && layout.ignoresThrowable()) t = event.getThrowableInformation().getThrowable(); // build an Eclipse Status record, map severity and code from Event. Status s = Status(getSeverity(event), getSymbolicName(), getCode(event), layout.format(event), t); log.log(s); }
/**
map LoggingEvent's level to Status severity
@param ev
@
*/
getSeverity(LoggingEvent ev)
Unknown macro: { Level level = ev.getLevel(); (level == Level.FATAL || level == Level.ERROR) IStatus.ERROR; (level == Level.WARN) IStatus.WARNING; (level == Level.INFO) IStatus.INFO; // debug, trace and custom levels IStatus.OK; }
/**
Return the pluginId under which the messages will be logged
@
*/
getSymbolicName()
Unknown macro: { .symbolicName; }
name)
Unknown macro: { .symbolicName = name; }
/**
map LoggingEvent to Status code
@param ev
@
*/
getCode(LoggingEvent ev)
Unknown macro: { 0; }
ILog getBundleILog() {
a plug-in
Bundle b = Platform.getBundle(getSymbolicName());
)
Unknown macro: { //$NON-NLS-1$ .name}
);
.errorHandler.error(m);
;
}
Platform.getLog(b);
}
void close()
Unknown macro: { // nothing to close }
requiresLayout()
Unknown macro: { ; }
}
Then you need to make that PluginLogAppender visible by reflection, using an: Eclipse-RegisterBuddy: org.apache.log4j directive within the plugin manifest e.g.:
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: IR_GIS (TM) Innovative Real-time Geographic Information
Bundle-SymbolicName: IR_GIS;singleton:=
Bundle-Version: 1.2.18
Bundle-Activator: IR_GIS.IRGISPlugin
Bundle-Vendor: Arising Technology Systems Pty Limited
Require-Bundle: org.apache.log4j,
ri.common,
net.refractions.udig.project,
net.refractions.udig.mapgraphic,
net.refractions.udig.printing.model,
net.refractions.udig.printing.ui,
net.refractions.udig.tool.,
net.refractions.udig.tool.info,
net.refractions.udig.ui,
ri.checklogin;bundle-version=;resolution:=optional,
ri.udig.InfotoolOverride;bundle-version=;resolution:=optional
Import-Package: org.eclipse.ui.plugin,
org.slf4j
Eclipse-RegisterBuddy: org.apache.log4j
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Bundle-ActivationPolicy: lazy
Export-Package: IR_GIS;version=
- I have kept the PluginLogAppender in the scope of ONE Plugin and its activator mandraulically configures the log4j properties via this code:
// Obtain the properties file to start the appender
IConfiguration config = ConfigurationFactory.getDefault();
//$NON-NLS-1$
, pathName));
PropertyConfigurator.configure(pathName);
logger = LoggerFactory.getLogger(.getClass());
(Note that ConfigurationFactory is proprietary code, you will need to use some other means to obtain the pathname to the log4k.properties file.)
I haven't spent any time using more than one plugin to contain the PluginLogAppender, nor tried to investigate whether the 1.3.0 udig code base actually contains one or more PluginLogAppender instances or equivalent classes, but my product has been running with one appender setup this way for over a year, perhaps this is something the development team can fix in the current udig code base?
Ralph Holland