working on net mail, remove printStackTrace()
Some checks are pending
CodeQL / Analyze (push) Waiting to run

This commit is contained in:
Jörg Prante 2024-08-04 22:53:28 +02:00
parent a42062479a
commit 40e34e5fcf
11 changed files with 24 additions and 585 deletions

View file

@ -1,432 +0,0 @@
/*
* Copyright (c) 2012, 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
* version 2 with the GNU Classpath Exception, which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/
package jakarta.mail;
import java.io.PrintStream;
import java.text.MessageFormat;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* A simplified logger used by Jakarta Mail to handle logging to a
* PrintStream and logging through a java.util.logging.Logger.
* If debug is set, messages are written to the PrintStream and
* prefixed by the specified prefix (which is not included in
* Logger messages).
* Messages are logged by the Logger based on the configuration
* of the logging system.
*/
/*
* It would be so much simpler to just subclass Logger and override
* the log(LogRecord) method, as the javadocs suggest, but that doesn't
* work because Logger makes the decision about whether to log the message
* or not before calling the log(LogRecord) method. Instead, we just
* provide the few log methods we need here.
*/
final class MailLogger {
/**
* For log messages.
*/
private final Logger logger;
/**
* For debug output.
*/
private final String prefix;
/**
* Produce debug output?
*/
private final boolean debug;
/**
* Stream for debug output.
*/
private final PrintStream out;
/**
* Construct a new MailLogger using the specified Logger name,
* debug prefix (e.g., "DEBUG"), debug flag, and PrintStream.
*
* @param name the Logger name
* @param prefix the prefix for debug output, or null for none
* @param debug if true, write to PrintStream
* @param out the PrintStream to write to
*/
public MailLogger(String name, String prefix, boolean debug,
PrintStream out) {
logger = Logger.getLogger(name);
this.prefix = prefix;
this.debug = debug;
this.out = out != null ? out : System.out;
}
/**
* Construct a new MailLogger using the specified class' package
* name as the Logger name,
* debug prefix (e.g., "DEBUG"), debug flag, and PrintStream.
*
* @param clazz the Logger name is the package name of this class
* @param prefix the prefix for debug output, or null for none
* @param debug if true, write to PrintStream
* @param out the PrintStream to write to
*/
public MailLogger(Class<?> clazz, String prefix, boolean debug,
PrintStream out) {
String name = packageOf(clazz);
logger = Logger.getLogger(name);
this.prefix = prefix;
this.debug = debug;
this.out = out != null ? out : System.out;
}
/**
* Construct a new MailLogger using the specified class' package
* name combined with the specified subname as the Logger name,
* debug prefix (e.g., "DEBUG"), debug flag, and PrintStream.
*
* @param clazz the Logger name is the package name of this class
* @param subname the Logger name relative to this Logger name
* @param prefix the prefix for debug output, or null for none
* @param debug if true, write to PrintStream
* @param out the PrintStream to write to
*/
public MailLogger(Class<?> clazz, String subname, String prefix, boolean debug,
PrintStream out) {
String name = packageOf(clazz) + "." + subname;
logger = Logger.getLogger(name);
this.prefix = prefix;
this.debug = debug;
this.out = out != null ? out : System.out;
}
/**
* Construct a new MailLogger using the specified Logger name and
* debug prefix (e.g., "DEBUG"). Get the debug flag and PrintStream
* from the Session.
*
* @param name the Logger name
* @param prefix the prefix for debug output, or null for none
* @param session where to get the debug flag and PrintStream
*/
@Deprecated
public MailLogger(String name, String prefix, Session session) {
this(name, prefix, session.getDebug(), session.getDebugOut());
}
/**
* Construct a new MailLogger using the specified class' package
* name as the Logger name and the specified
* debug prefix (e.g., "DEBUG"). Get the debug flag and PrintStream
* from the Session.
*
* @param clazz the Logger name is the package name of this class
* @param prefix the prefix for debug output, or null for none
* @param session where to get the debug flag and PrintStream
*/
@Deprecated
public MailLogger(Class<?> clazz, String prefix, Session session) {
this(clazz, prefix, session.getDebug(), session.getDebugOut());
}
/**
* Create a MailLogger that uses a Logger with the specified name
* and prefix. The new MailLogger uses the same debug flag and
* PrintStream as this MailLogger.
*
* @param name the Logger name
* @param prefix the prefix for debug output, or null for none
* @return a MailLogger for the given name and prefix.
*/
public MailLogger getLogger(String name, String prefix) {
return new MailLogger(name, prefix, debug, out);
}
/**
* Create a MailLogger using the specified class' package
* name as the Logger name and the specified prefix.
* The new MailLogger uses the same debug flag and
* PrintStream as this MailLogger.
*
* @param clazz the Logger name is the package name of this class
* @param prefix the prefix for debug output, or null for none
* @return a MailLogger for the given name and prefix.
*/
public MailLogger getLogger(Class<?> clazz, String prefix) {
return new MailLogger(clazz, prefix, debug, out);
}
/**
* Create a MailLogger that uses a Logger whose name is composed
* of this MailLogger's name plus the specified sub-name, separated
* by a dot. The new MailLogger uses the new prefix for debug output.
* This is used primarily by the protocol trace code that wants a
* different prefix (none).
*
* @param subname the Logger name relative to this Logger name
* @param prefix the prefix for debug output, or null for none
* @return a MailLogger for the given name and prefix.
*/
public MailLogger getSubLogger(String subname, String prefix) {
return new MailLogger(logger.getName() + "." + subname, prefix,
debug, out);
}
/**
* Create a MailLogger that uses a Logger whose name is composed
* of this MailLogger's name plus the specified sub-name, separated
* by a dot. The new MailLogger uses the new prefix for debug output.
* This is used primarily by the protocol trace code that wants a
* different prefix (none).
*
* @param subname the Logger name relative to this Logger name
* @param prefix the prefix for debug output, or null for none
* @param debug the debug flag for the sub-logger
* @return a MailLogger for the given name and prefix.
*/
public MailLogger getSubLogger(String subname, String prefix,
boolean debug) {
return new MailLogger(logger.getName() + "." + subname, prefix,
debug, out);
}
/**
* Log the message at the specified level.
*
* @param level the log level.
* @param msg the message.
*/
public void log(Level level, String msg) {
ifDebugOut(msg);
if (logger.isLoggable(level)) {
final StackTraceElement frame = inferCaller();
logger.logp(level, frame.getClassName(), frame.getMethodName(), msg);
}
}
/**
* Log the message at the specified level.
*
* @param level the log level.
* @param msg the message.
* @param param1 the additional parameter.
*/
public void log(Level level, String msg, Object param1) {
if (debug) {
msg = MessageFormat.format(msg, param1);
debugOut(msg);
}
if (logger.isLoggable(level)) {
final StackTraceElement frame = inferCaller();
logger.logp(level, frame.getClassName(), frame.getMethodName(), msg, param1);
}
}
/**
* Log the message at the specified level.
*
* @param level the log level.
* @param msg the message.
* @param params the message parameters.
*/
public void log(Level level, String msg, Object... params) {
if (debug) {
msg = MessageFormat.format(msg, params);
debugOut(msg);
}
if (logger.isLoggable(level)) {
final StackTraceElement frame = inferCaller();
logger.logp(level, frame.getClassName(), frame.getMethodName(), msg, params);
}
}
/**
* Log the message at the specified level using a format string.
*
* @param level the log level.
* @param msg the message format string.
* @param params the message parameters.
* @since JavaMail 1.5.4
*/
public void logf(Level level, String msg, Object... params) {
msg = String.format(msg, params);
ifDebugOut(msg);
logger.log(level, msg);
}
/**
* Log the message at the specified level.
*
* @param level the log level.
* @param msg the message.
* @param thrown the throwable to log.
*/
public void log(Level level, String msg, Throwable thrown) {
if (debug) {
if (thrown != null) {
debugOut(msg + ", THROW: ");
thrown.printStackTrace(out);
} else {
debugOut(msg);
}
}
if (logger.isLoggable(level)) {
final StackTraceElement frame = inferCaller();
logger.logp(level, frame.getClassName(), frame.getMethodName(), msg, thrown);
}
}
/**
* Log a message at the CONFIG level.
*
* @param msg the message.
*/
public void config(String msg) {
log(Level.CONFIG, msg);
}
/**
* Log a message at the FINE level.
*
* @param msg the message.
*/
public void fine(String msg) {
log(Level.FINE, msg);
}
/**
* Log a message at the FINER level.
*
* @param msg the message.
*/
public void finer(String msg) {
log(Level.FINER, msg);
}
/**
* Log a message at the FINEST level.
*
* @param msg the message.
*/
public void finest(String msg) {
log(Level.FINEST, msg);
}
/**
* If "debug" is set, or our embedded Logger is loggable at the
* given level, return true.
*
* @param level the log level.
* @return true if loggable.
*/
public boolean isLoggable(Level level) {
return debug || logger.isLoggable(level);
}
/**
* Common code to conditionally log debug statements.
*
* @param msg the message to log.
*/
private void ifDebugOut(String msg) {
if (debug)
debugOut(msg);
}
/**
* Common formatting for debug output.
*
* @param msg the message to log.
*/
private void debugOut(String msg) {
if (prefix != null)
out.println(prefix + ": " + msg);
else
out.println(msg);
}
/**
* Return the package name of the class.
* Sometimes there will be no Package object for the class,
* e.g., if the class loader hasn't created one (see Class.getPackage()).
*
* @param clazz the class source.
* @return the package name or an empty string.
*/
private String packageOf(Class<?> clazz) {
Package p = clazz.getPackage();
if (p != null)
return p.getName(); // hopefully the common case
String cname = clazz.getName();
int i = cname.lastIndexOf('.');
if (i > 0)
return cname.substring(0, i);
// no package name, now what?
return "";
}
/**
* A disadvantage of not being able to use Logger directly in Jakarta Mail
* code is that the "source class" information that Logger guesses will
* always refer to this class instead of our caller. This method
* duplicates what Logger does to try to find *our* caller, so that
* Logger doesn't have to do it (and get the wrong answer), and because
* our caller is what's wanted.
*
* @return StackTraceElement that logged the message. Treat as read-only.
*/
private StackTraceElement inferCaller() {
// Get the stack trace.
StackTraceElement[] stack = (new Throwable()).getStackTrace();
// First, search back to a method in the Logger class.
int ix = 0;
while (ix < stack.length) {
StackTraceElement frame = stack[ix];
String cname = frame.getClassName();
if (isLoggerImplFrame(cname)) {
break;
}
ix++;
}
// Now search for the first frame before the "Logger" class.
while (ix < stack.length) {
StackTraceElement frame = stack[ix];
String cname = frame.getClassName();
if (!isLoggerImplFrame(cname)) {
// We've found the relevant frame.
return frame;
}
ix++;
}
// We haven't found a suitable frame, so just punt. This is
// OK as we are only committed to making a "best effort" here.
return new StackTraceElement(MailLogger.class.getName(), "log",
MailLogger.class.getName(), -1);
}
/**
* Frames to ignore as part of the MailLogger to JUL bridge.
*
* @param cname the class name.
* @return true if the class name is part of the MailLogger bridge.
*/
private boolean isLoggerImplFrame(String cname) {
return MailLogger.class.getName().equals(cname);
}
}

View file

@ -64,12 +64,8 @@ public abstract class Service implements AutoCloseable {
/**
* The <code>URLName</code> of this service.
*/
protected volatile URLName url = null;
/**
* Debug flag for this service. Set from the session's debug
* flag when this service is created.
*/
protected boolean debug;
protected volatile URLName url;
private boolean connected = false;
/**
@ -80,7 +76,6 @@ public abstract class Service implements AutoCloseable {
*/
protected Service(Session session, URLName urlname) {
this.session = session;
debug = session.getDebug();
url = urlname;
/*

View file

@ -42,6 +42,7 @@ import java.util.StringTokenizer;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Support interface to generalize
@ -205,6 +206,8 @@ interface StreamLoader {
public final class Session {
private static final Logger logger = Logger.getLogger(Session.class.getName());
// Support legacy @DefaultProvider
private static final String DEFAULT_PROVIDER = "org.xbib.net.mail.util.DefaultProvider";
private static final String confDir;
@ -236,9 +239,6 @@ public final class Session {
// maps type to protocol
// the queue of events to be delivered, if mail.event.scope===session
private final EventQueue q;
private boolean debug = false;
private PrintStream out; // debug output stream
private MailLogger logger;
// Constructor is not public
private Session(Properties props, Authenticator authenticator) {
@ -246,11 +246,6 @@ public final class Session {
this.authenticator = authenticator;
this.streamProvider = StreamProvider.provider();
if (Boolean.parseBoolean(props.getProperty("mail.debug")))
debug = true;
initLogger();
// get the Class associated with the Authenticator
Class<?> cl;
if (authenticator != null) {
@ -479,68 +474,6 @@ public final class Session {
return streamProvider;
}
private final synchronized void initLogger() {
logger = new MailLogger(this.getClass(), "DEBUG", debug, getDebugOut());
}
/**
* Get the debug setting for this Session.
*
* @return current debug setting
*/
public synchronized boolean getDebug() {
return debug;
}
/**
* Set the debug setting for this Session.
* <p>
* Since the debug setting can be turned on only after the Session
* has been created, to turn on debugging in the Session
* constructor, set the property <code>mail.debug</code> in the
* Properties object passed in to the constructor to true. The
* value of the <code>mail.debug</code> property is used to
* initialize the per-Session debugging flag. Subsequent calls to
* the <code>setDebug</code> method manipulate the per-Session
* debugging flag and have no effect on the <code>mail.debug</code>
* property.
*
* @param debug Debug setting
*/
public synchronized void setDebug(boolean debug) {
this.debug = debug;
initLogger();
}
/**
* Returns the stream to be used for debugging output. If no stream
* has been set, <code>System.out</code> is returned.
*
* @return the PrintStream to use for debugging output
* @since JavaMail 1.3
*/
public synchronized PrintStream getDebugOut() {
if (out == null)
return System.out;
else
return out;
}
/**
* Set the stream to be used for debugging output for this session.
* If <code>out</code> is null, <code>System.out</code> will be used.
* Note that debugging output that occurs before any session is created,
* as a result of setting the <code>mail.debug</code> system property,
* will always be sent to <code>System.out</code>.
*
* @param out the PrintStream to use for debugging output
* @since JavaMail 1.3
*/
public synchronized void setDebugOut(PrintStream out) {
this.out = out;
initLogger();
}
/**
* This method returns an array of all the implementations installed
* via the javamail.[default.]providers files that can

View file

@ -234,9 +234,6 @@ public class IMAPStore extends Store
private volatile boolean forceClose = false;
private final Object connectionFailedLock = new Object();
private boolean debugusername; // include username in debug output?
private boolean debugpassword; // include password in debug output?
private boolean messageCacheDebug;
// constructors for IMAPFolder class provided by user
@ -441,12 +438,6 @@ public class IMAPStore extends Store
this.defaultPort = 143;
this.isSSL = isSSL;
debug = session.getDebug();
debugusername = PropUtil.getBooleanProperty(props,
"mail.debug.auth.username", true);
debugpassword = PropUtil.getBooleanProperty(props,
"mail.debug.auth.password", false);
boolean partialFetch = PropUtil.getBooleanProperty(props,
"mail." + name + ".partialfetch", true);
if (!partialFetch) {
@ -649,10 +640,7 @@ public class IMAPStore extends Store
// check for non-null values of host, password, user
if (host == null || password == null || user == null) {
if (logger.isLoggable(Level.FINE))
logger.fine("protocolConnect returning false" +
", host=" + host +
", user=" + traceUser(user) +
", password=" + tracePassword(password));
logger.fine("protocolConnect returning false" + ", host=" + host);
return false;
}
@ -681,10 +669,7 @@ public class IMAPStore extends Store
"\", port " + port + ", isSSL " + isSSL);
protocol = newIMAPProtocol(host, port);
if (logger.isLoggable(Level.FINE))
logger.fine("protocolConnect login" +
", host=" + host +
", user=" + traceUser(user) +
", password=" + tracePassword(password));
logger.fine("protocolConnect login" + ", host=" + host);
protocol.addResponseHandler(nonStoreResponseHandler);
login(protocol, user, password);
protocol.removeResponseHandler(nonStoreResponseHandler);
@ -1221,16 +1206,13 @@ public class IMAPStore extends Store
* XXX - remove this when SASL support is added
*/
private void refreshPassword() {
if (logger.isLoggable(Level.FINE))
logger.fine("refresh password, user: " + traceUser(user));
InetAddress addr;
try {
addr = InetAddress.getByName(host);
} catch (UnknownHostException e) {
addr = null;
}
PasswordAuthentication pa =
session.requestPasswordAuthentication(addr, port,
PasswordAuthentication pa = session.requestPasswordAuthentication(addr, port,
name, null, user);
if (pa != null) {
user = pa.getUserName();
@ -2181,13 +2163,4 @@ public class IMAPStore extends Store
// text there.
notifyStoreListeners(StoreEvent.NOTICE, s);
}
private String traceUser(String user) {
return debugusername ? user : "<user name suppressed>";
}
private String tracePassword(String password) {
return debugpassword ? password :
(password == null ? "<null>" : "<non-null>");
}
}

View file

@ -19,6 +19,8 @@ package org.xbib.net.mail.imap.protocol;
import java.io.CharArrayWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
@ -77,6 +79,9 @@ import java.io.Writer;
*/
public class BASE64MailboxEncoder {
private static final Logger logger = Logger.getLogger(BASE64MailboxEncoder.class.getName());
protected byte[] buffer = new byte[4];
protected int bufsize = 0;
protected boolean started = false;
@ -163,11 +168,10 @@ public class BASE64MailboxEncoder {
bufsize -= 3;
}
} catch (IOException e) {
//e.printStackTrace();
logger.log(Level.WARNING, e.getMessage(), e);
}
}
public void flush() {
try {
// flush any bytes we have
@ -175,14 +179,13 @@ public class BASE64MailboxEncoder {
encode();
bufsize = 0;
}
// write the terminating character of the encoding
if (started) {
out.write('-');
started = false;
}
} catch (IOException e) {
//e.printStackTrace();
logger.log(Level.WARNING, e.getMessage(), e);
}
}

View file

@ -46,6 +46,8 @@ import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.xbib.net.mail.util.LineInputStream;
/**
@ -57,6 +59,8 @@ import org.xbib.net.mail.util.LineInputStream;
public class MboxFolder extends Folder {
private static final Logger logger = Logger.getLogger(MboxFolder.class.getName());
private final String name; // null => the default folder
private boolean is_inbox = false;
private int total; // total number of messages in mailbox
@ -551,7 +555,7 @@ public class MboxFolder extends Folder {
} catch (IOException | MessagingException e) {
throw e;
} catch (Exception e) {
e.printStackTrace();
logger.log(Level.WARNING, e.getMessage(), e);
throw new MessagingException("unexpected exception " + e);
} finally {
// close the folder, flushing out the data
@ -760,7 +764,7 @@ public class MboxFolder extends Folder {
} catch (MessagingException e) {
throw e;
} catch (Exception e) {
e.printStackTrace();
logger.log(Level.WARNING, e.getMessage(), e);
throw new MessagingException("unexpected exception " + e);
} finally {
if (os != null)

View file

@ -103,9 +103,9 @@ public class SMTPTransport extends Transport {
private static final Logger logger = Logger.getLogger(SMTPTransport.class.getName());
private String name = "smtp"; // Name of this protocol
private int defaultPort = 25; // default SMTP port
private boolean isSSL = false; // use SSL?
private String name; // Name of this protocol
private int defaultPort; // default SMTP port
private boolean isSSL; // use SSL?
private String host; // host we're connected to
// Following fields valid only during the sendMessage method.
@ -2428,7 +2428,6 @@ public class SMTPTransport extends Transport {
serverResponse = buf.toString();
} catch (IOException ioex) {
logger.log(Level.FINE, "exception reading response", ioex);
//ioex.printStackTrace(out);
lastServerResponse = "";
lastReturnCode = 0;
throw new MessagingException("Exception reading response", ioex);

View file

@ -319,20 +319,4 @@ public class UUDecoderStream extends FilterInputStream {
}
return true;
}
/*** begin TEST program *****
public static void main(String argv[]) throws Exception {
FileInputStream infile = new FileInputStream(argv[0]);
UUDecoderStream decoder = new UUDecoderStream(infile);
int c;
try {
while ((c = decoder.read()) != -1)
System.out.write(c);
System.out.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
**** end TEST program ****/
}

View file

@ -26,7 +26,6 @@ import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.nio.charset.StandardCharsets;
import java.util.Properties;
import static org.junit.jupiter.api.Assertions.assertFalse;
@ -86,9 +85,6 @@ public final class IMAPAuthDebugTest {
properties.setProperty("mail.imap.port", String.valueOf(server.getPort()));
final Session session = Session.getInstance(properties);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(bos);
session.setDebugOut(ps);
session.setDebug(true);
final Store store = session.getStore("imap");
try {
@ -101,7 +97,6 @@ public final class IMAPAuthDebugTest {
store.close();
}
ps.close();
bos.close();
ByteArrayInputStream bis =
new ByteArrayInputStream(bos.toByteArray());
@ -120,7 +115,6 @@ public final class IMAPAuthDebugTest {
r.close();
return found;
} catch (final Exception e) {
e.printStackTrace();
fail(e.getMessage());
return false; // XXX - doesn't matter
} finally {

View file

@ -86,22 +86,16 @@ public final class POP3AuthDebugTest {
properties.setProperty("mail.pop3.port", String.valueOf(server.getPort()));
final Session session = Session.getInstance(properties);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(bos);
session.setDebugOut(ps);
session.setDebug(true);
final Store store = session.getStore("pop3");
try {
store.connect("test", "test");
} catch (Exception ex) {
System.out.println(ex);
//ex.printStackTrace();
fail(ex.toString());
} finally {
store.close();
}
ps.close();
bos.close();
ByteArrayInputStream bis =
new ByteArrayInputStream(bos.toByteArray());

View file

@ -86,22 +86,15 @@ public final class SMTPAuthDebugTest {
properties.setProperty("mail.smtp.port", String.valueOf(server.getPort()));
final Session session = Session.getInstance(properties);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(bos);
session.setDebugOut(ps);
session.setDebug(true);
final Transport t = session.getTransport("smtp");
try {
t.connect("test", "test");
} catch (Exception ex) {
System.out.println(ex);
//ex.printStackTrace();
fail(ex.toString());
} finally {
t.close();
}
ps.close();
bos.close();
ByteArrayInputStream bis =
new ByteArrayInputStream(bos.toByteArray());
@ -120,7 +113,6 @@ public final class SMTPAuthDebugTest {
r.close();
return found;
} catch (final Exception e) {
e.printStackTrace();
fail(e.getMessage());
return false; // XXX - doesn't matter
} finally {