This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

View | Details | Raw Unified | Return to bug 56311
Collapse All | Expand All

(-)src/org/netbeans/core/NbErrorManager.java (-125 / +153 lines)
Lines 19-24 Link Here
19
import java.lang.reflect.Method;
19
import java.lang.reflect.Method;
20
import java.io.*;
20
import java.io.*;
21
import java.util.*;
21
import java.util.*;
22
import java.util.logging.FileHandler;
23
import java.util.logging.Level;
24
import java.util.logging.Logger;
25
import java.util.logging.SimpleFormatter;
26
import java.util.logging.StreamHandler;
22
27
23
import org.xml.sax.SAXParseException;
28
import org.xml.sax.SAXParseException;
24
29
Lines 30-38 Link Here
30
* @author Jaroslav Tulach, Jesse Glick
35
* @author Jaroslav Tulach, Jesse Glick
31
*/
36
*/
32
public final class NbErrorManager extends ErrorManager {
37
public final class NbErrorManager extends ErrorManager {
38
    /** Where to log the file */
39
    private Logger logger;
33
40
34
    public NbErrorManager() {
41
    public NbErrorManager() {
35
        this(null, defaultSeverity(), null);
42
        this(null, null);
36
    }
43
    }
37
    
44
    
38
    /**
45
    /**
Lines 40-78 Link Here
40
     * @see "#18141"
47
     * @see "#18141"
41
     */
48
     */
42
    NbErrorManager(PrintStream pw) {
49
    NbErrorManager(PrintStream pw) {
43
        this(null, defaultSeverity(), pw);
50
        this(null, streamLogger (pw));
44
    }
51
    }
45
    
52
    
46
    private static int defaultSeverity() {
53
    private NbErrorManager(String pfx, Logger logger) {
47
        String dsev = System.getProperty("ErrorManager.minimum");
54
        if (logger == null) {
48
        // use e.g. 17 to avoid logging WARNING messages.
55
            if (pfx == null) {
49
        if (dsev != null) {
56
                pfx = ""; // NOI18N
50
            try {
51
                return Integer.parseInt(dsev);
52
            } catch (NumberFormatException nfe) {
53
                nfe.printStackTrace();
54
            }
55
        }
56
        // I.e. 2: avoid logging INFORMATIONAL messages.
57
        return ErrorManager.INFORMATIONAL + 1;
58
    }
59
    
60
    private NbErrorManager(String pfx, int sev, PrintStream pw) {
61
        prefix = pfx;
62
        minLogSeverity = sev;
63
        logWriter = pw;
64
        synchronized (uniquifiedIds) {
65
            Integer i = (Integer)uniquifiedIds.get(pfx);
66
            if (i == null) {
67
                uniquifier = 1;
68
            } else {
69
                uniquifier = i.intValue() + 1;
70
            }
57
            }
71
            uniquifiedIds.put(pfx, new Integer(uniquifier));
58
            logger = createLogger (pfx);
72
        }
59
        }
73
        //System.err.println("NbErrorManager[" + pfx + " #" + uniquifier + "]: minLogSeverity=" + sev);
60
        this.logger = logger;
74
    }
61
    }
75
62
63
    public void flush () {
64
        java.util.logging.Handler[] arr = logger.getHandlers();
65
        for (int i = 0; i < arr.length; i++) {
66
            arr[i].flush();
67
        }
68
    }
69
    
70
    private static Logger streamLogger (PrintStream pw) {
71
        Logger log = Logger.getAnonymousLogger();
72
        StreamHandler s = new StreamHandler (
73
            pw, NbFormater.FORMATTER
74
        );
75
        log.setLevel(Level.ALL);
76
        s.setLevel(Level.ALL);
77
        log.addHandler(s);
78
        return log;
79
    }
80
    
81
    private static java.util.logging.Handler streamHandler;
82
    private static synchronized java.util.logging.Handler streamHandler () {
83
        if (streamHandler == null) {
84
            streamHandler = new StreamHandler (System.err, NbFormater.FORMATTER);
85
        }
86
        return streamHandler;
87
    }
88
    
89
    private static java.util.logging.Handler defaultHandler;
90
    private static synchronized java.util.logging.Handler defaultHandler () {
91
        if (defaultHandler != null) return defaultHandler;
92
        
93
        String home = System.getProperty("netbeans.user");
94
        if (home != null && org.netbeans.core.startup.CLIOptions.isLogging()) {
95
            try {
96
                File f = new File (home + "/var/log");
97
                f.mkdirs ();
98
                
99
                defaultHandler = new FileHandler (home + "/var/log/messages.log", 1000000, 1, true);
100
                defaultHandler.setFormatter(NbFormater.FORMATTER);
101
            } catch (IOException ex) {
102
                ex.printStackTrace();
103
            }
104
        }
105
        
106
        if (defaultHandler == null) {
107
            defaultHandler = streamHandler();
108
        }
109
        return defaultHandler;
110
    }
111
    
112
    private static Logger createLogger (String pfx) {
113
        Logger logger = Logger.getLogger (pfx);
114
        logger.addHandler(defaultHandler ());
115
        if (Boolean.getBoolean("netbeans.logger.console")) { // NOI18N
116
            if (defaultHandler () instanceof FileHandler) {
117
                logger.addHandler (streamHandler ());
118
            }
119
        }
120
        return logger;
121
    }
122
    
76
    /** maps Throwables to java.util.List (Ann) */
123
    /** maps Throwables to java.util.List (Ann) */
77
    private static final Map map = new WeakHashMap (11);
124
    private static final Map map = new WeakHashMap (11);
78
    
125
    
Lines 81-126 Link Here
81
        "{0}*********** Exception occurred ************ at {1,time,short} on {1,date,medium}", // NOI18N
128
        "{0}*********** Exception occurred ************ at {1,time,short} on {1,date,medium}", // NOI18N
82
        java.util.Locale.ENGLISH
129
        java.util.Locale.ENGLISH
83
    );
130
    );
84
85
    /** The writer to the log file*/
86
    private PrintStream logWriter;
87
    
131
    
88
   /** assciates each thread with the lastly notified throwable
132
   /** assciates each thread with the lastly notified throwable
89
    * (Thread, Reference (Throwable))
133
    * (Thread, Reference (Throwable))
90
    */
134
    */
91
    private static final Map lastException = new WeakHashMap (27);
135
    private static final Map lastException = new WeakHashMap (27);
92
136
93
    /** Minimum value of severity to write message to the log file*/
94
    private final int minLogSeverity;
95
96
    /** Prefix preprended to customized loggers, if any. */
97
    private final String prefix;
98
    
99
    // Make sure two distinct EM impls log differently even with the same name.
100
    private final int uniquifier; // 0 for root EM (prefix == null), else >= 1
101
    private static final Map uniquifiedIds = new HashMap(20); // Map<String,Integer>
102
    
103
    static {
137
    static {
104
        System.setProperty("sun.awt.exception.handler", "org.netbeans.core.NbErrorManager$AWTHandler"); // NOI18N
138
        System.setProperty("sun.awt.exception.handler", "org.netbeans.core.NbErrorManager$AWTHandler"); // NOI18N
105
    }
139
    }
106
    
140
    
107
    /** Initializes the log stream.
108
     */
109
    private PrintStream getLogWriter () {
110
        synchronized (this) {
111
            if (logWriter != null) return logWriter;
112
            // to prevent further initializations during TopLogging.getLogOutputStream method
113
            logWriter = System.err;
114
        }
115
        
116
        PrintStream pw = org.netbeans.core.startup.TopLogging.getLogOutputStream();
117
        
118
        synchronized (this) {
119
            logWriter = pw;
120
            return logWriter;
121
        }
122
    }
123
124
    public synchronized Throwable annotate (
141
    public synchronized Throwable annotate (
125
        Throwable t,
142
        Throwable t,
126
        int severity, String message, String localizedMessage,
143
        int severity, String message, String localizedMessage,
Lines 177-182 Link Here
177
    public boolean isNotifiable(int severity) {
194
    public boolean isNotifiable(int severity) {
178
        return isLoggable(severity + 1);
195
        return isLoggable(severity + 1);
179
    }
196
    }
197
    
198
    private static java.util.logging.Level mapSeverity (int severity) {
199
        if (severity == ErrorManager.UNKNOWN) {
200
            return Level.FINEST;
201
        }
202
        
203
        if (severity == ErrorManager.INFORMATIONAL) {
204
            return Level.FINE;
205
        }
206
        
207
        if (severity <= ErrorManager.WARNING) {
208
            return Level.WARNING;
209
        }
210
        
211
        if (severity <= ErrorManager.USER) {
212
            return Level.INFO;
213
        }
214
        
215
        if (severity <= ErrorManager.EXCEPTION) {
216
            return Level.INFO;
217
        }
218
        return Level.SEVERE;
219
    }
180
220
181
    /** Notifies all the exceptions associated with
221
    /** Notifies all the exceptions associated with
182
    * this thread.
222
    * this thread.
Lines 215-228 Link Here
215
            }
255
            }
216
        }
256
        }
217
        if (wantStackTrace) {
257
        if (wantStackTrace) {
218
            PrintStream log = getLogWriter();
258
            Level level = mapSeverity(ex.getSeverity ());
219
            if (prefix != null)
259
            if (logger.isLoggable(level)) {
220
                log.print ("[" + prefix + "] "); // NOI18N        
260
                String l = ex.getSeverity() == INFORMATIONAL ? "INFORMATIONAL " : "";// NOI18N
221
            String level = ex.getSeverity() == INFORMATIONAL ? "INFORMATIONAL " : "";// NOI18N
261
                String msg = EXC_HEADER.format (new Object[] { l, ex.getDate() });
222
            
262
                logger.log (level, msg);
223
            
263
                StringWriter w = new StringWriter ();
224
            log.println (EXC_HEADER.format (new Object[] { level, ex.getDate() }));
264
                ex.printStackTrace (new PrintWriter (w));
225
            ex.printStackTrace(log);
265
                msg = w.toString ();
266
                logger.log (level, msg);
267
            }
226
        }
268
        }
227
269
228
        if (ex.getSeverity () > INFORMATIONAL) {
270
        if (ex.getSeverity () > INFORMATIONAL) {
Lines 255-298 Link Here
255
    }
297
    }
256
298
257
    public void log(int severity, String s) {
299
    public void log(int severity, String s) {
258
        if (isLoggable (severity)) {
300
        logger.log (mapSeverity(severity), s);
259
            //System.err.println(toString() + " logging '" + s + "' at " + severity);
260
            PrintStream log = getLogWriter ();
261
            
262
            if (prefix != null) {
263
                boolean showUniquifier;
264
                // Print a unique EM sequence # if there is more than one
265
                // with this name. Shortcut: if the # > 1, clearly there are.
266
                if (uniquifier > 1) {
267
                    showUniquifier = true;
268
                } else if (uniquifier == 1) {
269
                    synchronized (uniquifiedIds) {
270
                        int count = ((Integer)uniquifiedIds.get(prefix)).intValue();
271
                        showUniquifier = count > 1;
272
                    }
273
                } else {
274
                    throw new IllegalStateException("prefix != null yet uniquifier == 0");
275
                }
276
                if (showUniquifier) {
277
                    log.print ("[" + prefix + " #" + uniquifier + "] "); // NOI18N
278
                } else {
279
                    log.print ("[" + prefix + "] "); // NOI18N
280
                }
281
            }
282
            log.println(s);
283
        }
284
    }
301
    }
285
    
302
    
286
    /** Allows to test whether messages with given severity will be logged
287
     * or not prior to constraction of complicated and time expensive
288
     * logging messages.
289
     *
290
     * @param severity the severity to check
291
     * @return false if the next call to log method with the same severity will
292
     *    discard the message
293
     */
294
    public boolean isLoggable (int severity) {
303
    public boolean isLoggable (int severity) {
295
        return severity >= minLogSeverity;
304
        return logger.isLoggable (mapSeverity(severity));
296
    }
305
    }
297
    
306
    
298
    
307
    
Lines 301-329 Link Here
301
     * a hierarchy.
310
     * a hierarchy.
302
     */
311
     */
303
    public final ErrorManager getInstance(String name) {
312
    public final ErrorManager getInstance(String name) {
304
        String pfx = (prefix == null) ? name : prefix + '.' + name;
313
        String pfx = logger.getName() + '.' + name;
305
        int sev = minLogSeverity;
314
        return new NbErrorManager(pfx, null);
306
        String prop = pfx;
307
        while (prop != null) {
308
            String value = System.getProperty (prop);
309
            //System.err.println ("Trying; prop=" + prop + " value=" + value);
310
            if (value != null) {
311
                try {
312
                    sev = Integer.parseInt (value);                    
313
                } catch (NumberFormatException nfe) {
314
                    notify (WARNING, nfe);
315
                }
316
                break;
317
            } else {
318
                int idx = prop.lastIndexOf ('.');
319
                if (idx == -1)
320
                    prop = null;
321
                else
322
                    prop = prop.substring (0, idx);
323
            }
324
        }
325
        //System.err.println ("getInstance: prefix=" + prefix + " mls=" + minLogSeverity + " name=" + name + " prefix2=" + newEM.prefix + " mls2=" + newEM.minLogSeverity);
326
        return new NbErrorManager(pfx, sev, logWriter);
327
    }    
315
    }    
328
    
316
    
329
    /** Method (or field) names in various exception classes which give
317
    /** Method (or field) names in various exception classes which give
Lines 474-480 Link Here
474
    }
462
    }
475
    
463
    
476
    public String toString() {
464
    public String toString() {
477
        return super.toString() + "<" + prefix + "," + minLogSeverity + ">"; // NOI18N
465
        return super.toString() + "<" + logger + ">"; // NOI18N
478
    }
466
    }
479
467
480
    /** Implementation of annotation interface.
468
    /** Implementation of annotation interface.
Lines 849-852 Link Here
849
            ErrorManager.getDefault().notify((ERROR << 1), t);
837
            ErrorManager.getDefault().notify((ERROR << 1), t);
850
        }
838
        }
851
    }
839
    }
840
841
    /** Modified formater for use in NetBeans.
842
     */
843
    private static final class NbFormater extends java.util.logging.Formatter {
844
        private static String lineSeparator = System.getProperty ("line.separator"); // NOI18N
845
        static java.util.logging.Formatter FORMATTER = new NbFormater ();
846
847
        
848
        public String format(java.util.logging.LogRecord record) {
849
            StringBuffer sb = new StringBuffer();
850
            sb.append(record.getLevel().getName());
851
            addLoggerName (sb, record);
852
            sb.append(": ");
853
            String message = formatMessage(record);
854
            sb.append(message);
855
            sb.append(lineSeparator);
856
            if (record.getThrown() != null) {
857
                try {
858
                    StringWriter sw = new StringWriter();
859
                    PrintWriter pw = new PrintWriter(sw);
860
                    record.getThrown().printStackTrace(pw);
861
                    pw.close();
862
                    sb.append(sw.toString());
863
                } catch (Exception ex) {
864
                }
865
            }
866
            return sb.toString();
867
        }
868
        
869
        private static void addLoggerName (StringBuffer sb, java.util.logging.LogRecord record) {
870
            String name = record.getLoggerName ();
871
            if (!"".equals (name)) {
872
                if (record.getSourceClassName() != null) {	
873
                    sb.append(record.getSourceClassName());
874
                } else {
875
                    sb.append(record.getLoggerName());
876
                }
877
            }
878
        }
879
    }    
852
}
880
}
(-)src/org/netbeans/core/NbTopManager.java (-1 / +2 lines)
Lines 26-31 Link Here
26
import java.util.List;
26
import java.util.List;
27
import java.util.Locale;
27
import java.util.Locale;
28
import java.util.Map;
28
import java.util.Map;
29
import java.util.StringTokenizer;
29
import javax.swing.*;
30
import javax.swing.*;
30
import javax.swing.border.*;
31
import javax.swing.border.*;
31
import javax.swing.event.ChangeEvent;
32
import javax.swing.event.ChangeEvent;
Lines 184-190 Link Here
184
        // Did not work.
185
        // Did not work.
185
        Toolkit.getDefaultToolkit().beep();
186
        Toolkit.getDefaultToolkit().beep();
186
    }
187
    }
187
188
    
188
    /**
189
    /**
189
     * Implementation of URL displayer, which shows documents in the configured web browser.
190
     * Implementation of URL displayer, which shows documents in the configured web browser.
190
     */
191
     */
(-)src/org/netbeans/core/NonGuiMain.java (-3 / +1 lines)
Lines 23-29 Link Here
23
import java.lang.reflect.*;
23
import java.lang.reflect.*;
24
import java.text.MessageFormat;
24
import java.text.MessageFormat;
25
import org.netbeans.core.startup.CLIOptions;
25
import org.netbeans.core.startup.CLIOptions;
26
import org.netbeans.core.startup.TopLogging;
27
26
28
import org.openide.*;
27
import org.openide.*;
29
import org.openide.explorer.*;
28
import org.openide.explorer.*;
Lines 89-95 Link Here
89
        String sysInfo;
88
        String sysInfo;
90
        sysInfo = NbBundle.getBundle(org.netbeans.core.NonGui.class).getString ("CTL_System_info");	// NOI18N
89
        sysInfo = NbBundle.getBundle(org.netbeans.core.NonGui.class).getString ("CTL_System_info");	// NOI18N
91
        out.println("-- " + sysInfo + " ----------------------------------------------------------------"); // NOI18N
90
        out.println("-- " + sysInfo + " ----------------------------------------------------------------"); // NOI18N
92
        TopLogging.printSystemInfo(out);
91
        org.netbeans.core.startup.CLIOptions.printSystemInfo(out);
93
        out.println("-------------------------------------------------------------------------------"); // NOI18N
92
        out.println("-------------------------------------------------------------------------------"); // NOI18N
94
    }
93
    }
95
    
94
    
Lines 344-350 Link Here
344
	    startGui(tmpArgs);
343
	    startGui(tmpArgs);
345
        } else {
344
        } else {
346
            new CLIOptions().cli(tmpArgs);
345
            new CLIOptions().cli(tmpArgs);
347
            CLIOptions.initialize();
348
        }
346
        }
349
        
347
        
350
        if (showInfo) {
348
        if (showInfo) {
(-)src/org/netbeans/core/ui/ProductInformationPanel.java (-1 lines)
Lines 30-36 Link Here
30
import javax.swing.JLabel;
30
import javax.swing.JLabel;
31
import javax.swing.JPanel;
31
import javax.swing.JPanel;
32
import javax.swing.UIManager;
32
import javax.swing.UIManager;
33
import org.netbeans.core.startup.TopLogging;
34
import org.openide.filesystems.FileUtil;
33
import org.openide.filesystems.FileUtil;
35
import org.openide.util.Enumerations;
34
import org.openide.util.Enumerations;
36
import org.openide.util.NbBundle;
35
import org.openide.util.NbBundle;
(-)startup/src/org/netbeans/core/startup/CLIOptions.java (-19 / +86 lines)
Lines 18-24 Link Here
18
import java.beans.*;
18
import java.beans.*;
19
import java.io.*;
19
import java.io.*;
20
import java.security.*;
20
import java.security.*;
21
import java.text.DateFormat;
21
import java.util.Locale;
22
import java.util.Locale;
23
import java.util.StringTokenizer;
22
import javax.swing.*;
24
import javax.swing.*;
23
import javax.swing.border.*;
25
import javax.swing.border.*;
24
26
Lines 37-50 Link Here
37
    
39
    
38
    /** The flag whether to create the log - can be set via -nologging
40
    /** The flag whether to create the log - can be set via -nologging
39
    * command line option */
41
    * command line option */
40
    protected static boolean noLogging = false;
42
    private static boolean noLogging = false;
41
43
42
    /** The flag whether to show the Splash screen on the startup */
44
    /** The flag whether to show the Splash screen on the startup */
43
    protected static boolean noSplash = false;
45
    private static boolean noSplash = false;
44
    /** The Class that logs the IDE events to a log file */
45
    protected static TopLogging logger;
46
    /* The class of the UIManager to be used for netbeans - can be set by command-line argument -ui <class name> */
46
    /* The class of the UIManager to be used for netbeans - can be set by command-line argument -ui <class name> */
47
    protected static Class uiClass;
47
    static Class uiClass;
48
    /* The size of the fonts in the UI - 0 pt, the default value is set in NbTheme (for Metal L&F), for other L&Fs is set
48
    /* The size of the fonts in the UI - 0 pt, the default value is set in NbTheme (for Metal L&F), for other L&Fs is set
49
       in the class Main. The value can be changed in Themes.xml in system directory or by command-line argument -fontsize <size> */
49
       in the class Main. The value can be changed in Themes.xml in system directory or by command-line argument -fontsize <size> */
50
    protected static int uiFontSize = 0;
50
    protected static int uiFontSize = 0;
Lines 188-207 Link Here
188
        return 0;
188
        return 0;
189
    }
189
    }
190
    
190
    
191
    /** Initializes logging etc.
192
     */
193
    public static void initialize() {
194
        if (!noLogging) {
195
            try {
196
                logger = new TopLogging(getLogDir());
197
            } catch (IOException e) {
198
                System.err.println("Cannot create log file. Logging disabled."); // NOI18N
199
                e.printStackTrace();
200
            }
201
        }
202
        StartLog.logProgress("TopLogging initialized"); // NOI18N
203
    }
204
    
205
    protected void usage(PrintWriter w) {
191
    protected void usage(PrintWriter w) {
206
        w.println("Core options:");
192
        w.println("Core options:");
207
        w.println("  --laf <LaF classname> use given LookAndFeel class instead of the default");
193
        w.println("  --laf <LaF classname> use given LookAndFeel class instead of the default");
Lines 219-224 Link Here
219
    private static String getString (String key) {
205
    private static String getString (String key) {
220
        return NbBundle.getMessage (CLIOptions.class, key);
206
        return NbBundle.getMessage (CLIOptions.class, key);
221
    }
207
    }
208
   
209
    /** print the status line.
210
     */
211
    public static void initialize() {
212
        DateFormat df = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL, Locale.ENGLISH);
213
        java.util.Date date = new java.util.Date();
214
        
215
        PrintStream logPrintStream = System.err;
216
        logPrintStream.println("-------------------------------------------------------------------------------"); // NOI18N
217
        logPrintStream.println(">Log Session: "+ df.format (date)); // NOI18N
218
        logPrintStream.println(">System Info: "); // NOI18N
219
        printSystemInfo(logPrintStream);
220
        logPrintStream.println("-------------------------------------------------------------------------------"); // NOI18N
221
    }
222
    
223
    public static void printSystemInfo(PrintStream ps) {
224
        String buildNumber = System.getProperty ("netbeans.buildnumber"); // NOI18N
225
        String currentVersion = NbBundle.getMessage(CLIOptions.class, "currentVersion", buildNumber );
226
        ps.println("  Product Version       = " + currentVersion); // NOI18N
227
        ps.println("  Operating System      = " + System.getProperty("os.name", "unknown")
228
                   + " version " + System.getProperty("os.version", "unknown")
229
                   + " running on " +  System.getProperty("os.arch", "unknown"));
230
        ps.println("  Java; VM; Vendor      = " + System.getProperty("java.version", "unknown") + "; " +
231
                   System.getProperty("java.vm.name", "unknown") + " " + System.getProperty("java.vm.version", "") + "; " +
232
                   System.getProperty("java.vendor", "unknown"));
233
        //ps.println("  Java Vendor URL          = " + System.getProperty("java.vendor.url", "unknown"));
234
        ps.println("  Java Home             = " + System.getProperty("java.home", "unknown"));
235
        //ps.println("  Java Class Version       = " + System.getProperty("java.class.version", "unknown"));
236
        ps.print  ("  System Locale; Encod. = " + Locale.getDefault()); // NOI18N
237
        String branding = NbBundle.getBranding ();
238
        if (branding != null) {
239
            ps.print(" (" + branding + ")"); // NOI18N
240
        }
241
        ps.println("; " + System.getProperty("file.encoding", "unknown")); // NOI18N
242
        ps.println("  Home Dir; Current Dir = " + System.getProperty("user.home", "unknown") + "; " +
243
                   System.getProperty("user.dir", "unknown"));
244
        ps.println("  IDE Install; User Dir = " + CLIOptions.getHomeDir () + "; " + // NOI18N
245
                   CLIOptions.getUserDir ()); // NOI18N
246
        //ps.println("  System Directory         = " + Main.getSystemDir ()); // NOI18N
247
        ps.println("  CLASSPATH             = " + System.getProperty("java.class.path", "unknown")); // NOI18N
248
        ps.println("  Boot & ext classpath  = " + createBootClassPath()); // NOI18N
249
        ps.println("  Dynamic classpath     = " + System.getProperty("netbeans.dynamic.classpath", "unknown")); // NOI18N
250
    }
251
252
    // Copied from NbClassPath:
253
    private static String createBootClassPath() {
254
        // boot
255
        String boot = System.getProperty("sun.boot.class.path"); // NOI18N
256
        StringBuffer sb = (boot != null ? new StringBuffer(boot) : new StringBuffer());
257
        
258
        // std extensions
259
        String extensions = System.getProperty("java.ext.dirs"); // NOI18N
260
        if (extensions != null) {
261
            for (StringTokenizer st = new StringTokenizer(extensions, File.pathSeparator); st.hasMoreTokens();) {
262
                File dir = new File(st.nextToken());
263
                File[] entries = dir.listFiles();
264
                if (entries != null) {
265
                    for (int i = 0; i < entries.length; i++) {
266
                        String name = entries[i].getName().toLowerCase(Locale.US);
267
                        if (name.endsWith(".zip") || name.endsWith(".jar")) { // NOI18N
268
                            if (sb.length() > 0) {
269
                                sb.append(File.pathSeparatorChar);
270
                            }
271
                            sb.append(entries[i].getPath());
272
                        }
273
                    }
274
                }
275
            }
276
        }
277
        
278
        return sb.toString();
279
    }
280
    
222
    
281
    
223
    //
282
    //
224
    // Directory functions
283
    // Directory functions
Lines 313-317 Link Here
313
    
372
    
314
    public static int getFontSize () {
373
    public static int getFontSize () {
315
        return uiFontSize;
374
        return uiFontSize;
375
    }
376
    
377
    public static boolean isLogging() {
378
        return !noLogging;
379
    }
380
    
381
    static boolean isSplash() {
382
        return !noSplash;
316
    }
383
    }
317
}
384
}
(-)startup/src/org/netbeans/core/startup/Main.java (-7 / +6 lines)
Lines 60-66 Link Here
60
   */
60
   */
61
  public static void setSplashMaxSteps(int maxSteps)
61
  public static void setSplashMaxSteps(int maxSteps)
62
  {
62
  {
63
      if (noBar || CLIOptions.noSplash || splash == null)
63
      if (noBar || !CLIOptions.isSplash() || splash == null)
64
          return;
64
          return;
65
      splash.setMaxSteps(maxSteps);
65
      splash.setMaxSteps(maxSteps);
66
  }
66
  }
Lines 69-75 Link Here
69
   */
69
   */
70
  public static void addToSplashMaxSteps(int steps)
70
  public static void addToSplashMaxSteps(int steps)
71
  {
71
  {
72
      if (noBar || CLIOptions.noSplash || splash == null)
72
      if (noBar || !CLIOptions.isSplash() || splash == null)
73
          return;
73
          return;
74
      splash.addToMaxSteps(steps);
74
      splash.addToMaxSteps(steps);
75
  }
75
  }
Lines 78-84 Link Here
78
   */
78
   */
79
  public static void addAndSetSplashMaxSteps(int steps)
79
  public static void addAndSetSplashMaxSteps(int steps)
80
  {
80
  {
81
      if (noBar || CLIOptions.noSplash || splash == null)
81
      if (noBar || !CLIOptions.isSplash() || splash == null)
82
          return;
82
          return;
83
      splash.addAndSetMaxSteps(steps);
83
      splash.addAndSetMaxSteps(steps);
84
  }
84
  }
Lines 94-100 Link Here
94
   */
94
   */
95
  public static void incrementSplashProgressBar(int steps)
95
  public static void incrementSplashProgressBar(int steps)
96
  {
96
  {
97
      if (noBar || CLIOptions.noSplash || splash == null)
97
      if (noBar || !CLIOptions.isSplash() || splash == null)
98
          return;
98
          return;
99
      splash.increment(steps);
99
      splash.increment(steps);
100
  }
100
  }
Lines 283-290 Link Here
283
283
284
    CLIOptions.initialize();
284
    CLIOptions.initialize();
285
    StartLog.logProgress ("Command line parsed"); // NOI18N
285
    StartLog.logProgress ("Command line parsed"); // NOI18N
286
286
    
287
288
// 5. initialize GUI 
287
// 5. initialize GUI 
289
    StartLog.logStart ("XML Factories"); //NOI18N
288
    StartLog.logStart ("XML Factories"); //NOI18N
290
    
289
    
Lines 403-409 Link Here
403
     * during startup (Import, Setup). It makes splash screen visible again.
402
     * during startup (Import, Setup). It makes splash screen visible again.
404
     */
403
     */
405
    protected static void showSplash () {
404
    protected static void showSplash () {
406
        if (!CLIOptions.noSplash) {
405
        if (!!CLIOptions.isSplash()) {
407
            if (splash != null) {
406
            if (splash != null) {
408
                if (Splash.isVisible(splash))
407
                if (Splash.isVisible(splash))
409
                    return;
408
                    return;
(-)startup/src/org/netbeans/core/startup/NbEvents.java (-7 / +9 lines)
Lines 18-23 Link Here
18
import java.io.File;
18
import java.io.File;
19
import java.text.Collator;
19
import java.text.Collator;
20
import java.util.*;
20
import java.util.*;
21
import java.util.logging.Level;
22
import java.util.logging.Logger;
21
import javax.swing.JOptionPane;
23
import javax.swing.JOptionPane;
22
import org.openide.ErrorManager;
24
import org.openide.ErrorManager;
23
import org.openide.filesystems.FileObject;
25
import org.openide.filesystems.FileObject;
Lines 74-80 Link Here
74
        } else if (message == FINISH_ENABLE_MODULES) {
76
        } else if (message == FINISH_ENABLE_MODULES) {
75
            List modules = (List)args[0];
77
            List modules = (List)args[0];
76
            if (! modules.isEmpty()) {
78
            if (! modules.isEmpty()) {
77
                System.err.println(NbBundle.getMessage(NbEvents.class, "TEXT_finish_enable_modules"));
79
                Logger.getLogger("").log (Level.INFO, NbBundle.getMessage(NbEvents.class, "TEXT_finish_enable_modules"));
78
                dumpModulesList(modules);
80
                dumpModulesList(modules);
79
            }
81
            }
80
            setStatusText(
82
            setStatusText(
Lines 209-218 Link Here
209
            Util.err.log(ErrorManager.WARNING, "Warning: the extension " + (File)args[0] + " may be multiply loaded by modules: " + (Set/*<File>*/)args[1] + "; see: http://www.netbeans.org/download/dev/javadoc/OpenAPIs/org/openide/doc-files/classpath.html#class-path"); // NOI18N
211
            Util.err.log(ErrorManager.WARNING, "Warning: the extension " + (File)args[0] + " may be multiply loaded by modules: " + (Set/*<File>*/)args[1] + "; see: http://www.netbeans.org/download/dev/javadoc/OpenAPIs/org/openide/doc-files/classpath.html#class-path"); // NOI18N
210
        } else if (message == MISSING_JAR_FILE) {
212
        } else if (message == MISSING_JAR_FILE) {
211
            File jar = (File)args[0];
213
            File jar = (File)args[0];
212
            System.err.println(NbBundle.getMessage(NbEvents.class, "TEXT_missing_jar_file", jar.getAbsolutePath()));
214
            Logger.getLogger("").log (Level.INFO, NbBundle.getMessage(NbEvents.class, "TEXT_missing_jar_file", jar.getAbsolutePath()));
213
        } else if (message == CANT_DELETE_ENABLED_AUTOLOAD) {
215
        } else if (message == CANT_DELETE_ENABLED_AUTOLOAD) {
214
            Module m = (Module)args[0];
216
            Module m = (Module)args[0];
215
            System.err.println(NbBundle.getMessage(NbEvents.class, "TEXT_cant_delete_enabled_autoload", m.getDisplayName()));
217
            Logger.getLogger("").log (Level.INFO, NbBundle.getMessage(NbEvents.class, "TEXT_cant_delete_enabled_autoload", m.getDisplayName()));
216
        } else if (message == MISC_PROP_MISMATCH) {
218
        } else if (message == MISC_PROP_MISMATCH) {
217
            // XXX does this really need to be logged to the user?
219
            // XXX does this really need to be logged to the user?
218
            // Or should it just be sent quietly to the log file?
220
            // Or should it just be sent quietly to the log file?
Lines 220-229 Link Here
220
            String prop = (String)args[1];
222
            String prop = (String)args[1];
221
            Object onDisk = (Object)args[2];
223
            Object onDisk = (Object)args[2];
222
            Object inMem = (Object)args[3];
224
            Object inMem = (Object)args[3];
223
            System.err.println(NbBundle.getMessage(NbEvents.class, "TEXT_misc_prop_mismatch", new Object[] {m.getDisplayName(), prop, onDisk, inMem}));
225
            Logger.getLogger("").log (Level.INFO, NbBundle.getMessage(NbEvents.class, "TEXT_misc_prop_mismatch", new Object[] {m.getDisplayName(), prop, onDisk, inMem}));
224
        } else if (message == PATCH) {
226
        } else if (message == PATCH) {
225
            File f = (File)args[0];
227
            File f = (File)args[0];
226
            System.err.println(NbBundle.getMessage(NbEvents.class, "TEXT_patch", f.getAbsolutePath()));
228
            Logger.getLogger("").log (Level.INFO, NbBundle.getMessage(NbEvents.class, "TEXT_patch", f.getAbsolutePath()));
227
        }
229
        }
228
        // XXX other messages?
230
        // XXX other messages?
229
    }
231
    }
Lines 259-271 Link Here
259
            // #32331: use platform-specific newlines
261
            // #32331: use platform-specific newlines
260
            buf.append(lineSep);
262
            buf.append(lineSep);
261
        }
263
        }
262
        System.err.print(buf.toString());
264
        Logger.getLogger("").log (Level.INFO, buf.toString());
263
    }
265
    }
264
    
266
    
265
    private void notify(String text, boolean warn) {
267
    private void notify(String text, boolean warn) {
266
        if (Boolean.getBoolean("netbeans.full.hack")) { // NOI18N
268
        if (Boolean.getBoolean("netbeans.full.hack")) { // NOI18N
267
            // #21773: interferes with automated GUI testing.
269
            // #21773: interferes with automated GUI testing.
268
            System.err.println(text);
270
            Logger.getLogger("").log (Level.INFO, text);
269
        } else {
271
        } else {
270
            // Normal - display dialog.
272
            // Normal - display dialog.
271
            int type = warn ? JOptionPane.WARNING_MESSAGE : JOptionPane.INFORMATION_MESSAGE;
273
            int type = warn ? JOptionPane.WARNING_MESSAGE : JOptionPane.INFORMATION_MESSAGE;
(-)startup/src/org/netbeans/core/startup/TopLogging.java (-288 lines)
Removed Link Here
1
/*
2
 *                 Sun Public License Notice
3
 * 
4
 * The contents of this file are subject to the Sun Public License
5
 * Version 1.0 (the "License"). You may not use this file except in
6
 * compliance with the License. A copy of the License is available at
7
 * http://www.sun.com/
8
 * 
9
 * The Original Code is NetBeans. The Initial Developer of the Original
10
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2005 Sun
11
 * Microsystems, Inc. All Rights Reserved.
12
 */
13
14
package org.netbeans.core.startup;
15
16
import java.io.*;
17
import java.text.DateFormat;
18
import java.util.Locale;
19
import java.util.StringTokenizer;
20
21
import org.openide.util.NbBundle;
22
import org.openide.util.RequestProcessor;
23
24
/**
25
 * A class that provides logging facility for the IDE - once instantiated, it
26
 * redirects the System.err into a log file.
27
 * @author Ian Formanek, Ales Novak, Jesse Glick
28
 */
29
public class TopLogging
30
{
31
    /** The name of the log file */
32
    public static final String LOG_FILE_NAME = "messages.log"; // NOI18N
33
34
    private static final boolean disabledConsole = ! Boolean.getBoolean("netbeans.logger.console"); // NOI18N
35
36
    private final PrintStream logPrintStream;
37
38
    private static TopLogging topLogging;
39
    
40
    /** Maximal size of log file.*/
41
    private static final long LOG_MAX_SIZE = 
42
        Long.getLong("org.netbeans.core.TopLogging.LOG_MAX_SIZE", 0x40000).longValue(); // NOI18N
43
44
    /** Number of old log files that are maintained.*/    
45
    private static final int LOG_COUNT = 
46
        Integer.getInteger("org.netbeans.core.TopLogging.LOG_COUNT", 3).intValue(); // NOI18N
47
    
48
    
49
    /** Creates a new TopLogging - redirects the System.err to a log file.
50
     * @param logDir A directory for the log file
51
     */
52
    TopLogging (String logDir) throws IOException  {
53
        topLogging = this;
54
        
55
        File logFileDir = new File (logDir);
56
        if (! logFileDir.exists () && ! logFileDir.mkdirs ()) {
57
            throw new IOException ("Cannot make directory to contain log file"); // NOI18N
58
        }
59
        File logFile = createLogFile (logFileDir, LOG_FILE_NAME);
60
        if ((logFile.exists() && !logFile.canWrite()) || logFile.isDirectory()) {
61
            throw new IOException ("Cannot write to file"); // NOI18N
62
        }
63
64
        OutputStream log = new BufferedOutputStream(new FileOutputStream(logFile.getAbsolutePath(), true));
65
        DateFormat df = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL, Locale.ENGLISH);
66
        java.util.Date date = new java.util.Date();
67
68
        final PrintStream stderr = System.err;
69
        logPrintStream = new PrintStream(new StreamDemultiplexor(stderr, log), false, "UTF-8"); // NOI18N
70
        Runtime.getRuntime().addShutdownHook(new Thread() {
71
            public void run() {
72
                logPrintStream.flush(); // #31519
73
                logPrintStream.close();
74
            }
75
        });
76
        logPrintStream.println("-------------------------------------------------------------------------------"); // NOI18N
77
        logPrintStream.println(">Log Session: "+ df.format (date)); // NOI18N
78
        logPrintStream.println(">System Info: "); // NOI18N
79
        printSystemInfo(logPrintStream);
80
        logPrintStream.println("-------------------------------------------------------------------------------"); // NOI18N
81
82
        System.setErr(logPrintStream);
83
    }
84
85
    private static TopLogging getDefault() {
86
        if (topLogging == null) {
87
            try {
88
                new TopLogging(CLIOptions.getLogDir());
89
            } catch (IOException x) {
90
                org.openide.ErrorManager.getDefault().notify(x);
91
            }
92
        }
93
        return topLogging;
94
    }
95
96
    /** This method limits size of log files. There is kept: actual log file   
97
     *  and old log files. This method prevents from growing log file infinitely.*/
98
    private static File createLogFile (File parent, String chld) {
99
        long firstModified = 0;
100
        File renameTo = null;
101
        File retFile = new File (parent, chld);
102
        
103
        if (!retFile.exists() || retFile.length() < LOG_MAX_SIZE)
104
            return retFile;
105
        
106
        for (int i = 1; i < LOG_COUNT;i++) {
107
            String logName = chld + "."+i; // NOI18N
108
            File logFile = new File (parent, logName);
109
            
110
            if (!logFile.exists()) {
111
                renameTo = logFile;               
112
                break;
113
            }
114
            
115
            long logModif = logFile.lastModified();
116
            if ((firstModified == 0 || logModif < firstModified) &&  logModif > 0) {
117
                firstModified = logModif;
118
                renameTo = logFile;
119
            }            
120
        }
121
122
        if (renameTo != null) {
123
            if (renameTo.exists()) renameTo.delete();
124
            retFile.renameTo(renameTo);
125
        }
126
        
127
        return retFile;
128
    }
129
    
130
    public static void printSystemInfo(PrintStream ps) {
131
        String buildNumber = System.getProperty ("netbeans.buildnumber"); // NOI18N
132
        String currentVersion = NbBundle.getMessage(TopLogging.class, "currentVersion", buildNumber );
133
        ps.println("  Product Version       = " + currentVersion); // NOI18N
134
        ps.println("  Operating System      = " + System.getProperty("os.name", "unknown")
135
                   + " version " + System.getProperty("os.version", "unknown")
136
                   + " running on " +  System.getProperty("os.arch", "unknown"));
137
        ps.println("  Java; VM; Vendor      = " + System.getProperty("java.version", "unknown") + "; " +
138
                   System.getProperty("java.vm.name", "unknown") + " " + System.getProperty("java.vm.version", "") + "; " +
139
                   System.getProperty("java.vendor", "unknown"));
140
        //ps.println("  Java Vendor URL          = " + System.getProperty("java.vendor.url", "unknown"));
141
        ps.println("  Java Home             = " + System.getProperty("java.home", "unknown"));
142
        //ps.println("  Java Class Version       = " + System.getProperty("java.class.version", "unknown"));
143
        ps.print  ("  System Locale; Encod. = " + Locale.getDefault()); // NOI18N
144
        String branding = NbBundle.getBranding ();
145
        if (branding != null) {
146
            ps.print(" (" + branding + ")"); // NOI18N
147
        }
148
        ps.println("; " + System.getProperty("file.encoding", "unknown")); // NOI18N
149
        ps.println("  Home Dir; Current Dir = " + System.getProperty("user.home", "unknown") + "; " +
150
                   System.getProperty("user.dir", "unknown"));
151
        ps.println("  IDE Install; User Dir = " + CLIOptions.getHomeDir () + "; " + // NOI18N
152
                   CLIOptions.getUserDir ()); // NOI18N
153
        //ps.println("  System Directory         = " + Main.getSystemDir ()); // NOI18N
154
        ps.println("  CLASSPATH             = " + System.getProperty("java.class.path", "unknown")); // NOI18N
155
        ps.println("  Boot & ext classpath  = " + createBootClassPath()); // NOI18N
156
        ps.println("  Dynamic classpath     = " + System.getProperty("netbeans.dynamic.classpath", "unknown")); // NOI18N
157
    }
158
159
    // Copied from NbClassPath:
160
    private static String createBootClassPath() {
161
        // boot
162
        String boot = System.getProperty("sun.boot.class.path"); // NOI18N
163
        StringBuffer sb = (boot != null ? new StringBuffer(boot) : new StringBuffer());
164
        
165
        // std extensions
166
        String extensions = System.getProperty("java.ext.dirs"); // NOI18N
167
        if (extensions != null) {
168
            for (StringTokenizer st = new StringTokenizer(extensions, File.pathSeparator); st.hasMoreTokens();) {
169
                File dir = new File(st.nextToken());
170
                File[] entries = dir.listFiles();
171
                if (entries != null) {
172
                    for (int i = 0; i < entries.length; i++) {
173
                        String name = entries[i].getName().toLowerCase(Locale.US);
174
                        if (name.endsWith(".zip") || name.endsWith(".jar")) { // NOI18N
175
                            if (sb.length() > 0) {
176
                                sb.append(File.pathSeparatorChar);
177
                            }
178
                            sb.append(entries[i].getPath());
179
                        }
180
                    }
181
                }
182
            }
183
        }
184
        
185
        return sb.toString();
186
    }
187
    
188
    protected void finalize() throws Throwable {
189
        logPrintStream.flush();
190
        logPrintStream.close();
191
    }
192
193
    /** @since JST-PENDING needed by NbErrorManager */
194
    public static PrintStream getLogOutputStream() {
195
        if (System.getProperty("netbeans.user") == null) { // NOI18N
196
            // No user directory. E.g. from <makeparserdb>. Skip ide.log.
197
            return System.err;
198
        }
199
        return TopLogging.getDefault().logPrintStream;
200
    }
201
202
    private static final class StreamDemultiplexor extends OutputStream implements Runnable {
203
        
204
        /** task to flush the log file, or null */
205
        private RequestProcessor.Task logFlushTask;
206
207
        /** processor in which to flush them */
208
        private static final RequestProcessor RP = new RequestProcessor("Flush ide.log"); // NOI18N
209
210
        /** a lock for flushing */
211
        private static final Object FLUSH_LOCK = new String("org.netbeans.core.TopLogging.StreamDemultiplexor.FLUSH_LOCK"); // NOI18N
212
213
        /** delay for flushing */
214
        private static final int FLUSH_DELAY = Integer.getInteger("netbeans.logger.flush.delay", 15000).intValue(); // NOI18N
215
216
        private final OutputStream stderr;
217
        private final OutputStream log;
218
219
        StreamDemultiplexor(PrintStream stderr, OutputStream log) {
220
            this.stderr = stderr;
221
            this.log = log;
222
        }
223
        
224
        public void write(int b) throws IOException {
225
            log.write(b);
226
            if (! disabledConsole)
227
                stderr.write(b);
228
            flushLog();
229
        }
230
231
        public void write(byte b[]) throws IOException {
232
            log.write(b);
233
            if (! disabledConsole) stderr.write(b);
234
            flushLog();
235
        }
236
237
        public void write(byte b[],
238
                          int off,
239
                          int len)
240
        throws IOException {
241
            log.write(b, off, len);
242
            if (! disabledConsole) stderr.write(b, off, len);
243
            flushLog();
244
        }
245
246
        public void flush() throws IOException {
247
            log.flush();
248
            stderr.flush();
249
        }
250
251
        public void close() throws IOException {
252
            log.close();
253
            stderr.close();
254
        }
255
256
        /**
257
         * Flush the log file asynch.
258
         * Waits for e.g. 15 seconds after the first write.
259
         * Note that this is only a delay to force a flush; if there is a lot
260
         * of content, the buffer will fill up and it may have been written out
261
         * long before. This just catches any trailing content.
262
         * @see "#31519"
263
         */
264
        private void flushLog() {
265
            synchronized (FLUSH_LOCK) {
266
                if (logFlushTask == null) {
267
                    logFlushTask = RP.create(this);
268
                    logFlushTask.schedule(FLUSH_DELAY);
269
                }
270
            }
271
        }
272
273
        /**
274
         * Flush log messages periodically.
275
         */
276
        public void run() {
277
            synchronized (FLUSH_LOCK) {
278
                try {
279
                    flush();
280
                } catch (IOException e) {
281
                    e.printStackTrace();
282
                }
283
                logFlushTask = null;
284
            }
285
        }
286
287
    }
288
}
(-)test/unit/src/org/netbeans/core/NbErrorManagerTest.java (-4 / +24 lines)
Lines 40-51 Link Here
40
    private NbErrorManager err;
40
    private NbErrorManager err;
41
    private ByteArrayOutputStream w;
41
    private ByteArrayOutputStream w;
42
    protected void setUp() throws Exception {
42
    protected void setUp() throws Exception {
43
        w = new ByteArrayOutputStream();
43
        clearWorkDir();
44
        System.setProperty("netbeans.user", getWorkDirPath());
45
        
46
        w = new ByteArrayOutputStream() {
47
            public String toString () {
48
                err.flush();
49
                return super.toString ();
50
            }
51
        };
44
        err = new NbErrorManager(new PrintStream(w));
52
        err = new NbErrorManager(new PrintStream(w));
45
    }
53
    }
46
    
54
    
47
    public void testEMFound() throws Exception {
55
    public void testEMFound() throws Exception {
48
        assertEquals(NbErrorManager.class, Lookup.getDefault().lookup(ErrorManager.class).getClass());
56
        ErrorManager em = (ErrorManager)Lookup.getDefault ().lookup (ErrorManager.class);
57
        assertNotNull ("em", em);
58
        assertEquals(NbErrorManager.class, em.getClass());
59
        
60
        em.log (em.EXCEPTION, "Exception!");
61
        
62
        File f = new File (new File (new File (getWorkDirPath (), "var"), "log"), "messages.log");
63
        if (!f.exists ()) {
64
            fail (
65
                "Cannot find messages.log, parent contains just: " + 
66
                java.util.Arrays.asList (f.getParentFile().list())
67
            );
68
        }
49
    }
69
    }
50
    
70
    
51
    public void testBasicNotify() throws Exception {
71
    public void testBasicNotify() throws Exception {
Lines 56-62 Link Here
56
        assertTrue(s.indexOf("java.lang.NullPointerException: unloc msg") != -1);
76
        assertTrue(s.indexOf("java.lang.NullPointerException: unloc msg") != -1);
57
        assertTrue(s.indexOf("testBasicNotify") != -1);
77
        assertTrue(s.indexOf("testBasicNotify") != -1);
58
    }
78
    }
59
    
79
/*    
60
    public void testLog() throws Exception {
80
    public void testLog() throws Exception {
61
        assertFalse(err.isLoggable(ErrorManager.INFORMATIONAL));
81
        assertFalse(err.isLoggable(ErrorManager.INFORMATIONAL));
62
        err.log("some msg");
82
        err.log("some msg");
Lines 79-85 Link Here
79
        assertTrue(s.indexOf("sub msg #2") != -1);
99
        assertTrue(s.indexOf("sub msg #2") != -1);
80
        assertTrue(s.indexOf("quux.hoho.yaya") != -1);
100
        assertTrue(s.indexOf("quux.hoho.yaya") != -1);
81
    }
101
    }
82
    
102
*/    
83
    /** @see "#15611" */
103
    /** @see "#15611" */
84
    public void testNestedThrowables() throws Exception {
104
    public void testNestedThrowables() throws Exception {
85
        NullPointerException npe = new NullPointerException("unloc msg");
105
        NullPointerException npe = new NullPointerException("unloc msg");

Return to bug 56311