Return-Path: X-Original-To: apmail-logging-log4j-dev-archive@www.apache.org Delivered-To: apmail-logging-log4j-dev-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 742FC185B4 for ; Wed, 27 Jan 2016 13:08:02 +0000 (UTC) Received: (qmail 59993 invoked by uid 500); 27 Jan 2016 13:08:02 -0000 Delivered-To: apmail-logging-log4j-dev-archive@logging.apache.org Received: (qmail 59944 invoked by uid 500); 27 Jan 2016 13:08:02 -0000 Mailing-List: contact log4j-dev-help@logging.apache.org; run by ezmlm Precedence: bulk List-Unsubscribe: List-Help: List-Post: List-Id: "Log4J Developers List" Reply-To: "Log4J Developers List" Delivered-To: mailing list log4j-dev@logging.apache.org Received: (qmail 59934 invoked by uid 99); 27 Jan 2016 13:08:02 -0000 Received: from Unknown (HELO spamd1-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 27 Jan 2016 13:08:02 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd1-us-west.apache.org (ASF Mail Server at spamd1-us-west.apache.org) with ESMTP id B5F44C29C3 for ; Wed, 27 Jan 2016 13:08:01 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd1-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: 2.902 X-Spam-Level: ** X-Spam-Status: No, score=2.902 tagged_above=-999 required=6.31 tests=[DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HTML_MESSAGE=3, MIME_QP_LONG_LINE=0.001, URIBL_BLOCKED=0.001] autolearn=disabled Authentication-Results: spamd1-us-west.apache.org (amavisd-new); dkim=pass (2048-bit key) header.d=gmail.com Received: from mx1-eu-west.apache.org ([10.40.0.8]) by localhost (spamd1-us-west.apache.org [10.40.0.7]) (amavisd-new, port 10024) with ESMTP id 39jOAarKJlaM for ; Wed, 27 Jan 2016 13:07:46 +0000 (UTC) Received: from mail-pf0-f172.google.com (mail-pf0-f172.google.com [209.85.192.172]) by mx1-eu-west.apache.org (ASF Mail Server at mx1-eu-west.apache.org) with ESMTPS id 6C52A31AA9 for ; Wed, 27 Jan 2016 13:07:45 +0000 (UTC) Received: by mail-pf0-f172.google.com with SMTP id o185so75995pfb.1 for ; Wed, 27 Jan 2016 05:07:45 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:content-type:content-transfer-encoding:mime-version:subject :message-id:date:references:in-reply-to:to; bh=PqFq1PEbwIvuR2Uk+PReivg5B2ISRx6R/YTnfgpThIk=; b=zI5ms8NSwjBy7hkx+YKk56ObNsNPy1G7MK4mdnILyI0F5vKLbfT9orEo8PYuAgsm6I xMTgwTEusFAt9fuxy5PsfF0reQ6jsaCnxi2qEIPNFvUc68ATCU9PEFmWrVbizigKavb3 sAXiS+aVYPQPM+w4YmqSdbhfgbDnUxLP3rP8F6/ErxV9uv2SCLeFoLFJS/anXFx0seIV TCD5qJfcAvb4SvokCv7WLfjbW0coukuCMylNLSP1iSkPAEKIoY+Xe4iXLxHRfP9YFURl 65RGXd5lH9UAGkc2hokecRBpSsVfngn2HiULmERoMq/BOPxegtMc2Xj+D9/we7yJcT60 EOAg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:content-type:content-transfer-encoding :mime-version:subject:message-id:date:references:in-reply-to:to; bh=PqFq1PEbwIvuR2Uk+PReivg5B2ISRx6R/YTnfgpThIk=; b=luvkoJS29yWSYv+2o1exetj2ygEs41pguGaPFp/O9bT8XRANLZkVbS35geVur/SPoS O2HDLbYQGCeAmaUe9BXHFR3241crD1/2W/HYcOwDVR7Oxk41agW22ORvVeKPG19M6ZPq JQtc2nKPpxMJuxWKA0Lc25Gs71oSEn+YgSxxqM3OVrCOTCQ4h8Dn0F7RKCmRKSHBRzgr pq294ELlG+30flgOiSMlJ/f0HKJg4caSY5BtriQonFz4nf8X57fl3b6gTnkIZ6FTj0bS qkiflO7a+h9Mg6IVnr8U5a6XAtsMtvzsF9J3eD+SIPAASg0CawxKTnPVM/wO3bc8PW3h AU1Q== X-Gm-Message-State: AG10YOQs3t103xdXjcapiVApo1l6CwVCY0hDTYeaLf8UWlHfWr9Ad5GZkDengQNowLldyQ== X-Received: by 10.98.10.198 with SMTP id 67mr42249093pfk.75.1453900064007; Wed, 27 Jan 2016 05:07:44 -0800 (PST) Received: from [10.34.207.157] (pw126255075062.9.panda-world.ne.jp. [126.255.75.62]) by smtp.gmail.com with ESMTPSA id i76sm9091414pfj.68.2016.01.27.05.07.42 for (version=TLS1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 27 Jan 2016 05:07:42 -0800 (PST) From: Remko Popma Content-Type: multipart/alternative; boundary=Apple-Mail-6A83D31B-1A6B-4CFB-AB5A-2D7645CF925C Content-Transfer-Encoding: 7bit Mime-Version: 1.0 (1.0) Subject: Re: logging-log4j2 git commit: LOG4J2-124 - Add shutdown methods to LogManager Message-Id: <0C7EB709-2C8F-4B1C-99E8-C9A84FD971D6@gmail.com> Date: Wed, 27 Jan 2016 22:07:38 +0900 References: <34D06835-A7DB-474B-82D8-F4114423F1A4@dslextreme.com> <8A96F0A4-EAB3-478A-9F63-A13793015BDC@dslextreme.com> <39156D84-B0B6-418B-9AD5-8974DDB80D6B@dslextreme.com> <03355D59-AA1A-47AD-92C0-69EA1E300354@dslextreme.com> In-Reply-To: To: Log4J Developers List X-Mailer: iPhone Mail (13D15) --Apple-Mail-6A83D31B-1A6B-4CFB-AB5A-2D7645CF925C Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Perhaps you also want to add this to the LogManager.shutdown() methods, sinc= e I imagine that's what people will actually use/look at.=20 Sent from my iPhone > On 2016/01/27, at 18:20, Mikael St=C3=A5ldal w= rote: >=20 > OK, done. >=20 >> On Wed, Jan 27, 2016 at 6:17 AM, Remko Popma wrot= e: >> Mikael, feel free to update the javadoc when you have time.=20 >>=20 >>=20 >>> On Wednesday, 27 January 2016, Remko Popma wrote= : >>> Since the async loggers and appenders will wait until their queue has be= en cleared by the background thread, it is a blocking call.=20 >>>=20 >>> We should probably add a sentence to the java doc to clarify this. =20 >>>=20 >>> Sent from my iPhone >>>=20 >>>> On 2016/01/26, at 18:15, Mikael St=C3=A5ldal wrote: >>>>=20 >>>> I think that we should be clear, in Javadoc, about whether this new met= hod is synchronous/blocking or not. >>>>=20 >>>> (I could say the same about quite a few existing methods as well, but l= et's at least start to be clear about new methods from now.) >>>>=20 >>>>> On Tue, Jan 26, 2016 at 1:31 AM, Matt Sicker wrote:= >>>>> I like it! >>>>>=20 >>>>>> On 25 January 2016 at 18:23, Ralph Goers = wrote: >>>>>> Then the method name would be terminate? I could live with that. I a= lso like the fact that when something goes wrong with it then it would be in= terminable ;-) >>>>>>=20 >>>>>> Ralph >>>>>>=20 >>>>>>> On Jan 25, 2016, at 5:18 PM, Matt Sicker wrote: >>>>>>>=20 >>>>>>> How about Terminable? It's even a real word to boot. >>>>>>>=20 >>>>>>> On 25 January 2016 at 18:15, Ralph Goers wrote: >>>>>>>> Yes, well - Serializable actually sounds like it should be a real w= ord. Shutdownable doesn=E2=80=99t - in fact, my mail editor just split it in= to two words to =E2=80=9Chelp=E2=80=9D me. I take a different view. A class t= hat declares it implements an interface isn=E2=80=99t =E2=80=9Ccapable=E2=80= =9D of anything - it just implements the interface. The interface name is wh= at tells you that the implementing class is able to do something, which is w= hy you have Comparable instead of just Compare, Cloneable instead of just Cl= one, or Closeable instead of just Close. Would you want Stop instead of Sto= ppable? I view =E2=80=9Cable=E2=80=9D as just a shorthand way of saying =E2= =80=9CCapable=E2=80=9D, but unfortunately that just doesn=E2=80=99t sound ri= ght with Shutdown (at least to me). >>>>>>>>=20 >>>>>>>> Here are some =E2=80=9Cable=E2=80=9D alternatives - presumably each= would have a corresponding method name instead of shutdown: >>>>>>>> Terminateable. >>>>>>>> Completeable. >>>>>>>> Concludeable. >>>>>>>> Haltable. >>>>>>>> Dismissable. >>>>>>>> Expireable. >>>>>>>>=20 >>>>>>>> I suppose we could also use Stoppable but that seems odd since stop= is part of Lifecycle. >>>>>>>>=20 >>>>>>>> Got a preference? >>>>>>>>=20 >>>>>>>> Ralph >>>>>>>>=20 >>>>>>>>=20 >>>>>>>>=20 >>>>>>>>> On Jan 25, 2016, at 4:35 PM, Gary Gregory = wrote: >>>>>>>>>=20 >>>>>>>>> I see some interfaces with "*Capable*" in the name here and there i= n the FOSS world (but not in the JRE) so I am a little more comfortable with= it.=20 >>>>>>>>>=20 >>>>>>>>> I still see plain old "Shutdown" as simpler.=20 >>>>>>>>>=20 >>>>>>>>> I think I've boiled down my feel for this name to the fact that th= e Capable postfix is redundant since a class implementing any interface is "= capable" of that functionality. IOW we have Serializable vs. SerializationCa= bable, which means the same thing. >>>>>>>>>=20 >>>>>>>>> Gary >>>>>>>>>=20 >>>>>>>>>> On Mon, Jan 25, 2016 at 7:27 AM, Ralph Goers wrote: >>>>>>>>>> What does it feel weird to you? To be honest, I originally named= the interface =E2=80=98Shutdown=E2=80=9D and then changed it since it reall= y is about implementing a behavior and =E2=80=9CShutdown=E2=80=9D alone does= n=E2=80=99t really describe that. >>>>>>>>>>=20 >>>>>>>>>> Ralph >>>>>>>>>>=20 >>>>>>>>>>> On Jan 24, 2016, at 11:09 PM, Gary Gregory wrote: >>>>>>>>>>>=20 >>>>>>>>>>>> On Sun, Jan 24, 2016 at 10:07 PM, Gary Gregory wrote: >>>>>>>>>>>>> On Sun, Jan 24, 2016 at 1:54 PM, Ralph Goers wrote: >>>>>>>>>>>>> Yes, Shutdownable is too weird.=20 >>>>>>>>>>>>=20 >>>>>>>>>>>> How about calling it simply "Shutdown" then? FooCapable feels w= eird to me. >>>>>>>>>>>>=20 >>>>>>>>>>>> Can anyone think of other (one-method or not) optional feature-= like interfaces in the JRE or other code base? >>>>>>>>>>>=20 >>>>>>>>>>> hm... ShutdownService? >>>>>>>>>>>=20 >>>>>>>>>>> Gary >>>>>>>>>>> =20 >>>>>>>>>>>>=20 >>>>>>>>>>>> Gary >>>>>>>>>>>>=20 >>>>>>>>>>>>> Closeable would imply there is a close method, not a shutdown m= ethod. I have my doubts about the try-with-resources use case here. Virtua= lly all usages are probably going to be to disable automatic shutdown and th= en the user placing the shutdown call somewhere they can control, which prob= ably will have nothing to do with initialization of logging.=20 >>>>>>>>>>>>>=20 >>>>>>>>>>>>> Ralph >>>>>>>>>>>>>=20 >>>>>>>>>>>>>> On Jan 24, 2016, at 2:43 PM, Gary Gregory wrote: >>>>>>>>>>>>>>=20 >>>>>>>>>>>>>> Resending, got a error from my phone... >>>>>>>>>>>>>>=20 >>>>>>>>>>>>>> ---------- Forwarded message ---------- >>>>>>>>>>>>>> From: "Gary Gregory" >>>>>>>>>>>>>> Date: Jan 24, 2016 1:41 PM >>>>>>>>>>>>>> Subject: Re: logging-log4j2 git commit: LOG4J2-124 - Add shut= down methods to LogManager >>>>>>>>>>>>>> To: >>>>>>>>>>>>>> Cc:=20 >>>>>>>>>>>>>>=20 >>>>>>>>>>>>>> Hi all, >>>>>>>>>>>>>>=20 >>>>>>>>>>>>>> Any reason not use the usual -able postfix instead of Shutdow= nCapable: Shutdownable sounds too weird? What about reusing plain old Closea= ble? That means you could use the context in a try-with-resources block, a b= onus. >>>>>>>>>>>>>>=20 >>>>>>>>>>>>>> Gary=20 >>>>>>>>>>>>>>=20 >>>>>>>>>>>>>>> On Jan 24, 2016 10:18 AM, wrote: >>>>>>>>>>>>>>> Repository: logging-log4j2 >>>>>>>>>>>>>>> Updated Branches: >>>>>>>>>>>>>>> refs/heads/master 7d3aac4b9 -> 2df3f0e72 >>>>>>>>>>>>>>>=20 >>>>>>>>>>>>>>>=20 >>>>>>>>>>>>>>> LOG4J2-124 - Add shutdown methods to LogManager >>>>>>>>>>>>>>>=20 >>>>>>>>>>>>>>>=20 >>>>>>>>>>>>>>> Project: http://git-wip-us.apache.org/repos/asf/logging-log4= j2/repo >>>>>>>>>>>>>>> Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j= 2/commit/2df3f0e7 >>>>>>>>>>>>>>> Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/= tree/2df3f0e7 >>>>>>>>>>>>>>> Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/= diff/2df3f0e7 >>>>>>>>>>>>>>>=20 >>>>>>>>>>>>>>> Branch: refs/heads/master >>>>>>>>>>>>>>> Commit: 2df3f0e7262c90e3fe1700f053eebf18491650d9 >>>>>>>>>>>>>>> Parents: 7d3aac4 >>>>>>>>>>>>>>> Author: Ralph Goers >>>>>>>>>>>>>>> Authored: Sun Jan 24 11:18:41 2016 -0700 >>>>>>>>>>>>>>> Committer: Ralph Goers >>>>>>>>>>>>>>> Committed: Sun Jan 24 11:18:41 2016 -0700 >>>>>>>>>>>>>>>=20 >>>>>>>>>>>>>>> ------------------------------------------------------------= ---------- >>>>>>>>>>>>>>> .../org/apache/logging/log4j/LogManager.java | 62 ++++++= ++++++++++++++ >>>>>>>>>>>>>>> .../logging/log4j/spi/ShutdownCapable.java | 17 ++++++= >>>>>>>>>>>>>>> .../apache/logging/log4j/LogManagerTest.java | 7 +++ >>>>>>>>>>>>>>> .../logging/log4j/core/LoggerContext.java | 8 ++- >>>>>>>>>>>>>>> 4 files changed, 93 insertions(+), 1 deletion(-) >>>>>>>>>>>>>>> ------------------------------------------------------------= ---------- >>>>>>>>>>>>>>>=20 >>>>>>>>>>>>>>>=20 >>>>>>>>>>>>>>> http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/2= df3f0e7/log4j-api/src/main/java/org/apache/logging/log4j/LogManager.java >>>>>>>>>>>>>>> ------------------------------------------------------------= ---------- >>>>>>>>>>>>>>> diff --git a/log4j-api/src/main/java/org/apache/logging/log4= j/LogManager.java b/log4j-api/src/main/java/org/apache/logging/log4j/LogMana= ger.java >>>>>>>>>>>>>>> index f10e5a8..64c6ee5 100644 >>>>>>>>>>>>>>> --- a/log4j-api/src/main/java/org/apache/logging/log4j/LogMa= nager.java >>>>>>>>>>>>>>> +++ b/log4j-api/src/main/java/org/apache/logging/log4j/LogMa= nager.java >>>>>>>>>>>>>>> @@ -27,6 +27,7 @@ import org.apache.logging.log4j.simple.Sim= pleLoggerContextFactory; >>>>>>>>>>>>>>> import org.apache.logging.log4j.spi.LoggerContext; >>>>>>>>>>>>>>> import org.apache.logging.log4j.spi.LoggerContextFactory; >>>>>>>>>>>>>>> import org.apache.logging.log4j.spi.Provider; >>>>>>>>>>>>>>> +import org.apache.logging.log4j.spi.ShutdownCapable; >>>>>>>>>>>>>>> import org.apache.logging.log4j.status.StatusLogger; >>>>>>>>>>>>>>> import org.apache.logging.log4j.util.LoaderUtil; >>>>>>>>>>>>>>> import org.apache.logging.log4j.util.PropertiesUtil; >>>>>>>>>>>>>>> @@ -285,6 +286,67 @@ public class LogManager { >>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>=20 >>>>>>>>>>>>>>> /** >>>>>>>>>>>>>>> + * Shutdown using the default LoggerContext. >>>>>>>>>>>>>>> + * @since 2.6 >>>>>>>>>>>>>>> + */ >>>>>>>>>>>>>>> + public static void shutdown() { >>>>>>>>>>>>>>> + shutdown(getContext()); >>>>>>>>>>>>>>> + } >>>>>>>>>>>>>>> + >>>>>>>>>>>>>>> + /** >>>>>>>>>>>>>>> + * Shutdown the logging system if the logging system su= pports it. >>>>>>>>>>>>>>> + * @param currentContext if true the LoggerContext for t= he caller of this method will be used. >>>>>>>>>>>>>>> + * @since 2.6 >>>>>>>>>>>>>>> + */ >>>>>>>>>>>>>>> + public static void shutdown(boolean currentContext) { >>>>>>>>>>>>>>> + shutdown(getContext(currentContext)); >>>>>>>>>>>>>>> + } >>>>>>>>>>>>>>> + >>>>>>>>>>>>>>> + /** >>>>>>>>>>>>>>> + * Shutdown the logging system if the logging system su= pports it. >>>>>>>>>>>>>>> + * @param loader The ClassLoader for the context. If nu= ll the context will attempt to determine the appropriate >>>>>>>>>>>>>>> + * ClassLoader. >>>>>>>>>>>>>>> + * @param currentContext if false the LoggerContext app= ropriate for the caller of this method will be used. >>>>>>>>>>>>>>> + * @since 2.6 >>>>>>>>>>>>>>> + */ >>>>>>>>>>>>>>> + public static void shutdown(final ClassLoader loader, f= inal boolean currentContext) { >>>>>>>>>>>>>>> + shutdown(getContext(loader, currentContext)); >>>>>>>>>>>>>>> + } >>>>>>>>>>>>>>> + >>>>>>>>>>>>>>> + /** >>>>>>>>>>>>>>> + * Shutdown the logging system if the logging system su= pports it. >>>>>>>>>>>>>>> + * @param context the LoggerContext. >>>>>>>>>>>>>>> + * @since 2.6 >>>>>>>>>>>>>>> + */ >>>>>>>>>>>>>>> + public static void shutdown(LoggerContext context) { >>>>>>>>>>>>>>> + if (context !=3D null && context instanceof Shutdow= nCapable) { >>>>>>>>>>>>>>> + ((ShutdownCapable) context).shutdown(); >>>>>>>>>>>>>>> + } >>>>>>>>>>>>>>> + } >>>>>>>>>>>>>>> + >>>>>>>>>>>>>>> + /** >>>>>>>>>>>>>>> + * Shutdown the logging system if the logging system su= pports it. >>>>>>>>>>>>>>> + * @param fqcn The fully qualified class name of the Cl= ass that this method is a member of. >>>>>>>>>>>>>>> + * @param currentContext if false the LoggerContext app= ropriate for the caller of this method will be used. >>>>>>>>>>>>>>> + * @since 2.6 >>>>>>>>>>>>>>> + */ >>>>>>>>>>>>>>> + protected static void shutdown(final String fqcn, final= boolean currentContext) { >>>>>>>>>>>>>>> + shutdown(getContext(fqcn, currentContext)); >>>>>>>>>>>>>>> + } >>>>>>>>>>>>>>> + >>>>>>>>>>>>>>> + /** >>>>>>>>>>>>>>> + * Shutdown the logging system if the logging system su= pports it. >>>>>>>>>>>>>>> + * @param fqcn The fully qualified class name of the Cl= ass that this method is a member of. >>>>>>>>>>>>>>> + * @param loader The ClassLoader for the context. If nu= ll the context will attempt to determine the appropriate >>>>>>>>>>>>>>> + * ClassLoader. >>>>>>>>>>>>>>> + * @param currentContext if false the LoggerContext app= ropriate for the caller of this method will be used. >>>>>>>>>>>>>>> + * @since 2.6 >>>>>>>>>>>>>>> + */ >>>>>>>>>>>>>>> + protected static void shutdown(final String fqcn, final= ClassLoader loader, final boolean currentContext) { >>>>>>>>>>>>>>> + shutdown(getContext(fqcn, loader, currentContext));= >>>>>>>>>>>>>>> + } >>>>>>>>>>>>>>> + >>>>>>>>>>>>>>> + /** >>>>>>>>>>>>>>> * Returns the current LoggerContextFactory. >>>>>>>>>>>>>>> * >>>>>>>>>>>>>>> * @return The LoggerContextFactory. >>>>>>>>>>>>>>>=20 >>>>>>>>>>>>>>> http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/2= df3f0e7/log4j-api/src/main/java/org/apache/logging/log4j/spi/ShutdownCapable= .java >>>>>>>>>>>>>>> ------------------------------------------------------------= ---------- >>>>>>>>>>>>>>> diff --git a/log4j-api/src/main/java/org/apache/logging/log4= j/spi/ShutdownCapable.java b/log4j-api/src/main/java/org/apache/logging/log4= j/spi/ShutdownCapable.java >>>>>>>>>>>>>>> new file mode 100644 >>>>>>>>>>>>>>> index 0000000..a46ef60 >>>>>>>>>>>>>>> --- /dev/null >>>>>>>>>>>>>>> +++ b/log4j-api/src/main/java/org/apache/logging/log4j/spi/S= hutdownCapable.java >>>>>>>>>>>>>>> @@ -0,0 +1,17 @@ >>>>>>>>>>>>>>> +/* >>>>>>>>>>>>>>> + * Copyright (c) 2016 Nextiva, Inc. to Present. >>>>>>>>>>>>>>> + * All rights reserved. >>>>>>>>>>>>>>> + */ >>>>>>>>>>>>>>> +package org.apache.logging.log4j.spi; >>>>>>>>>>>>>>> + >>>>>>>>>>>>>>> +/** >>>>>>>>>>>>>>> + * Interface to be implemented by LoggerContext's that prov= ide a shutdown method. >>>>>>>>>>>>>>> + * @since 2.6 >>>>>>>>>>>>>>> + */ >>>>>>>>>>>>>>> +public interface ShutdownCapable { >>>>>>>>>>>>>>> + >>>>>>>>>>>>>>> + /** >>>>>>>>>>>>>>> + * Requests that the logging implementation shut down. >>>>>>>>>>>>>>> + */ >>>>>>>>>>>>>>> + void shutdown(); >>>>>>>>>>>>>>> +} >>>>>>>>>>>>>>>=20 >>>>>>>>>>>>>>> http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/2= df3f0e7/log4j-api/src/test/java/org/apache/logging/log4j/LogManagerTest.java= >>>>>>>>>>>>>>> ------------------------------------------------------------= ---------- >>>>>>>>>>>>>>> diff --git a/log4j-api/src/test/java/org/apache/logging/log4= j/LogManagerTest.java b/log4j-api/src/test/java/org/apache/logging/log4j/Log= ManagerTest.java >>>>>>>>>>>>>>> index 48f0eea..596a9f2 100644 >>>>>>>>>>>>>>> --- a/log4j-api/src/test/java/org/apache/logging/log4j/LogMa= nagerTest.java >>>>>>>>>>>>>>> +++ b/log4j-api/src/test/java/org/apache/logging/log4j/LogMa= nagerTest.java >>>>>>>>>>>>>>> @@ -17,6 +17,7 @@ >>>>>>>>>>>>>>> package org.apache.logging.log4j; >>>>>>>>>>>>>>>=20 >>>>>>>>>>>>>>> import org.apache.logging.log4j.message.ParameterizedMessag= eFactory; >>>>>>>>>>>>>>> +import org.apache.logging.log4j.spi.LoggerContext; >>>>>>>>>>>>>>> import org.junit.Test; >>>>>>>>>>>>>>>=20 >>>>>>>>>>>>>>> import static org.junit.Assert.*; >>>>>>>>>>>>>>> @@ -53,4 +54,10 @@ public class LogManagerTest { >>>>>>>>>>>>>>> assertNotNull("No Logger returned", logger); >>>>>>>>>>>>>>> assertTrue("Incorrect Logger name: " + logger.getNa= me(),LogManagerTest.class.getName().equals(logger.getName())); >>>>>>>>>>>>>>> } >>>>>>>>>>>>>>> + >>>>>>>>>>>>>>> + @Test >>>>>>>>>>>>>>> + public void testShutdown() { >>>>>>>>>>>>>>> + LoggerContext loggerContext =3D LogManager.getConte= xt(false); >>>>>>>>>>>>>>> + LogManager.shutdown(loggerContext); >>>>>>>>>>>>>>> + } >>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>=20 >>>>>>>>>>>>>>> http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/2= df3f0e7/log4j-core/src/main/java/org/apache/logging/log4j/core/LoggerContext= .java >>>>>>>>>>>>>>> ------------------------------------------------------------= ---------- >>>>>>>>>>>>>>> diff --git a/log4j-core/src/main/java/org/apache/logging/log= 4j/core/LoggerContext.java b/log4j-core/src/main/java/org/apache/logging/log= 4j/core/LoggerContext.java >>>>>>>>>>>>>>> index 42efbb5..fcdfc16 100644 >>>>>>>>>>>>>>> --- a/log4j-core/src/main/java/org/apache/logging/log4j/core= /LoggerContext.java >>>>>>>>>>>>>>> +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core= /LoggerContext.java >>>>>>>>>>>>>>> @@ -45,6 +45,7 @@ import org.apache.logging.log4j.message.Me= ssageFactory; >>>>>>>>>>>>>>> import org.apache.logging.log4j.spi.AbstractLogger; >>>>>>>>>>>>>>> import org.apache.logging.log4j.spi.LoggerContextFactory; >>>>>>>>>>>>>>> import org.apache.logging.log4j.spi.LoggerContextKey; >>>>>>>>>>>>>>> +import org.apache.logging.log4j.spi.ShutdownCapable; >>>>>>>>>>>>>>>=20 >>>>>>>>>>>>>>> import static org.apache.logging.log4j.core.util.ShutdownCa= llbackRegistry.*; >>>>>>>>>>>>>>>=20 >>>>>>>>>>>>>>> @@ -54,7 +55,7 @@ import static org.apache.logging.log4j.cor= e.util.ShutdownCallbackRegistry.*; >>>>>>>>>>>>>>> * filters, etc and will be atomically updated whenever a r= econfigure occurs. >>>>>>>>>>>>>>> */ >>>>>>>>>>>>>>> public class LoggerContext extends AbstractLifeCycle implem= ents org.apache.logging.log4j.spi.LoggerContext, >>>>>>>>>>>>>>> - ConfigurationListener { >>>>>>>>>>>>>>> + ShutdownCapable, ConfigurationListener { >>>>>>>>>>>>>>>=20 >>>>>>>>>>>>>>> /** >>>>>>>>>>>>>>> * Property name of the property change event fired if t= he configuration is changed. >>>>>>>>>>>>>>> @@ -278,6 +279,11 @@ public class LoggerContext extends Abst= ractLifeCycle implements org.apache.loggi >>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>=20 >>>>>>>>>>>>>>> @Override >>>>>>>>>>>>>>> + public void shutdown() { >>>>>>>>>>>>>>> + stop(); >>>>>>>>>>>>>>> + } >>>>>>>>>>>>>>> + >>>>>>>>>>>>>>> + @Override >>>>>>>>>>>>>>> public void stop() { >>>>>>>>>>>>>>> LOGGER.debug("Stopping LoggerContext[name=3D{}, {}]= ...", getName(), this); >>>>>>>>>>>>>>> configLock.lock(); >>>>>>>>>>>>=20 >>>>>>>>>>>>=20 >>>>>>>>>>>>=20 >>>>>>>>>>>> --=20 >>>>>>>>>>>> E-Mail: garydgregory@gmail.com | ggregory@apache.org=20 >>>>>>>>>>>> Java Persistence with Hibernate, Second Edition >>>>>>>>>>>> JUnit in Action, Second Edition >>>>>>>>>>>> Spring Batch in Action >>>>>>>>>>>> Blog: http://garygregory.wordpress.com=20 >>>>>>>>>>>> Home: http://garygregory.com/ >>>>>>>>>>>> Tweet! http://twitter.com/GaryGregory >>>>>>>>>>>=20 >>>>>>>>>>>=20 >>>>>>>>>>>=20 >>>>>>>>>>> --=20 >>>>>>>>>>> E-Mail: garydgregory@gmail.com | ggregory@apache.org=20 >>>>>>>>>>> Java Persistence with Hibernate, Second Edition >>>>>>>>>>> JUnit in Action, Second Edition >>>>>>>>>>> Spring Batch in Action >>>>>>>>>>> Blog: http://garygregory.wordpress.com=20 >>>>>>>>>>> Home: http://garygregory.com/ >>>>>>>>>>> Tweet! http://twitter.com/GaryGregory >>>>>>>>>=20 >>>>>>>>>=20 >>>>>>>>>=20 >>>>>>>>> --=20 >>>>>>>>> E-Mail: garydgregory@gmail.com | ggregory@apache.org=20 >>>>>>>>> Java Persistence with Hibernate, Second Edition >>>>>>>>> JUnit in Action, Second Edition >>>>>>>>> Spring Batch in Action >>>>>>>>> Blog: http://garygregory.wordpress.com=20 >>>>>>>>> Home: http://garygregory.com/ >>>>>>>>> Tweet! http://twitter.com/GaryGregory >>>>>>>=20 >>>>>>>=20 >>>>>>>=20 >>>>>>> --=20 >>>>>>> Matt Sicker >>>>>=20 >>>>>=20 >>>>>=20 >>>>> --=20 >>>>> Matt Sicker >>>>=20 >>>>=20 >>>>=20 >>>> --=20 >>>> =20 >>>>=20 >>>> Mikael St=C3=A5ldal >>>> Senior software developer=20 >>>>=20 >>>> Magine TV >>>> mikael.staldal@magine.com =20 >>>> Grev Turegatan 3 | 114 46 Stockholm, Sweden | www.magine.com=20 >>>>=20 >>>> Privileged and/or Confidential Information may be contained in this mes= sage. If you are not the addressee indicated in this message >>>> (or responsible for delivery of the message to such a person), you may n= ot copy or deliver this message to anyone. In such case,=20 >>>> you should destroy this message and kindly notify the sender by reply e= mail. =20 >=20 >=20 >=20 > --=20 > =20 >=20 > Mikael St=C3=A5ldal > Senior software developer=20 >=20 > Magine TV > mikael.staldal@magine.com =20 > Grev Turegatan 3 | 114 46 Stockholm, Sweden | www.magine.com = =20 >=20 > Privileged and/or Confidential Information may be contained in this messag= e. If you are not the addressee indicated in this message > (or responsible for delivery of the message to such a person), you may not= copy or deliver this message to anyone. In such case,=20 > you should destroy this message and kindly notify the sender by reply emai= l. =20 --Apple-Mail-6A83D31B-1A6B-4CFB-AB5A-2D7645CF925C Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: quoted-printable
Perhaps you also want to add this to t= he LogManager.shutdown() methods, since I imagine that's what people will ac= tually use/look at. 

Sent from my iPhone

On 2016/0= 1/27, at 18:20, Mikael St=C3=A5ldal <mikael.staldal@magine.com> wrote:

OK, done.

On Wed, Jan 27, 2016 at 6:17 AM, Remko Popma= <remko.popma@gmail.com> wrote:
Mikael, feel free to update the javadoc when you have time. 


On Wednesday, 27 Ja= nuary 2016, Remko Popma <remko.popma@gmail.com> wrote:
Since the async loggers and appenders will wait un= til their queue has been cleared by the background thread, it is a blocking c= all. 

We should probably add a sentence to the= java doc to clarify this.  

Sent from my iPhone

O= n 2016/01/26, at 18:15, Mikael St=C3=A5ldal <mikael.staldal@magine.com= > wrote:

I think that we should be clear, in Javadoc, about whether this new method i= s synchronous/blocking or not.

(I could say the same abou= t quite a few existing methods as well, but let's at least start to be clear= about new methods from now.)

On Tue, Jan 26, 2016 at 1:31 AM, Matt Sicker <boards@gmail.com> wrote:
I like it!

On 25 January 2016 at 18:23, Ralph Goe= rs <ralph.goers@dslextreme.com> wrote:=
Then t= he method name would be terminate?  I could live with that.  I als= o like the fact that when something goes wrong with it then it would be inte= rminable ;-)

Ralph

On Jan 25,= 2016, at 5:18 PM, Matt Sicker <boards@gmail.com> wrote:
<= br>
How about Terminable? It's even a real word to boot= .

On 25 Janua= ry 2016 at 18:15, Ralph Goers <ralph.goers@dslextrem= e.com> wrote:
Yes, well - Serializable actually sounds like it s= hould be a real word. Shutdownable doesn=E2=80=99t - in fact, my mail editor= just split it into two words to =E2=80=9Chelp=E2=80=9D me. I take a differe= nt view. A class that declares it implements an interface isn=E2=80=99t =E2=80= =9Ccapable=E2=80=9D of anything - it just implements the interface. The inte= rface name is what tells you that the implementing class is able to do somet= hing, which is why you have Comparable instead of just Compare, Cloneable in= stead of just Clone,  or Closeable instead of just Close. Would you wan= t Stop instead of Stoppable?  I view =E2=80=9Cable=E2=80=9D as just a s= horthand way of saying =E2=80=9CCapable=E2=80=9D, but unfortunately that jus= t doesn=E2=80=99t sound right with Shutdown (at least to me).

=
Here are some =E2=80=9Cable=E2=80=9D alternatives - presumably ea= ch would have a corresponding method name instead of shutdown:
Ter= minateable.
Completeable.
Concludeable.
Haltab= le.
Dismissable.
Expireable.

I s= uppose we could also use Stoppable but that seems odd since stop is part of L= ifecycle.

Got a preference?

Ralph



On Jan 25, 2016, a= t 4:35 PM, Gary Gregory <garydgregory@gmail.com> wrote:
I see some interfaces with "*Capable*" in the name h= ere and there in the FOSS world (but not in the JRE) so I am a little more c= omfortable with it. 

I still see plain old "Shutdown= " as simpler. 

I think I've boiled down my fee= l for this name to the fact that the Capable postfix is redundant since a cl= ass implementing any interface is "capable" of that functionality. IOW we ha= ve Serializable vs. SerializationCabable, which means the same thing.
<= div>
Gary

On Mon, Jan 25, 2016 at 7:27 AM, Ralph Goers <ralph.goers@dslextreme.com> wrote:
What does it feel w= eird to you?  To be honest, I originally named the interface =E2=80=98S= hutdown=E2=80=9D and then changed it since it really is about implementing a= behavior and =E2=80=9CShutdown=E2=80=9D alone doesn=E2=80=99t really descri= be that.

Ralph
<= /font>

On Jan 24, 20= 16, at 11:09 PM, Gary Gregory <garydgregory@gmail.com> wrote:
On Sun, Jan 24, 2016 at 10:07 PM, Gary Gregory <garydgregory@gmail.com> = ;wrote:
=
On Sun, Jan 24, 2016 at 1:54 PM, Ralph Goer= s <ralph.goers@dslextreme.com&= gt; wrote:
Yes, Shutdownable is too weird. 
<= /div>

How about calling it simply "Sh= utdown" then? FooCapable feels weird to me.

Can any= one think of other (one-method or not) optional feature-like interfaces in t= he JRE or other code base?

hm... ShutdownService?

Gary
 =

Gary

Closeable would imply there is a close method, not a shutdo= wn method.  I have my doubts about the try-with-resources use case here= .  Virtually all usages are probably going to be to disable automatic s= hutdown and then the user placing the shutdown call somewhere they can contr= ol, which probably will have nothing to do with initialization of logging.&n= bsp;

Ralph

On Jan 24, 2016, a= t 2:43 PM, Gary Gregory <garydgregory@gmail.com> wrote:

Resending, got a error from my phone...

---------- Forwarded message ----------
From: "Gary Gregory= " <garydgregory@gmail.com>
Date: Jan 24, 2016 1:41 PM
Sub= ject: Re: logging-log4j2 git commit: LOG4J2-124 - Add shutdown methods to Lo= gManager
To: <dev@logging.apache.org>
Cc: 

Hi all,

Any= reason not use the usual -able postfix instead of ShutdownCapable: Shutdown= able sounds too weird? What about reusing plain old Closeable? That means yo= u could use the context in a try-with-resources block, a bonus.

Gary 

On Jan 24, 2016 1= 0:18 AM, <rgoers@apache.org> wrote:
Repository: logging-log4j2
Updated Branches:
 &= nbsp;refs/heads/master 7d3aac4b9 -> 2df3f0e72


LOG4J2-12= 4 - Add shutdown methods to LogManager


Project: http://git-wip-us.apache.org/repos/asf/loggin= g-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/2= df3f0e7
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/2df3f0e7<= br>Diff: http://g= it-wip-us.apache.org/repos/asf/logging-log4j2/diff/2df3f0e7

Branc= h: refs/heads/master
Commit: 2df3f0e7262c90e3fe1700f053eebf18491650d9
= Parents: 7d3aac4
Author: Ralph Goers <rgoers@nextiva.com>Authored: Sun Jan 24 11:18:41 2016 -0700
Committer: Ralph Goers <r= goers@nextiva.com>
Committed: Sun Jan 24 11:18:41 2016 -0700
----------------------------------------------------------------------
=  .../org/apache/logging/log4j/LogManager.java    | 62 +++++++= +++++++++++++
 .../logging/log4j/spi/ShutdownCapable.java  &nbs= p;   | 17 ++++++
 .../apache/logging/log4j/LogManagerTest.java&= nbsp;   |  7 +++
 .../logging/log4j/core/LoggerContext.jav= a       |  8 ++-
 4 files changed, 93 inser= tions(+), 1 deletion(-)
-------------------------------------------------= ---------------------


http://git-wi= p-us.apache.org/repos/asf/logging-log4j2/blob/2df3f0e7/log4j-api/src/main/ja= va/org/apache/logging/log4j/LogManager.java
-------------------------= ---------------------------------------------
diff --git a/log4j-api/src/= main/java/org/apache/logging/log4j/LogManager.java b/log4j-api/src/main/java= /org/apache/logging/log4j/LogManager.java
index f10e5a8..64c6ee5 100644--- a/log4j-api/src/main/java/org/apache/logging/log4j/LogManager.java
= +++ b/log4j-api/src/main/java/org/apache/logging/log4j/LogManager.java
@@= -27,6 +27,7 @@ import org.apache.logging.log4j.simple.SimpleLoggerContextFa= ctory;
 import org.apache.logging.log4j.spi.LoggerContext;
 = import org.apache.logging.log4j.spi.LoggerContextFactory;
 import or= g.apache.logging.log4j.spi.Provider;
+import org.apache.logging.log4j.spi= .ShutdownCapable;
 import org.apache.logging.log4j.status.StatusLogg= er;
 import org.apache.logging.log4j.util.LoaderUtil;
 impor= t org.apache.logging.log4j.util.PropertiesUtil;
@@ -285,6 +286,67 @@ publ= ic class LogManager {
     }

     /*= *
+     * Shutdown using the default LoggerContext.
+&n= bsp;    * @since 2.6
+     */
+    p= ublic static void shutdown() {
+        shutdown(getC= ontext());
+    }
+
+    /**
+    &= nbsp;* Shutdown the logging system if the logging system supports it.
+&n= bsp;    * @param currentContext if true the LoggerContext for the c= aller of this method will be used.
+     * @since 2.6
+=      */
+    public static void shutdown(boolean= currentContext) {
+        shutdown(getContext(curre= ntContext));
+    }
+
+    /**
+   = ;  * Shutdown the logging system if the logging system supports it.
= +     * @param loader The ClassLoader for the context. If nul= l the context will attempt to determine the appropriate
+    &n= bsp;*            ClassLoader.
+   = ;  * @param currentContext if false the LoggerContext appropriate for t= he caller of this method will be used.
+     * @since 2.6<= br>+     */
+    public static void shutdown(fin= al ClassLoader loader, final boolean currentContext) {
+    &nb= sp;   shutdown(getContext(loader, currentContext));
+    }=
+
+    /**
+     * Shutdown the logging s= ystem if the logging system supports it.
+     * @param co= ntext the LoggerContext.
+     * @since 2.6
+  &nb= sp;  */
+    public static void shutdown(LoggerContext con= text) {
+        if (context !=3D null && con= text instanceof ShutdownCapable) {
+          &n= bsp; ((ShutdownCapable) context).shutdown();
+       = }
+    }
+
+    /**
+     * S= hutdown the logging system if the logging system supports it.
+  &nb= sp;  * @param fqcn The fully qualified class name of the Class that thi= s method is a member of.
+     * @param currentContext if f= alse the LoggerContext appropriate for the caller of this method will be use= d.
+     * @since 2.6
+     */
+ = ;   protected static void shutdown(final String fqcn, final boolean cur= rentContext) {
+        shutdown(getContext(fqcn, cur= rentContext));
+    }
+
+    /**
+  &nb= sp;  * Shutdown the logging system if the logging system supports it.+     * @param fqcn The fully qualified class name of the C= lass that this method is a member of.
+     * @param loade= r The ClassLoader for the context. If null the context will attempt to deter= mine the appropriate
+     *        &n= bsp;   ClassLoader.
+     * @param currentContext if f= alse the LoggerContext appropriate for the caller of this method will be use= d.
+     * @since 2.6
+     */
+ = ;   protected static void shutdown(final String fqcn, final ClassLoader= loader, final boolean currentContext) {
+        shu= tdown(getContext(fqcn, loader, currentContext));
+    }
++    /**
      * Returns the c= urrent LoggerContextFactory.
      *
=       * @return The LoggerContextFactory.
http://git-wip-us.apache.org/re= pos/asf/logging-log4j2/blob/2df3f0e7/log4j-api/src/main/java/org/apache/logg= ing/log4j/spi/ShutdownCapable.java
----------------------------------= ------------------------------------
diff --git a/log4j-api/src/main/java= /org/apache/logging/log4j/spi/ShutdownCapable.java b/log4j-api/src/main/java= /org/apache/logging/log4j/spi/ShutdownCapable.java
new file mode 100644index 0000000..a46ef60
--- /dev/null
+++ b/log4j-api/src/main/java/o= rg/apache/logging/log4j/spi/ShutdownCapable.java
@@ -0,0 +1,17 @@
+/*<= br>+ * Copyright (c) 2016 Nextiva, Inc. to Present.
+ * All rights reserv= ed.
+ */
+package org.apache.logging.log4j.spi;
+
+/**
+ * In= terface to be implemented by LoggerContext's that provide a shutdown method.=
+ * @since 2.6
+ */
+public interface ShutdownCapable {
+
+&= nbsp;   /**
+     * Requests that the logging impleme= ntation shut down.
+     */
+    void shutdow= n();
+}

http://git-wip-us.apache= .org/repos/asf/logging-log4j2/blob/2df3f0e7/log4j-api/src/test/java/org/apac= he/logging/log4j/LogManagerTest.java
--------------------------------= --------------------------------------
diff --git a/log4j-api/src/test/ja= va/org/apache/logging/log4j/LogManagerTest.java b/log4j-api/src/test/java/or= g/apache/logging/log4j/LogManagerTest.java
index 48f0eea..596a9f2 100644<= br>--- a/log4j-api/src/test/java/org/apache/logging/log4j/LogManagerTest.jav= a
+++ b/log4j-api/src/test/java/org/apache/logging/log4j/LogManagerTest.j= ava
@@ -17,6 +17,7 @@
 package org.apache.logging.log4j;

&= nbsp;import org.apache.logging.log4j.message.ParameterizedMessageFactory;+import org.apache.logging.log4j.spi.LoggerContext;
 import org.jun= it.Test;

 import static org.junit.Assert.*;
@@ -53,4 +54,10 @= @ public class LogManagerTest {
         assertN= otNull("No Logger returned", logger);
         a= ssertTrue("Incorrect Logger name: " + logger.getName(),LogManagerTest.class.= getName().equals(logger.getName()));
     }
+
+ = ;   @Test
+    public void testShutdown() {
+  &nb= sp;     LoggerContext loggerContext =3D LogManager.getContext(fals= e);
+        LogManager.shutdown(loggerContext);
+=     }
 }

htt= p://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/2df3f0e7/log4j-core/= src/main/java/org/apache/logging/log4j/core/LoggerContext.java
------= ----------------------------------------------------------------
diff --g= it a/log4j-core/src/main/java/org/apache/logging/log4j/core/LoggerContext.ja= va b/log4j-core/src/main/java/org/apache/logging/log4j/core/LoggerContext.ja= va
index 42efbb5..fcdfc16 100644
--- a/log4j-core/src/main/java/org/ap= ache/logging/log4j/core/LoggerContext.java
+++ b/log4j-core/src/main/java= /org/apache/logging/log4j/core/LoggerContext.java
@@ -45,6 +45,7 @@ impor= t org.apache.logging.log4j.message.MessageFactory;
 import org.apach= e.logging.log4j.spi.AbstractLogger;
 import org.apache.logging.log4j= .spi.LoggerContextFactory;
 import org.apache.logging.log4j.spi.Logg= erContextKey;
+import org.apache.logging.log4j.spi.ShutdownCapable;
 import static org.apache.logging.log4j.core.util.ShutdownCallbackReg= istry.*;

@@ -54,7 +55,7 @@ import static org.apache.logging.log4j.cor= e.util.ShutdownCallbackRegistry.*;
  * filters, et= c and will be atomically updated whenever a reconfigure occurs.
  
*/
 public class LoggerContext extends AbstractLifeC= ycle implements org.apache.logging.log4j.spi.LoggerContext,
-   = ;     ConfigurationListener {
+        Shut= downCapable, ConfigurationListener {

     /**
 = ;     * Property name of the property change eve= nt fired if the configuration is changed.
@@ -278,6 +279,11 @@ public cla= ss LoggerContext extends AbstractLifeCycle implements org.apache.loggi
&n= bsp;    }

     @Override
+    p= ublic void shutdown() {
+        stop();
+  &= nbsp; }
+
+    @Override
     public void s= top() {
         LOGGER.debug("Stopping LoggerCo= ntext[name=3D{}, {}]...", getName(), this);
        &= nbsp;configLock.lock();

<= /div>



-- 






--




--
Matt Sicker <boards@gmail.com>


=

-= -



--
3D=

Mikael St=C3=A5ldal
Senior software developer

Magine TV
Grev Turegatan 3  | 114 46 Stoc= kholm, Sweden  |   www.magine.com

Privileged= and/or Confidential Information may be contained in this message. If=20 you are not the addressee indicated in this message
(or responsible for delivery of the message to such a person), you may not copy or deliver this message to anyone. In such case, 
you should destroy this message and kindly notify the sender by reply emai= l.   



--
<= div class=3D"gmail_signature">
3D"MagineTV"

Mikael St=C3=A5ldal
Senior software developer

Magine TV
Grev Turegatan 3  | 114 46 Stoc= kholm, Sweden  |   www.magine.com

Privileged= and/or Confidential Information may be contained in this message. If=20 you are not the addressee indicated in this message
(or responsible for delivery of the message to such a person), you may not copy or deliver this message to anyone. In such case, 
you should destroy this message and kindly notify the sender by reply emai= l.   
= --Apple-Mail-6A83D31B-1A6B-4CFB-AB5A-2D7645CF925C--