Author: ceki Date: Tue Jul 3 20:29:13 2007 New Revision: 830 Added: slf4j/trunk/slf4j-jcl/src/main/java/org/slf4j/impl/StaticMDCBinder.java slf4j/trunk/slf4j-log4j12/src/main/java/org/slf4j/impl/StaticMDCBinder.java slf4j/trunk/slf4j-nop/src/main/java/org/slf4j/impl/StaticMDCBinder.java slf4j/trunk/slf4j-simple/src/main/java/org/slf4j/impl/StaticMDCBinder.java Modified: slf4j/trunk/slf4j-api/src/main/java/org/slf4j/MDC.java slf4j/trunk/slf4j-api/src/test/java/org/slf4j/NoBindingTest.java slf4j/trunk/slf4j-jcl/src/test/java/org/slf4j/InvocationTest.java slf4j/trunk/slf4j-jdk14/src/main/java/org/slf4j/impl/StaticMDCBinder.java slf4j/trunk/slf4j-jdk14/src/test/java/org/slf4j/InvocationTest.java slf4j/trunk/slf4j-nop/src/test/java/org/slf4j/InvocationTest.java slf4j/trunk/slf4j-simple/src/main/java/org/slf4j/impl/StaticLoggerBinder.java slf4j/trunk/slf4j-simple/src/main/java/org/slf4j/impl/StaticMarkerBinder.java slf4j/trunk/slf4j-simple/src/test/java/org/slf4j/InvocationTest.java slf4j/trunk/slf4j-site/src/site/pages/codes.html
Log: continued work on MDC support Modified: slf4j/trunk/slf4j-api/src/main/java/org/slf4j/MDC.java ============================================================================== --- slf4j/trunk/slf4j-api/src/main/java/org/slf4j/MDC.java (original) +++ slf4j/trunk/slf4j-api/src/main/java/org/slf4j/MDC.java Tue Jul 3 20:29:13 2007 @@ -39,6 +39,9 @@ * @author Ceki Gülcü */ public class MDC { + + static final String NULL_MDCA_URL = "http://www.slf4j.org/codes.html#null_MDCA"; + static final String NO_STATIC_MDC_BINDER_URL = "http://www.slf4j.org/codes.html#no_static_mdc_binder"; static MDCAdapter mdcAdapter; private MDC() { @@ -47,9 +50,17 @@ static { try { mdcAdapter = StaticMDCBinder.SINGLETON.getMDCA(); + } catch(NoClassDefFoundError ncde) { + String msg = ncde.getMessage(); + if(msg != null && msg.indexOf("org/slf4j/impl/StaticMDCBinder") != -1) { + Util.reportFailure("Failed to load class \"org.slf4j.impl.StaticMDCBinder\"."); + Util.reportFailure("See "+NO_STATIC_MDC_BINDER_URL+" for further details."); + + } + throw ncde; } catch (Exception e) { // we should never get here - Util.reportFailure("Could not instantiate instance of class [" + Util.reportFailure("Could not bind with an instance of class [" + StaticMDCBinder.SINGLETON.getMDCAdapterClassStr() + "]", e); } } @@ -61,6 +72,9 @@ * method delegates all work to the MDC of the underlying logging system. */ public static void put(String key, String val) { + if(mdcAdapter == null) { + throw new IllegalStateException("MDCAdapter cannot be null. See also "+NULL_MDCA_URL); + } mdcAdapter.put(key, val); } @@ -71,6 +85,9 @@ * @return the string value identified by the <code>key</code> parameter. */ public static String get(String key) { + if(mdcAdapter == null) { + throw new IllegalStateException("MDCAdapter cannot be null. See also "+NULL_MDCA_URL); + } return mdcAdapter.get(key); } @@ -79,13 +96,19 @@ * the underlying system's MDC implementation. */ public static void remove(String key) { + if(mdcAdapter == null) { + throw new IllegalStateException("MDCAdapter cannot be null. See also "+NULL_MDCA_URL); + } mdcAdapter.remove(key); } /** * Clear all entries in the MDC of the underlying implementation. */ - public void clear() { + public static void clear() { + if(mdcAdapter == null) { + throw new IllegalStateException("MDCAdapter cannot be null. See also "+NULL_MDCA_URL); + } mdcAdapter.clear(); } Modified: slf4j/trunk/slf4j-api/src/test/java/org/slf4j/NoBindingTest.java ============================================================================== --- slf4j/trunk/slf4j-api/src/test/java/org/slf4j/NoBindingTest.java (original) +++ slf4j/trunk/slf4j-api/src/test/java/org/slf4j/NoBindingTest.java Tue Jul 3 20:29:13 2007 @@ -4,13 +4,22 @@ public class NoBindingTest extends TestCase { - public void test() { + public void testLogger() { try { - Logger logger = LoggerFactory.getLogger(NoBindingTest.class); - logger.debug("hello"); - fail("slf4j-api does not ship with a binding"); - } catch(NoClassDefFoundError e) { - + Logger logger = LoggerFactory.getLogger(NoBindingTest.class); + logger.debug("hello"); + fail("slf4j-api does not ship with a binding"); + } catch (NoClassDefFoundError e) { + + } + } + + public void testMDC() { + try { + MDC.put("k", "v"); + fail("slf4j-api does not ship with a binding"); + } catch (NoClassDefFoundError e) { + } } } Added: slf4j/trunk/slf4j-jcl/src/main/java/org/slf4j/impl/StaticMDCBinder.java ============================================================================== --- (empty file) +++ slf4j/trunk/slf4j-jcl/src/main/java/org/slf4j/impl/StaticMDCBinder.java Tue Jul 3 20:29:13 2007 @@ -0,0 +1,34 @@ +package org.slf4j.impl; + +import org.slf4j.helpers.NOPMakerAdapter; +import org.slf4j.spi.MDCAdapter; + + +/** + * This implementation is bound to [EMAIL PROTECTED] NOPMakerAdapter}. + * + * @author Ceki Gülcü + */ +public class StaticMDCBinder { + + + /** + * The unique instance of this class. + */ + public static final StaticMDCBinder SINGLETON = new StaticMDCBinder(); + + private StaticMDCBinder() { + } + + /** + * Currently this method always returns an instance of + * [EMAIL PROTECTED] StaticMDCBinder}. + */ + public MDCAdapter getMDCA() { + return new NOPMakerAdapter(); + } + + public String getMDCAdapterClassStr() { + return NOPMakerAdapter.class.getName(); + } +} Modified: slf4j/trunk/slf4j-jcl/src/test/java/org/slf4j/InvocationTest.java ============================================================================== --- slf4j/trunk/slf4j-jcl/src/test/java/org/slf4j/InvocationTest.java (original) +++ slf4j/trunk/slf4j-jcl/src/test/java/org/slf4j/InvocationTest.java Tue Jul 3 20:29:13 2007 @@ -118,4 +118,11 @@ logger.warn(blue, "hello {} and {} ", "world", "universe"); logger.error(blue, "hello {} and {} ", "world", "universe"); } + + public void testMDC() { + MDC.put("k", "v"); + MDC.remove("k"); + assertNull(MDC.get("k")); + MDC.clear(); + } } Modified: slf4j/trunk/slf4j-jdk14/src/main/java/org/slf4j/impl/StaticMDCBinder.java ============================================================================== --- slf4j/trunk/slf4j-jdk14/src/main/java/org/slf4j/impl/StaticMDCBinder.java (original) +++ slf4j/trunk/slf4j-jdk14/src/main/java/org/slf4j/impl/StaticMDCBinder.java Tue Jul 3 20:29:13 2007 @@ -18,7 +18,6 @@ public static final StaticMDCBinder SINGLETON = new StaticMDCBinder(); private StaticMDCBinder() { - throw new UnsupportedOperationException("This code should never make it into the jar"); } /** Modified: slf4j/trunk/slf4j-jdk14/src/test/java/org/slf4j/InvocationTest.java ============================================================================== --- slf4j/trunk/slf4j-jdk14/src/test/java/org/slf4j/InvocationTest.java (original) +++ slf4j/trunk/slf4j-jdk14/src/test/java/org/slf4j/InvocationTest.java Tue Jul 3 20:29:13 2007 @@ -118,4 +118,11 @@ logger.warn(blue, "hello {} and {} ", "world", "universe"); logger.error(blue, "hello {} and {} ", "world", "universe"); } + + public void testMDC() { + MDC.put("k", "v"); + MDC.remove("k"); + assertNull(MDC.get("k")); + MDC.clear(); + } } Added: slf4j/trunk/slf4j-log4j12/src/main/java/org/slf4j/impl/StaticMDCBinder.java ============================================================================== --- (empty file) +++ slf4j/trunk/slf4j-log4j12/src/main/java/org/slf4j/impl/StaticMDCBinder.java Tue Jul 3 20:29:13 2007 @@ -0,0 +1,33 @@ +package org.slf4j.impl; + +import org.slf4j.spi.MDCAdapter; + + +/** + * This implementation is bound to [EMAIL PROTECTED] Log4jMDCAdapter}. + * + * @author Ceki Gülcü + */ +public class StaticMDCBinder { + + + /** + * The unique instance of this class. + */ + public static final StaticMDCBinder SINGLETON = new StaticMDCBinder(); + + private StaticMDCBinder() { + } + + /** + * Currently this method always returns an instance of + * [EMAIL PROTECTED] StaticMDCBinder}. + */ + public MDCAdapter getMDCA() { + return new Log4jMDCAdapter(); + } + + public String getMDCAdapterClassStr() { + return Log4jMDCAdapter.class.getName(); + } +} Added: slf4j/trunk/slf4j-nop/src/main/java/org/slf4j/impl/StaticMDCBinder.java ============================================================================== --- (empty file) +++ slf4j/trunk/slf4j-nop/src/main/java/org/slf4j/impl/StaticMDCBinder.java Tue Jul 3 20:29:13 2007 @@ -0,0 +1,34 @@ +package org.slf4j.impl; + +import org.slf4j.helpers.NOPMakerAdapter; +import org.slf4j.spi.MDCAdapter; + + +/** + * This implementation is bound to [EMAIL PROTECTED] NOPMakerAdapter}. + * + * @author Ceki Gülcü + */ +public class StaticMDCBinder { + + + /** + * The unique instance of this class. + */ + public static final StaticMDCBinder SINGLETON = new StaticMDCBinder(); + + private StaticMDCBinder() { + } + + /** + * Currently this method always returns an instance of + * [EMAIL PROTECTED] StaticMDCBinder}. + */ + public MDCAdapter getMDCA() { + return new NOPMakerAdapter(); + } + + public String getMDCAdapterClassStr() { + return NOPMakerAdapter.class.getName(); + } +} Modified: slf4j/trunk/slf4j-nop/src/test/java/org/slf4j/InvocationTest.java ============================================================================== --- slf4j/trunk/slf4j-nop/src/test/java/org/slf4j/InvocationTest.java (original) +++ slf4j/trunk/slf4j-nop/src/test/java/org/slf4j/InvocationTest.java Tue Jul 3 20:29:13 2007 @@ -118,4 +118,11 @@ logger.warn(blue, "hello {} and {} ", "world", "universe"); logger.error(blue, "hello {} and {} ", "world", "universe"); } + + public void testMDC() { + MDC.put("k", "v"); + MDC.remove("k"); + assertNull(MDC.get("k")); + MDC.clear(); + } } Modified: slf4j/trunk/slf4j-simple/src/main/java/org/slf4j/impl/StaticLoggerBinder.java ============================================================================== --- slf4j/trunk/slf4j-simple/src/main/java/org/slf4j/impl/StaticLoggerBinder.java (original) +++ slf4j/trunk/slf4j-simple/src/main/java/org/slf4j/impl/StaticLoggerBinder.java Tue Jul 3 20:29:13 2007 @@ -1,34 +1,25 @@ -/* - * Copyright (c) 2004-2005 SLF4J.ORG - * Copyright (c) 2004-2005 QOS.ch - * +/* + * Copyright (c) 2004-2007 QOS.ch * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons - * to whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT - * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR - * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY - * SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER - * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF - * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * Except as contained in this notice, the name of a copyright holder - * shall not be used in advertising or otherwise to promote the sale, use - * or other dealings in this Software without prior written authorization - * of the copyright holder. - * + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ package org.slf4j.impl; Added: slf4j/trunk/slf4j-simple/src/main/java/org/slf4j/impl/StaticMDCBinder.java ============================================================================== --- (empty file) +++ slf4j/trunk/slf4j-simple/src/main/java/org/slf4j/impl/StaticMDCBinder.java Tue Jul 3 20:29:13 2007 @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2004-2007 QOS.ch + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package org.slf4j.impl; + +import org.slf4j.helpers.NOPMakerAdapter; +import org.slf4j.spi.MDCAdapter; + + +/** + * This implementation is bound to [EMAIL PROTECTED] NOPMakerAdapter}. + * + * @author Ceki Gülcü + */ +public class StaticMDCBinder { + + + /** + * The unique instance of this class. + */ + public static final StaticMDCBinder SINGLETON = new StaticMDCBinder(); + + private StaticMDCBinder() { + } + + /** + * Currently this method always returns an instance of + * [EMAIL PROTECTED] StaticMDCBinder}. + */ + public MDCAdapter getMDCA() { + return new NOPMakerAdapter(); + } + + public String getMDCAdapterClassStr() { + return NOPMakerAdapter.class.getName(); + } +} Modified: slf4j/trunk/slf4j-simple/src/main/java/org/slf4j/impl/StaticMarkerBinder.java ============================================================================== --- slf4j/trunk/slf4j-simple/src/main/java/org/slf4j/impl/StaticMarkerBinder.java (original) +++ slf4j/trunk/slf4j-simple/src/main/java/org/slf4j/impl/StaticMarkerBinder.java Tue Jul 3 20:29:13 2007 @@ -1,36 +1,28 @@ -/* - * Copyright (c) 2004-2005 SLF4J.ORG - * Copyright (c) 2004-2005 QOS.ch - * +/* + * Copyright (c) 2004-2007 QOS.ch * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons - * to whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT - * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR - * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY - * SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER - * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF - * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * Except as contained in this notice, the name of a copyright holder - * shall not be used in advertising or otherwise to promote the sale, use - * or other dealings in this Software without prior written authorization - * of the copyright holder. - * + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + package org.slf4j.impl; import org.slf4j.IMarkerFactory; Modified: slf4j/trunk/slf4j-simple/src/test/java/org/slf4j/InvocationTest.java ============================================================================== --- slf4j/trunk/slf4j-simple/src/test/java/org/slf4j/InvocationTest.java (original) +++ slf4j/trunk/slf4j-simple/src/test/java/org/slf4j/InvocationTest.java Tue Jul 3 20:29:13 2007 @@ -1,6 +1,5 @@ /* - * Copyright (c) 2004-2005 SLF4J.ORG - * Copyright (c) 2004-2005 QOS.CH + * Copyright (c) 2004-2007 QOS.CH * * All rights reserved. * @@ -118,4 +117,11 @@ logger.warn(blue, "hello {} and {} ", "world", "universe"); logger.error(blue, "hello {} and {} ", "world", "universe"); } + + public void testMDC() { + MDC.put("k", "v"); + MDC.remove("k"); + assertNull(MDC.get("k")); + MDC.clear(); + } } Modified: slf4j/trunk/slf4j-site/src/site/pages/codes.html ============================================================================== --- slf4j/trunk/slf4j-site/src/site/pages/codes.html (original) +++ slf4j/trunk/slf4j-site/src/site/pages/codes.html Tue Jul 3 20:29:13 2007 @@ -20,9 +20,8 @@ <div id="content"> <center> - <h2>SLF4J warning or error messages and their meanings</h2> - <h3>Ceki Gülcü <br/> - created May 2006, last updated on May 2006</h3> + <h2>SLF4J warning or error messages and their meanings</h2> + </center> @@ -47,7 +46,7 @@ <p>This is a relatively common occurrence with recent versions of Tomcat, especially if you place <em>jcl104-over-slf4j.jar</em> in <em>WEB-INF/lib</em> directory of your web-application instead of - <em>$TOMCAT_HOME/common/lib</em> where $TOMCAT_HOME stands for the + <em>$TOMCAT_HOME/common/lib</em>, where $TOMCAT_HOME stands for the directory where Tomcat is installed. In order to fully benefit from the stability offered by <em>jcl104-over-slf4j.jar</em>, we recommend that you place <em>jcl104-over-slf4j.jar</em> in @@ -59,36 +58,62 @@ href="http://bugzilla.slf4j.org/show_bug.cgi?id=22">bug #22</a>.</p> - <a name="null_LF"> + + + <a name="StaticLoggerBinder"> + </a> + + <h3>Failed to load class + <code>org.slf4j.impl.StaticLoggerBinder</code></h3> + + <p>This error is reported when the + <code>org.slf4j.impl.StaticLoggerBinder</code> class could not be + loaded into memory. This happens when no appropriate SLF4J + binding could be found on the class path. Placing one (and only + one) of <em>slf4j-nop.jar</em>, <em>slf4j-simple.jar</em>, + <em>slf4j-log4j12.jar</em>, <em>slf4j-jdk14.jar</em> or + <em>logback-classic.jar</em> on the class path should solve the + problem. + </p> + + <a name="null_LF"> </a> <h3>Logging factory implementation cannot be null</h3> <p>This error is reported when the <code>LoggerFactory</code> - class could not find an appropriate binding, indicating that no - appropriate SLF4J binding could be found. Placing one of - <em>slf4j-nop.jar</em>, <em>slf4j-simple.jar</em>, + class could not find an appropriate binding. Placing one (and only + one) of <em>slf4j-nop.jar</em>, <em>slf4j-simple.jar</em>, <em>slf4j-log4j12.jar</em>, <em>slf4j-jdk14.jar</em> or <em>logback-classic.jar</em> on the class path should prove to be an effective remedy. </p> - <a name="StaticLoggerBinder"> + <a name="no_static_mdc_binder"> </a> - <h3>Failed to load class - <code>org.slf4j.impl.StaticLoggerBinder</code></h3> + <h3>Failed to load class "org.slf4j.impl.StaticMDCBinder".</h3> - <p>This error is reported when the - <code>org.slf4j.impl.StaticLoggerBinder</code> class could not be - loaded into memory. This happens when no appropriate SLF4J - binding could be found on the class path. Placing one of + <p>This error indicates that appropriate SLF4J binding could be + found on the class path. Placing one (and only one) of <em>slf4j-nop.jar</em>, <em>slf4j-simple.jar</em>, <em>slf4j-log4j12.jar</em>, <em>slf4j-jdk14.jar</em> or <em>logback-classic.jar</em> on the class path should solve the problem. </p> + + <a name="null_MDCA"> + </a> + <h3>MDCAdapter cannot be null</h3> + + <p>This error is reported when <code>org.slf4j.MDC</code> class + has not been initialized correctly. Same cause and remedy as the + previously listed item. + </p> + + + </div> </body> _______________________________________________ dev mailing list dev@slf4j.org http://www.slf4j.org/mailman/listinfo/dev