You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ant.apache.org by Michael Zhou <zy...@alibaba.com> on 2002/05/31 10:12:40 UTC

A logger issue

Hi,

I tried to echo some Non-English message in my build files.
For example:

  <echo message="some Chinese characters here!"/>

which replaces all Chinese character with a "?":

  [echo] ??????

I'm aware that it is PrintStream converts the Strings to bytes with the
system default character encoding (ISO-8859-1).  

Well, I decided to write my own logger instead of using the
ant's DefaultLogger.  The code comes here:

// ========================
// DefaultLogger.java
// ========================
package com.alibaba.toolkit.ant.loggers;

import org.apache.tools.ant.BuildEvent;
import java.io.PrintStream;

public class DefaultLogger extends org.apache.tools.ant.DefaultLogger {

    public void setErrorPrintStream(PrintStream err) {
        this.err = CharsetPrintStream.createWrapper(err);
    }

    public void setOutputPrintStream(PrintStream out) {
        this.out = CharsetPrintStream.createWrapper(out);
    }
}

// ========================
// CharsetPrintStream.java
// ========================
package com.alibaba.toolkit.ant.loggers;

import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;

import org.apache.tools.ant.BuildEvent;

public class CharsetPrintStream extends PrintStream {
    private final static String SYSTEM_CHARSET  = new OutputStreamWriter(System.out).getEncoding();
    private String charset                      = SYSTEM_CHARSET;

    public static CharsetPrintStream createWrapper(OutputStream stream) {
        if (stream == null || stream instanceof CharsetPrintStream) {
            return (CharsetPrintStream) stream;
        }
        try {
            return new CharsetPrintStream(stream, System.getProperty("ant.logger.charset"));
        } catch (UnsupportedEncodingException e) {
            try {
                return new CharsetPrintStream(stream, SYSTEM_CHARSET);
            } catch (UnsupportedEncodingException e2) {
                return null;// should not occur
            }
        }
    }

    public CharsetPrintStream(OutputStream out, String charset)
             throws UnsupportedEncodingException {
        this(out, charset, false);
    }

    public CharsetPrintStream(OutputStream out, String charset, boolean autoFlush)
             throws UnsupportedEncodingException {
        super(out, autoFlush);

        if (charset != null && !charset.trim().equals("")) {
            this.charset = new OutputStreamWriter(out, charset).getEncoding();
        }
    }

    public void print(char c) {
        super.print(correctCharset(String.valueOf(c)));
    }

    public void print(char[] s) {
        super.print(correctCharset(String.valueOf(s)));
    }

    public void print(String s) {
        super.print(correctCharset(String.valueOf(s)));
    }

    public void print(Object obj) {
        super.print(correctCharset(String.valueOf(obj)));
    }

    private String correctCharset(String s) {
        if (s == null) {
            return null;
        }
        try {
            if (SYSTEM_CHARSET.equals(charset)) {
                return s;
            } else {
                return new String(s.getBytes(charset), SYSTEM_CHARSET);
            }
        } catch (UnsupportedEncodingException e) {
            return "should not occur!";
        }
    }
}

Now the echo task do the work:

# export ant.logger.charset=GBK
# ant -logger com.alibaba.toolkit.ant.loggers.DefaultLogger

But there's another problem! When I tried to describe my ant target in
Chinese, like this:

<target name="test" description="Chinese Description">
    ...
</target>

# ant -projecthelp
The console output is:
  
Buildfile: build.xml
Main targets:

test  ???????

Default target: test

That is because these messages are output by calling System.out.println,
and in turn captured and forwared by ant. The problem is that the
System.out/System.err converts the Non-English characters to "?" BEFORE
forward these messages to logger handler!

It's a big problem to me!

Why not use PrintWriter instead of PrintStream?  It's more natural to
Unicode and Java.


-- 
Michael Zhou <zy...@alibaba.com>



--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: A logger issue

Posted by Magesh Umasankar <um...@apache.org>.
You, being in Australia, are not only a day
ahead, but also a couple of seasons ahead - I
am still enjoying Spring ;-)

Cheers,
Magesh

**********************************************
*  Philosopher: A fool who torments himself  *
*  during life, to be spoken of when dead.   *
**********************************************
----- Original Message -----
From: "Conor MacNeill" <co...@cortexebusiness.com.au>
To: "Ant Developers List" <an...@jakarta.apache.org>
Sent: Friday, May 31, 2002 10:15 AM
Subject: Re: A logger issue


> Magesh Umasankar wrote:
> > Alright, Conor.  I will wait for Michael's
> > feedback and if it is positive, I will apply
> > this before building beta2 tomorrow.
> >
> > Cheers,
> > Magesh
>
> For me it is already June 1. :-)
>
> You know, only the clone army (New Zealand) are ahead of us timezone wise.
> (OK, a few others too)
>
> Thanks
> Conor
>
>
>
>
>
> --
> To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
> For additional commands, e-mail: <ma...@jakarta.apache.org>
>


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: A logger issue

Posted by Conor MacNeill <co...@cortexebusiness.com.au>.
Magesh Umasankar wrote:
> Alright, Conor.  I will wait for Michael's
> feedback and if it is positive, I will apply
> this before building beta2 tomorrow.
> 
> Cheers,
> Magesh

For me it is already June 1. :-)

You know, only the clone army (New Zealand) are ahead of us timezone wise. 
(OK, a few others too)

Thanks
Conor





--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: A logger issue

Posted by Magesh Umasankar <um...@apache.org>.
Alright, Conor.  I will wait for Michael's
feedback and if it is positive, I will apply
this before building beta2 tomorrow.

Cheers,
Magesh

**********************************************
*  You are asking for big trouble and a big  *
*  bill when lawyers are the only ones who   *
*  understand the law.                       *
**********************************************
----- Original Message -----
From: "Conor MacNeill" <co...@cortexebusiness.com.au>
To: "Ant Developers List" <an...@jakarta.apache.org>
Sent: Friday, May 31, 2002 9:28 AM
Subject: Re: A logger issue


> Michael Zhou wrote:
> > Hi,
> >
> >
> > # ant -projecthelp
> > The console output is:
> >
> > Buildfile: build.xml
> > Main targets:
> >
> > test  ???????
> >
> > Default target: test
> >
> > That is because these messages are output by calling System.out.println,
> > and in turn captured and forwared by ant. The problem is that the
> > System.out/System.err converts the Non-English characters to "?" BEFORE
> > forward these messages to logger handler!
> >
> > It's a big problem to me!
> >
> > Why not use PrintWriter instead of PrintStream?  It's more natural to
> > Unicode and Java.
> >
> >
>
> Michael, Can you try the attached patch (against 1.5 Branch). I think it
> should give you the behaviour you desire. Please test and let me know.
>
> If it is OK, I'll leave it up to Magesh to decide whether to apply and
> include in the second beta, otherwise I'll commiy after the beta2 is built
> and it will make the final build.
>
> Conor
>
>
>
>
>
>


----------------------------------------------------------------------------
----


> Index: src/main/org/apache/tools/ant/Main.java
> ===================================================================
> RCS file: /home/cvs/jakarta-ant/src/main/org/apache/tools/ant/Main.java,v
> retrieving revision 1.65.2.1
> diff -3 -u -w -p -r1.65.2.1 Main.java
> --- src/main/org/apache/tools/ant/Main.java 7 May 2002 15:11:24 -0000
1.65.2.1
> +++ src/main/org/apache/tools/ant/Main.java 31 May 2002 13:23:16 -0000
> @@ -806,7 +806,7 @@ public class Main {
>        */
>      private static void printDescription(Project project) {
>         if (project.getDescription() != null) {
> -          System.out.println(project.getDescription());
> +          project.log(project.getDescription());
>         }
>      }
>
> @@ -850,20 +850,21 @@ public class Main {
>              }
>          }
>
> -        printTargets(topNames, topDescriptions, "Main targets:",
maxLength);
> +        printTargets(project, topNames, topDescriptions, "Main targets:",
> +                     maxLength);
>          //if there were no main targets, we list all subtargets
>          //as it means nothing has a description
>          if(topNames.size()==0) {
>              printSubTargets=true;
>          }
>          if (printSubTargets) {
> -            printTargets(subNames, null, "Subtargets:", 0);
> +            printTargets(project, subNames, null, "Subtargets:", 0);
>          }
>
>          String defaultTarget = project.getDefaultTarget();
>          if (defaultTarget != null && !"".equals(defaultTarget)) {
>              // shouldn't need to check but...
> -            System.out.println("Default target: " + defaultTarget);
> +            project.log("Default target: " + defaultTarget);
>          }
>      }
>
> @@ -905,8 +906,9 @@ public class Main {
>       *               position so they line up (so long as the names
really
>       *               <i>are</i> shorter than this).
>       */
> -    private static void printTargets(Vector names, Vector descriptions,
> -                                     String heading, int maxlen) {
> +    private static void printTargets(Project project,Vector names,
> +                                     Vector descriptions,String heading,
> +                                     int maxlen) {
>          // now, start printing the targets and their descriptions
>          String lSep = System.getProperty("line.separator");
>          // got a bit annoyed that I couldn't find a pad function
> @@ -925,6 +927,6 @@ public class Main {
>              }
>              msg.append(lSep);
>          }
> -        System.out.println(msg.toString());
> +        project.log(msg.toString());
>      }
>  }
>
>


----------------------------------------------------------------------------
----


> --
> To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
> For additional commands, e-mail: <ma...@jakarta.apache.org>


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: A logger issue

Posted by Michael Zhou <zy...@alibaba.com>.
Thanks, Conor.  The patch solved the problem!

But there's still something uncomfortable, for I still need to extend the
DefaultLogger(or AnsiColorLogger, NoBannerLogger, ..., if I need) in
order to display any Non-English characters. The CharsetPrintStream.java I
posted in last mail is a hack of PrintStream rather than a solution.

BTW, another code that print directly to System.out and System.err still works improperly.

My general idea is to refactory a few classes, so that they
output through PrintWriter rather than PrintStream.  But I have not made
a perfect work yet, because this may cause some interfaces change so the
classes implements this interface have to change either.

Do you have any good idea?

1. interface org.apache.tools.ant.BuildLogger:
   replace the lines:

     void setOutputPrintStream(PrintStream out);
     void setErrorPrintStream(PrintStream err);

   with lines:

     void setOutputStream(OutputStream out);
     void setOutputStreamForError(OutputStream err);

   This enforces the loggers should not "print" directly to the PrintStream.
   For loggers that never "print" or "println", it is sufficent.
   For example, XmlLogger can "write" to the output stream and never needs the PrintStream.
   MailLogger even doesn't need an OutputStream!

2. class org.apache.tools.ant.DefaultLogger

     protected OutputStream outStream;
     protected OutputStream errStream;
     protected PrintWriter out;
     protected PrintWriter err;

     public void setOutputStream(OutputStream outStream) {
         this.outStream = outStream;

         try {
             if (System.getProperty("ant.logger.charset") == null) {

                 // use system default charset
                 this.out = new PrintWriter(new OutputStreamWriter(outStream));
             } else {

                 // use user specified charset
                 this.out = new PrintWriter(new OutputStreamWriter(outStream, System.getProperty("ant.logger.charset")));
             }
         } catch (UnsupportedEncodingException e) {

             // if the user specified an invalid charset, use system default
             this.out = new PrintWriter(new OutputStreamWriter(outStream));
         }
     }

   This is the base class for most text-base logger, such as AnsiColorLogger, NoBannerLogger, ..., etc.
   The class accepts an OutputStream and convert it to a PrintWriter, use the user specified charset.

2. class org.apache.tools.ant.Main and class org.apache.tools.ant.taskdefs.Ant

   rather than set the out/err with PrintStream, use the following statement instead:

     System.setOut(new CharsetPrintStream(new DemuxOutputStream(project, false)));
     System.setErr(new CharsetPrintStream(new DemuxOutputStream(project, true)));

   where CharsetPrintStream is the extension of PrintStream (attached again).

3. class org.apache.tools.ant.DemuxOutputStream

    protected void processBuffer(ByteArrayOutputStream buffer) {
        String output = null;
        if (System.getProperty("ant.logger.charset") == null) {
            buffer.toString(System.getProperty("ant.logger.charset"));
        } else {
            buffer.toString();
        }
        project.demuxOutput(output, isErrorStream);
        resetBufferInfo();
    }

   so that the bytes array is converted properly to string.

If you like, I will debug and test the preceding code and send you the patch.

-- 
Michael Zhou <zy...@alibaba.com>



--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: A logger issue

Posted by Conor MacNeill <co...@cortexebusiness.com.au>.
Michael Zhou wrote:
> Hi,
> 
> 
> # ant -projecthelp
> The console output is:
>   
> Buildfile: build.xml
> Main targets:
> 
> test  ???????
> 
> Default target: test
> 
> That is because these messages are output by calling System.out.println,
> and in turn captured and forwared by ant. The problem is that the
> System.out/System.err converts the Non-English characters to "?" BEFORE
> forward these messages to logger handler!
> 
> It's a big problem to me!
> 
> Why not use PrintWriter instead of PrintStream?  It's more natural to
> Unicode and Java.
> 
> 

Michael, Can you try the attached patch (against 1.5 Branch). I think it 
should give you the behaviour you desire. Please test and let me know.

If it is OK, I'll leave it up to Magesh to decide whether to apply and 
include in the second beta, otherwise I'll commiy after the beta2 is built 
and it will make the final build.

Conor