Source Code Cross Referenced for ProfilerServer.java in  » IDE-Netbeans » cvsclient » org » netbeans » lib » profiler » server » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE Netbeans » cvsclient » org.netbeans.lib.profiler.server 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003:         *
0004:         * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005:         *
0006:         * The contents of this file are subject to the terms of either the GNU
0007:         * General Public License Version 2 only ("GPL") or the Common
0008:         * Development and Distribution License("CDDL") (collectively, the
0009:         * "License"). You may not use this file except in compliance with the
0010:         * License. You can obtain a copy of the License at
0011:         * http://www.netbeans.org/cddl-gplv2.html
0012:         * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013:         * specific language governing permissions and limitations under the
0014:         * License.  When distributing the software, include this License Header
0015:         * Notice in each file and include the License file at
0016:         * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
0017:         * particular file as subject to the "Classpath" exception as provided
0018:         * by Sun in the GPL Version 2 section of the License file that
0019:         * accompanied this code. If applicable, add the following below the
0020:         * License Header, with the fields enclosed by brackets [] replaced by
0021:         * your own identifying information:
0022:         * "Portions Copyrighted [year] [name of copyright owner]"
0023:         *
0024:         * Contributor(s):
0025:         * The Original Software is NetBeans. The Initial Developer of the Original
0026:         * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
0027:         * Microsystems, Inc. All Rights Reserved.
0028:         *
0029:         * If you wish your version of this file to be governed by only the CDDL
0030:         * or only the GPL Version 2, indicate your decision by adding
0031:         * "[Contributor] elects to include this software in this distribution
0032:         * under the [CDDL or GPL Version 2] license." If you do not indicate a
0033:         * single choice of license, a recipient has the option to distribute
0034:         * your version of this file under either the CDDL, the GPL Version 2 or
0035:         * to extend the choice of license to its licensees as provided above.
0036:         * However, if you add GPL Version 2 code and therefore, elected the GPL
0037:         * Version 2 license, then the option applies only if the new code is
0038:         * made subject to such option by the copyright holder.
0039:         */
0040:
0041:        package org.netbeans.lib.profiler.server;
0042:
0043:        import org.netbeans.lib.profiler.global.CalibrationDataFileIO;
0044:        import org.netbeans.lib.profiler.global.CommonConstants;
0045:        import org.netbeans.lib.profiler.global.Platform;
0046:        import org.netbeans.lib.profiler.global.ProfilingSessionStatus;
0047:        import org.netbeans.lib.profiler.server.system.Classes;
0048:        import org.netbeans.lib.profiler.server.system.GC;
0049:        import org.netbeans.lib.profiler.server.system.HeapDump;
0050:        import org.netbeans.lib.profiler.server.system.Threads;
0051:        import org.netbeans.lib.profiler.server.system.Timers;
0052:        import org.netbeans.lib.profiler.wireprotocol.*;
0053:        import java.io.*;
0054:        import java.lang.InterruptedException;
0055:        import java.lang.reflect.InvocationTargetException;
0056:        import java.lang.reflect.Method;
0057:        import java.lang.reflect.Modifier;
0058:        import java.net.*;
0059:        import java.text.MessageFormat;
0060:        import java.util.*;
0061:
0062:        /**
0063:         * This class contains functionality for starting (attaching to) the Target Application (TA), and for
0064:         * communication between the profiling back end and the tool (server and client).
0065:         *
0066:         * @author Tomas Hurka
0067:         * @author Misha Dmitriev
0068:         * @author Ian Formanek
0069:         */
0070:        public class ProfilerServer extends Thread implements  CommonConstants {
0071:            //~ Inner Classes ------------------------------------------------------------------------------------------------------------
0072:
0073:            private static class AttachDynamicThread extends Thread {
0074:                //~ Instance fields ------------------------------------------------------------------------------------------------------
0075:
0076:                private int activateCode;
0077:
0078:                //~ Constructors ---------------------------------------------------------------------------------------------------------
0079:
0080:                AttachDynamicThread(int activateCode) {
0081:                    this .setName(PROFILER_SPECIAL_EXEC_THREAD_NAME + " 5"); // NOI18N
0082:                    this .activateCode = activateCode;
0083:                }
0084:
0085:                //~ Methods --------------------------------------------------------------------------------------------------------------
0086:
0087:                public void run() {
0088:                    try {
0089:                        doActivate(activateCode);
0090:                    } catch (Throwable ex) {
0091:                        System.err
0092:                                .println("Profiler dynamic attach initialization failed due to:"); //NOI18N
0093:                        ex.printStackTrace();
0094:                    }
0095:                }
0096:            }
0097:
0098:            // Copied from org.openide.util.NbBundle
0099:            // Does not support branding!
0100:            private static class LocaleIterator extends Object implements 
0101:                    Iterator {
0102:                //~ Instance fields ------------------------------------------------------------------------------------------------------
0103:
0104:                /**
0105:                 * current locale, and initial locale
0106:                 */
0107:                private Locale initLocale;
0108:
0109:                /**
0110:                 * current locale, and initial locale
0111:                 */
0112:                private Locale locale;
0113:
0114:                /**
0115:                 * the branding string in use
0116:                 */
0117:                private String branding;
0118:
0119:                /**
0120:                 * current sufix which will be returned in next calling nextElement
0121:                 */
0122:                private String current;
0123:
0124:                /**
0125:                 * this flag means, if default locale is in progress
0126:                 */
0127:                private boolean defaultInProgress = false;
0128:
0129:                /**
0130:                 * this flag means, if empty sufix was exported yet
0131:                 */
0132:                private boolean empty = false;
0133:
0134:                //~ Constructors ---------------------------------------------------------------------------------------------------------
0135:
0136:                /**
0137:                 * Creates new LocaleIterator for given locale.
0138:                 *
0139:                 * @param locale given Locale
0140:                 */
0141:                public LocaleIterator(Locale locale) {
0142:                    this .locale = this .initLocale = locale;
0143:
0144:                    if (locale.equals(Locale.getDefault())) {
0145:                        defaultInProgress = true;
0146:                    }
0147:
0148:                    current = '_' + locale.toString(); // NOI18N
0149:
0150:                    //            if (brandingToken == null) {
0151:                    branding = null;
0152:
0153:                    //            } else {
0154:                    //                branding = "_" + brandingToken; // NOI18N
0155:                    //            }
0156:
0157:                    //System.err.println("Constructed: " + this);
0158:                }
0159:
0160:                //~ Methods --------------------------------------------------------------------------------------------------------------
0161:
0162:                /**
0163:                 * Tests if there is any sufix.
0164:                 */
0165:                public boolean hasNext() {
0166:                    return (current != null);
0167:                }
0168:
0169:                /**
0170:                 * @return next sufix.
0171:                 * @throws NoSuchElementException if there is no more locale sufix.
0172:                 */
0173:                public Object next() throws NoSuchElementException {
0174:                    if (current == null) {
0175:                        throw new NoSuchElementException();
0176:                    }
0177:
0178:                    final String ret;
0179:
0180:                    if (branding == null) {
0181:                        ret = current;
0182:                    } else {
0183:                        ret = branding + current;
0184:                    }
0185:
0186:                    int lastUnderbar = current.lastIndexOf('_'); // NOI18N
0187:
0188:                    if (lastUnderbar == 0) {
0189:                        if (empty) {
0190:                            reset();
0191:                        } else {
0192:                            current = ""; // NOI18N
0193:                            empty = true;
0194:                        }
0195:                    } else {
0196:                        if (lastUnderbar == -1) {
0197:                            if (defaultInProgress) {
0198:                                reset();
0199:                            } else {
0200:                                // [PENDING] stuff with trying the default locale
0201:                                // after the real one does not actually seem to work...
0202:                                locale = Locale.getDefault();
0203:                                current = '_' + locale.toString(); // NOI18N
0204:                                defaultInProgress = true;
0205:                            }
0206:                        } else {
0207:                            current = current.substring(0, lastUnderbar);
0208:                        }
0209:                    }
0210:
0211:                    //System.err.println("Returning: `" + ret + "' from: " + this);
0212:                    return ret;
0213:                }
0214:
0215:                public void remove() throws UnsupportedOperationException {
0216:                    throw new UnsupportedOperationException();
0217:                }
0218:
0219:                /**
0220:                 * Finish a series.
0221:                 * If there was a branding prefix, restart without that prefix
0222:                 * (or with a shorter prefix); else finish.
0223:                 */
0224:                private void reset() {
0225:                    if (branding != null) {
0226:                        current = '_' + initLocale.toString(); // NOI18N
0227:
0228:                        int idx = branding.lastIndexOf('_'); // NOI18N
0229:
0230:                        if (idx == 0) {
0231:                            branding = null;
0232:                        } else {
0233:                            branding = branding.substring(0, idx);
0234:                        }
0235:
0236:                        empty = false;
0237:                    } else {
0238:                        current = null;
0239:                    }
0240:                }
0241:            }
0242:
0243:            /**
0244:             * A shutdown wait thread
0245:             */
0246:            private static class ShutdownWaitThread extends Thread {
0247:                //~ Constructors ---------------------------------------------------------------------------------------------------------
0248:
0249:                public ShutdownWaitThread() {
0250:                    setName(PROFILER_SPECIAL_EXEC_THREAD_NAME + " 7"); // NOI18N
0251:                }
0252:
0253:                //~ Methods --------------------------------------------------------------------------------------------------------------
0254:
0255:                public void run() {
0256:                    if (preemptExit && connectionOpen) {
0257:                        profilerServer
0258:                                .sendSimpleCmdToClient(Command.SHUTDOWN_INITIATED);
0259:                        waitForShutdownOK();
0260:                        cleanupOnShutdown();
0261:
0262:                        // ... and proceed with shutdown
0263:                    }
0264:                }
0265:            }
0266:
0267:            /**
0268:             * A thread to execute certain commands in (see comments to executeInSeparateThread above)
0269:             */
0270:            private class SeparateCmdExecutionThread extends Thread {
0271:                //~ Instance fields ------------------------------------------------------------------------------------------------------
0272:
0273:                private boolean stopped = false;
0274:
0275:                //~ Constructors ---------------------------------------------------------------------------------------------------------
0276:
0277:                public SeparateCmdExecutionThread() {
0278:                    ThreadInfo.addProfilerServerThread(this );
0279:                    setName(PROFILER_SPECIAL_EXEC_THREAD_NAME + " 6"); // NOI18N
0280:                    setDaemon(true);
0281:                }
0282:
0283:                //~ Methods --------------------------------------------------------------------------------------------------------------
0284:
0285:                public void run() {
0286:                    synchronized (execInSeparateThreadLock) {
0287:                        while (true) {
0288:                            try {
0289:                                execInSeparateThreadLock.wait();
0290:                            } catch (InterruptedException ex) {
0291:                                System.err.println(THREAD_WAIT_EXCEPTION_MSG); // NOI18N
0292:                            }
0293:
0294:                            if (stopped) {
0295:                                return;
0296:                            }
0297:
0298:                            int opCode = execInSeparateThreadOpCode;
0299:
0300:                            switch (opCode) {
0301:                            case Command.DUMP_EXISTING_RESULTS:
0302:                            case Command.DUMP_EXISTING_RESULTS_LIVE:
0303:
0304:                                long absTimeStamp = ProfilerRuntimeCPU
0305:                                        .getAbsTimeStampInCollectedFormat();
0306:                                boolean res = false;
0307:
0308:                                if ((ProfilerRuntime.eventBuffer != null)
0309:                                        && !ProfilerRuntime.sendingBuffer) {
0310:                                    synchronized (ProfilerRuntime.eventBuffer) {
0311:                                        res = ProfilerInterface.serialClientOperationsLock
0312:                                                .beginTrans(true, true);
0313:
0314:                                        if (res) {
0315:                                            try {
0316:                                                ProfilerInterface
0317:                                                        .dumpExistingResults(opCode == Command.DUMP_EXISTING_RESULTS_LIVE);
0318:                                            } finally {
0319:                                                ProfilerInterface.serialClientOperationsLock
0320:                                                        .endTrans();
0321:                                            }
0322:                                        }
0323:                                    }
0324:                                }
0325:
0326:                                DumpResultsResponse resp = new DumpResultsResponse(
0327:                                        res, absTimeStamp);
0328:                                sendComplexResponseToClient(resp);
0329:
0330:                                break;
0331:                            case Command.RESET_PROFILER_COLLECTORS:
0332:                                requestClientResetResults();
0333:                                sendSimpleResponseToClient(true, null);
0334:
0335:                                break;
0336:                            }
0337:                        }
0338:                    }
0339:                }
0340:
0341:                public void terminate() {
0342:                    stopped = true;
0343:                }
0344:            }
0345:
0346:            //~ Static fields/initializers -----------------------------------------------------------------------------------------------
0347:
0348:            // -----
0349:            // I18N String constants
0350:            // !!! Warning - do not use ResourceBundle.getBundle here, won't work in context of direct/dynamic attach !!!
0351:            // Default EN messages initialized here, will be replaced by localized messages in initLocalizedResources()
0352:            private static ResourceBundle messages;
0353:            private static String ENTER_TO_SHUTDOWN_MSG = "Press ENTER to shut down the target JVM..."; // NOI18N
0354:            private static String MAIN_CLASS_NOT_PUBLIC_MSG = "Main class {0} is not public.\nProfiler can not start it"; // NOI18N
0355:            private static String INCORRECT_MAIN_MODIFIERS_MSG = "Method {0}.main(String args[]) has incorrect modifiers"; // NOI18N
0356:            private static String UNEXPECTED_EXCEPTION_MSG = "Target application threw an unexpected exception: {0}"; // NOI18N
0357:            private static String ELAPSED_TIME_MSG = "Main application thread elapsed time: {0} ms."; // NOI18N
0358:            private static String REMOTE_CONNECTION_MSG = "Profiler Agent: Established remote connection with the tool"; // NOI18N
0359:            private static String LOCAL_CONNECTION_MSG = "Profiler Agent: Established local connection with the tool"; // NOI18N
0360:            private static String WAITING_ON_PORT_MSG = "Profiler Agent: Waiting for connection on port {0} (Protocol version: {1})"; // NOI18N
0361:            private static String WAITING_ON_PORT_TIMEOUT_MSG = "Profiler Agent: Waiting for connection on port {0}, timeout {1} seconds (Protocol version: {2})"; // NOI18N
0362:            private static String CONNECTION_EXCEPTION_MSG = "Profiler Agent Error: Exception when trying to establish connection with client:\n{0}"; // NOI18N
0363:            private static String CONNECTION_TIMEOUT_MSG = "Profiler Agent Error: Timed out trying to establish connection with client"; // NOI18N
0364:            private static String AGENT_ERROR_MSG = "Profiler Agent Error: {0}"; // NOI18N
0365:            private static String CONNECTION_INTERRUPTED_MSG = "Profiler Agent Error: Connection with client interrupted"; // NOI18N
0366:            private static String COMMAND_EXCEPTION_MSG = "Profiler Agent Error: Exception when handling command from client:\n{0}"; // NOI18N
0367:            private static String RESPONSE_EXCEPTION_MSG = "Profiler Agent Error: Exception when trying to send response or command to client:\n{0}"; // NOI18N
0368:            private static String CONNECTION_CLOSED_MSG = "Profiler Agent: Connection with agent closed"; // NOI18N
0369:            private static String INCORRECT_AGENT_ID_MSG = "Profiler Agent Warning: Wrong agentId specified: {0}"; // NOI18N
0370:            private static String THREAD_EXCEPTION_MSG = "Profiler Agent Error: Exception in executeInSeparateThread()"; // NOI18N
0371:            private static String THREAD_WAIT_EXCEPTION_MSG = "Profiler Agent Error: Exception in wait in SeparateCmdExecutionThread"; // NOI18N
0372:            // -----
0373:            public static final int ATTACH_DYNAMIC = 0;
0374:            public static final int ATTACH_DIRECT = 1;
0375:            private static volatile boolean profilerInterfaceInitialized;
0376:            private static volatile boolean connectionOpen;
0377:            private static volatile boolean connectionFailed;
0378:            private static volatile boolean detachCommandReceived;
0379:            private static ProfilerServer profilerServer;
0380:            private static ProfilingSessionStatus status;
0381:            private static volatile boolean startTargetApp;
0382:            private static volatile boolean targetAppMainThreadComplete;
0383:            private static volatile Exception startupException;
0384:            private static Object targetAppRunningLock;
0385:            private static Thread mainThread;
0386:
0387:            // Management of execution of some commands in a separate thread
0388:            private static SeparateCmdExecutionThread separateCmdExecutionThread;
0389:            private static ShutdownWaitThread shutdownWaitThread;
0390:            static Object execInSeparateThreadLock;
0391:            static int execInSeparateThreadOpCode;
0392:            private static boolean preemptExit = true;
0393:            private static boolean shutdownOK = false;
0394:            private static final Object shutdownLock = new Object();
0395:            private static final Object resultsNotifiedLock = new Object();
0396:
0397:            // @GuardedBy resultsNotifiedLock
0398:            private static boolean resultsNotified = false;
0399:            private static boolean resourcesInitialized = false;
0400:
0401:            // This data is needed to avoid passing parameters to doActivate() which may cause problems in attach by pid mode on Windows.
0402:            private static String _fullJFluidPath;
0403:            private static int _portNo;
0404:            private static int _activateCode;
0405:            private static int _timeOut = 0;
0406:            private static Response lastResponse;
0407:            private static Object responseLock = new Object();
0408:
0409:            //~ Instance fields ----------------------------------------------------------------------------------------------------------
0410:
0411:            private ObjectInputStream socketIn;
0412:            private ObjectOutputStream socketOut;
0413:            private ServerSocket serverSocket;
0414:            private Socket clientSocket;
0415:            private WireIO wireIO;
0416:            private boolean dynamic;
0417:            private int agentId = -1;
0418:
0419:            //---------------------------------------------------------------------------------------
0420:            // Communication management
0421:            //---------------------------------------------------------------------------------------
0422:            private int serverPort;
0423:            private int serverTimeout = 0; // no timeout by default
0424:
0425:            //~ Constructors -------------------------------------------------------------------------------------------------------------
0426:
0427:            private ProfilerServer(int port, boolean dynamic, int timeout) {
0428:                super (PROFILER_SERVER_THREAD_NAME);
0429:                setPriority(Thread.MAX_PRIORITY);
0430:                serverPort = port;
0431:                ThreadInfo.addProfilerServerThread(this );
0432:                this .dynamic = dynamic;
0433:
0434:                if (!dynamic) {
0435:                    // for dynamic attach, the server should never timeout
0436:                    serverTimeout = timeout;
0437:                }
0438:
0439:                setDaemon(true);
0440:            }
0441:
0442:            //~ Methods ------------------------------------------------------------------------------------------------------------------
0443:
0444:            public static synchronized Response getLastResponse() {
0445:                Response res;
0446:
0447:                synchronized (responseLock) {
0448:                    if (lastResponse == null) {
0449:                        // I had to introduce the check below, since for some applications, seemingly the GUI ones that open a FileChooser dialog,
0450:                        // we can somehow get an InterruptedException below. This is likely a bug in JDK - maybe AWT just browses and calls
0451:                        // Thread.interrupt() that causes this exception, on waiting threads, and can mistake our thread for its own or something.
0452:                        boolean gotInterrupted = false;
0453:
0454:                        do {
0455:                            try {
0456:                                responseLock.wait();
0457:                                gotInterrupted = false;
0458:                            } catch (InterruptedException ex) {
0459:                                //System.err.println("*** JFluid warning: InterruptedException in ProfilerServer.getLastResponse()");
0460:                                gotInterrupted = true;
0461:                            }
0462:                        } while (gotInterrupted);
0463:
0464:                        if (lastResponse == null) {
0465:                            System.out
0466:                                    .println("Profiler Agent Error: lastResponse == null - internal error?"); // NOI18N
0467:                        }
0468:                    }
0469:
0470:                    res = lastResponse;
0471:                    lastResponse = null;
0472:                }
0473:
0474:                return res;
0475:            }
0476:
0477:            public static Thread getMainThread() {
0478:                return mainThread;
0479:            }
0480:
0481:            public static ProfilingSessionStatus getProfilingSessionStatus() {
0482:                return status;
0483:            }
0484:
0485:            public static boolean isTargetAppMainThreadComplete() {
0486:                return targetAppMainThreadComplete;
0487:            }
0488:
0489:            public static void activate(String fullJFluidPath, int portNo,
0490:                    final int activateCode) {
0491:                activate(fullJFluidPath, portNo, activateCode, 0);
0492:            }
0493:
0494:            /**
0495:             * Entrypoint in the usage scenario when the client attaches to the running target app using an OS signal,
0496:             * or the "attach on startup" method. On JDK 1.5,
0497:             * called from ProfilerActivate15.premain().
0498:             * activateCode == 0 : "attach on the fly", activateCode == 1 : "attach on startup"
0499:             *
0500:             * @param fullJFluidPath Full path to the agent libs
0501:             * @param portNo         Port number to use
0502:             * @param activateCode   one of ATTACH_DIRECT or ATTACH_DYNAMIC, determines whether the server is started in dynamic
0503:             *                       attach mode ( JDK 1.6) or Direct attach
0504:             * @param timeOut        Time out in seconds for server socket, or 0 for no timeout
0505:             * @see #ATTACH_DIRECT
0506:             * @see #ATTACH_DYNAMIC
0507:             */
0508:            public static void activate(String fullJFluidPath, int portNo,
0509:                    final int activateCode, int timeOut) {
0510:                try {
0511:                    _fullJFluidPath = fullJFluidPath;
0512:                    _portNo = portNo;
0513:                    _timeOut = timeOut;
0514:                    _activateCode = activateCode;
0515:
0516:                    initLocalizedResources();
0517:
0518:                    if (activateCode == ATTACH_DYNAMIC) {
0519:                        // Creation of the new thread is (hopefully) a temporary workaround to avoid the problem with stack
0520:                        // overflow or something else when we attach on Windows "by pid", i.e. using the CreateRemoteThread() call.
0521:                        new AttachDynamicThread(activateCode).start();
0522:                    } else {
0523:                        doActivate(activateCode);
0524:                    }
0525:                } catch (Throwable ex) {
0526:                    System.err
0527:                            .println("Profiler initialization failed due to:"); //NOI18N
0528:                    ex.printStackTrace();
0529:                }
0530:            }
0531:
0532:            /**
0533:             * Entrypoint in the usage scenario where the client starts and stops the target application.
0534:             * Start the communication thread and then the target application.
0535:             * args[0] is the full path to the directory where JFluid native libraries are contained.
0536:             * args[1] is the communication port number.
0537:             * args[2] (optional) if it is a number, it is a timeout for the profiler server (in seconds) to wait until the
0538:             * client connects
0539:             * args[2 or 3] is the target app main class name; args[3 or 4..n] are its arguments.
0540:             */
0541:            public static void main(String[] args) {
0542:                mainThread = Thread.currentThread();
0543:
0544:                // Fix for Issue 69454 - cannot find path to Profiler libraries (http://www.netbeans.org/issues/show_bug.cgi?id=69454)
0545:                // _fullJFluidPath is needed for lazy initializing localized messages, but it was originally set only by the activate() method
0546:                // Now it has to be set also here for the I18N to work
0547:                try {
0548:                    _fullJFluidPath = new File(args[0]).getParentFile()
0549:                            .getParentFile().getParentFile().getAbsolutePath();
0550:                } catch (Exception ex) {
0551:                    throw new RuntimeException(
0552:                            "ProfilerServer: Unable to initialize ResourceBundle for ProfilerServer, cannot resolve library directory\n" // NOI18N
0553:                                    + ex.getMessage());
0554:                }
0555:
0556:                initLocalizedResources();
0557:                initInternals();
0558:
0559:                // Get the port number
0560:                int portNo = 0;
0561:
0562:                try {
0563:                    portNo = Integer.parseInt(args[1]);
0564:                } catch (NumberFormatException e) {
0565:                    internalError("illegal port number specified: " + args[1]); // NOI18N
0566:                }
0567:
0568:                int idx = 2;
0569:
0570:                // Get the optional timeout number
0571:                int timeout = 0;
0572:
0573:                try {
0574:                    timeout = Integer.parseInt(args[2]);
0575:                    idx = 3;
0576:                } catch (NumberFormatException e) {
0577:                    // timeout not specified (it is optional)
0578:                }
0579:
0580:                // Move the target app arguments into special array
0581:                int len = args.length - (idx + 1);
0582:                String[] targetAppArgs = new String[len];
0583:                System.arraycopy(args, idx + 1, targetAppArgs, 0, len);
0584:
0585:                // Start the communication thread and wait for it to establish connection with client
0586:                profilerServer = new ProfilerServer(portNo, true, timeout);
0587:                profilerServer.start();
0588:
0589:                while (!(connectionOpen || connectionFailed)) {
0590:                    delay(50);
0591:                }
0592:
0593:                if (connectionFailed) {
0594:                    // prevent the console from dying without the user being able to see the error
0595:                    // pressEnterToShutDown();
0596:                    // no cleanup in this case, as there is no connection established
0597:                    preemptExit = false;
0598:                    System.exit(-1);
0599:                }
0600:
0601:                ProfilerInterface.setProfilerServer(profilerServer);
0602:
0603:                initSupportingFunctionality(false, profilerServer
0604:                        .isRemoteProfiling());
0605:
0606:                // Accept, or wait for, the client command to start the target app, and then start it.
0607:                while (!startTargetApp) {
0608:                    delay(100);
0609:                }
0610:
0611:                runTargetApp(args[idx], targetAppArgs);
0612:                targetAppMainThreadComplete = true;
0613:
0614:                // If we haven't actually managed to start the app, notify the waiting communication thread.
0615:                if (startupException != null) {
0616:                    synchronized (targetAppRunningLock) {
0617:                        targetAppRunningLock.notify();
0618:                    }
0619:                }
0620:
0621:                // Wait for some time in case the target app started some threads and then exited the main thread, while the
0622:                // offspring threads have not yet fully initialized
0623:                delay(300);
0624:
0625:                // Now wait until all target app threads (excluding this, main one) terminate.
0626:                while (Threads.targetAppThreadsExist()) {
0627:                    delay(300);
0628:                }
0629:
0630:                status.targetAppRunning = false;
0631:                ProfilerInterface.disableProfilerHooks(); // So that e.g. System.exit() doesn't cause class loads and command sends
0632:                // DEBUGGING: if it's needed to check how good is the sampling interval when sampled instrumentation is used,
0633:                // decomment the one below to make the sampling thread stop here and report the debug data.
0634:                // ProfilerRuntimeCPUSampledInstr.clearDataStructures();
0635:
0636:                profilerServer
0637:                        .sendSimpleCmdToClient(Command.SHUTDOWN_INITIATED);
0638:                waitForShutdownOK();
0639:                forcedShutdown();
0640:            }
0641:
0642:            public boolean isRemoteProfiling() {
0643:                String socketAddr = clientSocket.getRemoteSocketAddress()
0644:                        .toString();
0645:                boolean res = !(((socketAddr.indexOf("127.0.0.1") != -1) || socketAddr
0646:                        .startsWith("localhost"))); // NOI18N
0647:
0648:                if (res) {
0649:                    System.out.println(REMOTE_CONNECTION_MSG);
0650:                } else {
0651:                    System.out.println(LOCAL_CONNECTION_MSG);
0652:                }
0653:
0654:                return res;
0655:            }
0656:
0657:            public ObjectOutputStream getSocketOutputStream() {
0658:                return socketOut;
0659:            }
0660:
0661:            public static void notifyClientOnResultsAvailability() {
0662:                if (!connectionOpen) {
0663:                    return;
0664:                }
0665:
0666:                if (profilerServer == null) {
0667:                    return; // in calibration mode
0668:                }
0669:
0670:                synchronized (resultsNotifiedLock) {
0671:                    if (resultsNotified) {
0672:                        return; // no need to notify again
0673:                    }
0674:
0675:                    resultsNotified = true;
0676:                    profilerServer
0677:                            .sendSimpleCmdToClient(Command.RESULTS_AVAILABLE);
0678:                }
0679:            }
0680:
0681:            public static void requestClientResetResults() {
0682:                ProfilerInterface.resetProfilerCollectors();
0683:                ProfilerCalibrator.resetInternalStatsCollectors();
0684:            }
0685:
0686:            public static void requestClientTakeSnapshot() {
0687:                if (profilerServer == null) {
0688:                    return; // in calibration mode
0689:                }
0690:
0691:                profilerServer.sendSimpleCmdToClient(Command.TAKE_SNAPSHOT);
0692:            }
0693:
0694:            public boolean getAndCheckLastResponse() {
0695:                Response resp = getLastResponse();
0696:
0697:                return resp.isOK();
0698:            }
0699:
0700:            public void run() {
0701:                if (connectToClient()) {
0702:                    while (!profilerInterfaceInitialized) {
0703:                        delay(50);
0704:                    }
0705:
0706:                    listenToClient();
0707:                } else {
0708:                    preemptExit = false;
0709:                }
0710:            }
0711:
0712:            public void sendClassLoaderUnloadingCommand() {
0713:                sendSimpleCmdToClient(Command.CLASS_LOADER_UNLOADING);
0714:                getLastResponse();
0715:            }
0716:
0717:            public synchronized void sendComplexCmdToClient(Command cmd) {
0718:                try {
0719:                    wireIO.sendComplexCommand(cmd);
0720:                } catch (IOException ex) {
0721:                    if (!detachCommandReceived) {
0722:                        handleIOExceptionOnSend(ex);
0723:                    }
0724:                }
0725:            }
0726:
0727:            public synchronized void sendComplexResponseToClient(Response resp) {
0728:                try {
0729:                    wireIO.sendComplexResponse(resp);
0730:                } catch (IOException ex) {
0731:                    if (!detachCommandReceived) {
0732:                        handleIOExceptionOnSend(ex);
0733:                    }
0734:                }
0735:            }
0736:
0737:            // Several methods to send commands specific for modules that use wireprotocol just occasionally
0738:            public boolean sendEventBufferDumpedCommand(int length,
0739:                    boolean waitForResponse) {
0740:                EventBufferDumpedCommand cmd = new EventBufferDumpedCommand(
0741:                        length);
0742:                sendComplexCmdToClient(cmd);
0743:
0744:                if (waitForResponse) {
0745:                    Response resp = getLastResponse();
0746:
0747:                    return resp.isOK();
0748:                } else {
0749:                    return true;
0750:                }
0751:            }
0752:
0753:            public synchronized void sendSimpleCmdToClient(int cmdType) {
0754:                try {
0755:                    wireIO.sendSimpleCommand(cmdType);
0756:                } catch (IOException ex) {
0757:                    if (!detachCommandReceived) {
0758:                        handleIOExceptionOnSend(ex);
0759:                    }
0760:                }
0761:            }
0762:
0763:            public synchronized void sendSimpleResponseToClient(boolean val,
0764:                    String errorMessage) {
0765:                try {
0766:                    wireIO.sendSimpleResponse(val, errorMessage);
0767:                } catch (IOException ex) {
0768:                    if (!detachCommandReceived) {
0769:                        handleIOExceptionOnSend(ex);
0770:                    }
0771:                }
0772:            }
0773:
0774:            // --- I18N Support ----------------------------------------------------------
0775:
0776:            // This method is used for obtaining ResourceBundle from classes that can be
0777:            // used by ProfilerServer in context of direct/dynamic attach.
0778:            //
0779:            // If path to profiler server libraries (.jar) is known, ResourceBundle is obtained
0780:            // using custom classloader (solves problem with bootstrap classloader&dynamic attach)
0781:            //
0782:            // Does not support branding!
0783:            static ResourceBundle getProfilerServerResourceBundle() {
0784:                if (messages != null) {
0785:                    return messages;
0786:                }
0787:
0788:                // 1. try to get the ResourceBundle using custom classloader
0789:                if (_fullJFluidPath != null) {
0790:                    try {
0791:                        messages = getProfilerServerResourceBundle(_fullJFluidPath);
0792:                    } catch (Exception e) {
0793:                        System.err
0794:                                .println("Profiler Server: Problem with customized initializing localized messages...\n"
0795:                                        + e.getMessage()); // NOI18N
0796:                    }
0797:                }
0798:
0799:                ; // cannot find jfluid-server.jar or Bundle.properties not found
0800:
0801:                if (messages != null) {
0802:                    return messages; // ResourceBundle successfuly loaded using custom classloader
0803:                }
0804:
0805:                // 2. try to get the ResourceBundle in standard way
0806:                try {
0807:                    messages = ResourceBundle
0808:                            .getBundle("org.netbeans.lib.profiler.server.Bundle"); // NOI18N
0809:                } catch (Exception e) {
0810:                    System.err
0811:                            .println("Profiler Server: Problem with default initializing localized messages...\n"
0812:                                    + e.getMessage()); // NOI18N
0813:                }
0814:
0815:                ;
0816:
0817:                return messages;
0818:            }
0819:
0820:            static void initLocalizedResources() {
0821:                if (resourcesInitialized) {
0822:                    return;
0823:                }
0824:
0825:                messages = getProfilerServerResourceBundle();
0826:
0827:                if (messages != null) {
0828:                    ENTER_TO_SHUTDOWN_MSG = messages
0829:                            .getString("ProfilerServer_EnterToShutdownMsg"); // NOI18N
0830:                    MAIN_CLASS_NOT_PUBLIC_MSG = messages
0831:                            .getString("ProfilerServer_MainClassNotPublicMsg"); // NOI18N
0832:                    INCORRECT_MAIN_MODIFIERS_MSG = messages
0833:                            .getString("ProfilerServer_IncorrectMainModifiersMsg"); // NOI18N
0834:                    UNEXPECTED_EXCEPTION_MSG = messages
0835:                            .getString("ProfilerServer_UnexpectedExceptionMsg"); // NOI18N
0836:                    ELAPSED_TIME_MSG = messages
0837:                            .getString("ProfilerServer_ElapsedTimeMsg"); // NOI18N
0838:                    REMOTE_CONNECTION_MSG = messages
0839:                            .getString("ProfilerServer_RemoteConnectionMsg"); // NOI18N
0840:                    LOCAL_CONNECTION_MSG = messages
0841:                            .getString("ProfilerServer_LocalConnectionMsg"); // NOI18N
0842:                    WAITING_ON_PORT_MSG = messages
0843:                            .getString("ProfilerServer_WaitingOnPortMsg"); // NOI18N
0844:                    WAITING_ON_PORT_TIMEOUT_MSG = messages
0845:                            .getString("ProfilerServer_WaitingOnPortTimeoutMsg"); // NOI18N
0846:                    CONNECTION_EXCEPTION_MSG = messages
0847:                            .getString("ProfilerServer_ConnectionExceptionMsg"); // NOI18N
0848:                    CONNECTION_TIMEOUT_MSG = messages
0849:                            .getString("ProfilerServer_ConnectionTimeoutMsg"); // NOI18N
0850:                    AGENT_ERROR_MSG = messages
0851:                            .getString("ProfilerServer_AgentErrorMsg"); // NOI18N
0852:                    CONNECTION_INTERRUPTED_MSG = messages
0853:                            .getString("ProfilerServer_ConnectionInterruptedMsg"); // NOI18N
0854:                    COMMAND_EXCEPTION_MSG = messages
0855:                            .getString("ProfilerServer_CommandExceptionMsg"); // NOI18N
0856:                    RESPONSE_EXCEPTION_MSG = messages
0857:                            .getString("ProfilerServer_ResponseExceptionMsg"); // NOI18N
0858:                    CONNECTION_CLOSED_MSG = messages
0859:                            .getString("ProfilerServer_ConnectionClosedMsg"); // NOI18N
0860:                    INCORRECT_AGENT_ID_MSG = messages
0861:                            .getString("ProfilerServer_IncorrectAgentIdMsg"); // NOI18N
0862:                    THREAD_EXCEPTION_MSG = messages
0863:                            .getString("ProfilerServer_ThreadExceptionMsg"); // NOI18N
0864:                    THREAD_WAIT_EXCEPTION_MSG = messages
0865:                            .getString("ProfilerServer_ThreadWaitExceptionMsg"); // NOI18N
0866:                    resourcesInitialized = true;
0867:                }
0868:            }
0869:
0870:            static void loadNativeLibrary(String fullJFluidPath,
0871:                    boolean fullPathToLibSpecified) {
0872:                String libFullName = Platform.getAgentNativeLibFullName(
0873:                        fullJFluidPath, fullPathToLibSpecified, null, -1);
0874:                System.load(libFullName);
0875:            }
0876:
0877:            static boolean startProfilingPointsActive() {
0878:                if (status != null) {
0879:                    return status.startProfilingPointsActive;
0880:                }
0881:
0882:                return false;
0883:            }
0884:
0885:            private static File getInfoFile(int port) throws IOException {
0886:                String dirName = Platform.getProfilerUserDir();
0887:
0888:                return new File(dirName + File.separator + port); // NOI18N
0889:            }
0890:
0891:            private static void setShutdownOK() {
0892:                synchronized (shutdownLock) {
0893:                    shutdownOK = true;
0894:                    shutdownLock.notifyAll();
0895:                }
0896:            }
0897:
0898:            private static void cleanupOnShutdown() {
0899:                ProfilerInterface.disableProfilerHooks();
0900:                ProfilerRuntimeCPU.enableProfiling(false); // Bugfix for 65947: Profiler blocks a finishing profiled application
0901:                // The following connectionOpen = false is done just to prevent error message from listenToClient(). When the connection
0902:                // is closed either by the client or here by closeConnection(), whoever is faster, listenToClient() waiting for input in socket
0903:                // will get IOException.
0904:                // Be careful with this! sendResponseToClient() currently doesn't check connectionOpen value, but if it does, this should be changed.
0905:
0906:                connectionOpen = false;
0907:                profilerServer
0908:                        .sendSimpleCmdToClient(Command.SHUTDOWN_COMPLETED);
0909:                profilerServer.closeConnection();
0910:            }
0911:
0912:            private static void delay(int ms) {
0913:                try {
0914:                    Thread.sleep(ms);
0915:                } catch (InterruptedException e) {
0916:                }
0917:            }
0918:
0919:            /**
0920:             * Note that putting the code of this into the custom thread above and thus executing in "attach and startup"
0921:             * in a separate thread as well, causes the VM to crash. Probably a new thread can't be created in a call from
0922:             * pre-main function.
0923:             *
0924:             * @param activateCode ATTACH_DYNAMIC or ATTACH_DIRECT
0925:             * @see #ATTACH_DYNAMIC
0926:             * @see #ATTACH_DIRECT
0927:             */
0928:            private static void doActivate(int activateCode) {
0929:                loadNativeLibrary(_fullJFluidPath, false);
0930:
0931:                ProfilerInterface.disableProfilerHooks(); // Just in case
0932:                initInternals();
0933:
0934:                // Start the communication thread and wait for it to establish connection with client
0935:                profilerServer = new ProfilerServer(_portNo,
0936:                        activateCode == ATTACH_DYNAMIC, _timeOut);
0937:                profilerServer.start();
0938:
0939:                while (!(connectionOpen || connectionFailed)) {
0940:                    delay(100);
0941:                }
0942:
0943:                if (connectionFailed) {
0944:                    if (activateCode == ATTACH_DIRECT) {
0945:                        System.exit(-1);
0946:                    } else {
0947:                        return; // in dynamic attach we just continue with execution
0948:                    }
0949:                }
0950:
0951:                ProfilerInterface.setProfilerServer(profilerServer);
0952:
0953:                initSupportingFunctionality(true, profilerServer
0954:                        .isRemoteProfiling());
0955:
0956:                if (_activateCode == ATTACH_DIRECT) {
0957:                    // "Attach on startup", where we normally wait until the initiate instrumentation request arrives and instrumentation starts.
0958:                    // However, the user can also choose to resume the target app without any instrumentation
0959:                    while ((ProfilerInterface.getCurrentInstrType() == INSTR_NONE)
0960:                            && !status.targetAppRunning) {
0961:                        delay(200);
0962:                    }
0963:
0964:                    delay(100); // Wait a bit more to make sure the classLoadHook is really set
0965:                }
0966:
0967:                status.targetAppRunning = true;
0968:            }
0969:
0970:            private static void forcedShutdown() {
0971:                cleanupOnShutdown();
0972:                preemptExit = false;
0973:                System.exit(-1);
0974:            }
0975:
0976:            private static void initInternals() {
0977:                shutdownWaitThread = new ShutdownWaitThread();
0978:                Runtime.getRuntime().addShutdownHook(shutdownWaitThread);
0979:                profilerInterfaceInitialized = false;
0980:                connectionOpen = false;
0981:                connectionFailed = false;
0982:                detachCommandReceived = false;
0983:                profilerServer = null;
0984:                status = null;
0985:                startTargetApp = false;
0986:                startupException = null;
0987:                targetAppRunningLock = new Object();
0988:                execInSeparateThreadLock = new Object();
0989:
0990:                // Preload this class, to avoid possible strange problems that may happen in case of wire protocol errors, that in
0991:                // turn may cause loading of this class, that in turn may invoke classLoadHook, etc.
0992:                try {
0993:                    Class.forName("java.net.SocketException"); // NOI18N
0994:                } catch (ClassNotFoundException ex) { /* Shouldn't happen */
0995:                }
0996:
0997:                // Preload this class, to avoid possible strange problems that happen during Entire App CPU profiling of tomcat,
0998:                // where classLoadHook is invoked during processing GET_DEFINING_CLASSLOADER request
0999:                try {
1000:                    Class.forName("java.util.AbstractList$Itr"); // NOI18N
1001:                } catch (ClassNotFoundException ex) { /* Shouldn't happen */
1002:                }
1003:
1004:                ThreadInfo.clearProfilerServerThreads();
1005:            }
1006:
1007:            /**
1008:             * Called after the connection with the tool is established, i.e. we know that we are connected, in which mode
1009:             * (attached or called directly) and whether it's local or remote connection.
1010:             */
1011:            private static void initSupportingFunctionality(
1012:                    boolean inAttachedMode, boolean remoteProfiling) {
1013:                status = new ProfilingSessionStatus();
1014:                status.runningInAttachedMode = inAttachedMode;
1015:                status.remoteProfiling = remoteProfiling;
1016:                status.targetJDKVersionString = Platform.getJDKVersionString();
1017:
1018:                Monitors.initialize(); // Initialize before initProfilerInterface to get monitor thread(s) recorded as system thread(s)
1019:                // Also initialize before initProfilerInterface, same purpose
1020:
1021:                profilerServer.initSeparateCmdExecutionThread();
1022:                ThreadInfo.addProfilerServerThread(shutdownWaitThread);
1023:                // Profiler interface initialization includes recording profiler's own threads (all currently running threads minus the
1024:                // current thread, since it will become the target app's main thread).
1025:                ProfilerInterface.initProfilerInterface(status,
1026:                        inAttachedMode ? profilerServer : Thread
1027:                                .currentThread());
1028:
1029:                // This is to preload some classes that can otherwise be loaded at inappropriate time and cause class load hook firing.
1030:                if (remoteProfiling) {
1031:                    ClassBytesLoader.preloadClasses();
1032:                }
1033:
1034:                profilerInterfaceInitialized = true;
1035:            }
1036:
1037:            private static void pressEnterToShutDown() {
1038:                // Make sure any excessive previous input doesn't cause us to shut down immediately
1039:                try {
1040:                    while (System.in.available() > 0) {
1041:                        System.in.read();
1042:                    }
1043:                } catch (IOException ex) {
1044:                    // ignore
1045:                }
1046:
1047:                System.out.println(ENTER_TO_SHUTDOWN_MSG); // NOI18N
1048:
1049:                try {
1050:                    System.in.read();
1051:                } catch (IOException ex) {
1052:                    // ignore
1053:                }
1054:            }
1055:
1056:            private static void runTargetApp(String mainClassName,
1057:                    String[] mainArgs) {
1058:                Class targetMainClass = null;
1059:
1060:                try {
1061:                    targetMainClass = ClassLoader.getSystemClassLoader()
1062:                            .loadClass(mainClassName);
1063:                } catch (ClassNotFoundException ex) {
1064:                    startupException = ex;
1065:                    System.err.println(ex);
1066:
1067:                    return;
1068:                }
1069:
1070:                // For the reasons I don't quite understand, if the main class is not public, then somewhere (when we attempt to invoke the
1071:                // main method using reflection?) we get the following: "java.lang.IllegalAccessException: Class org.netbeans.lib.profiler.server.ProfilerServer
1072:                // can not access a member of class Test with modifiers "public static"". Thus we have to run the below preemptive check. Hope this is not
1073:                // a problem for the majority of our users...
1074:                if (!Modifier.isPublic(targetMainClass.getModifiers())) {
1075:                    startupException = new IllegalAccessException(MessageFormat
1076:                            .format(MAIN_CLASS_NOT_PUBLIC_MSG,
1077:                                    new Object[] { targetMainClass })); // NOI18N
1078:                    System.err.println(startupException);
1079:
1080:                    return;
1081:                }
1082:
1083:                Method targetMainMethod = null;
1084:                Class[] params = new Class[] { String[].class };
1085:
1086:                try {
1087:                    targetMainMethod = targetMainClass.getDeclaredMethod(
1088:                            "main", params); // NOI18N
1089:                } catch (NoSuchMethodException ex) {
1090:                    startupException = ex;
1091:                    System.err.println(ex);
1092:
1093:                    return;
1094:                }
1095:
1096:                // Check for correct method modifiers, to (hopefully) avoid IllegalAccessException and IllegalArgumentException
1097:                int mod = targetMainMethod.getModifiers();
1098:
1099:                if (!(Modifier.isPublic(mod) && Modifier.isStatic(mod))
1100:                        || Modifier.isAbstract(mod)
1101:                        || Modifier.isInterface(mod)) {
1102:                    startupException = new IllegalAccessException(MessageFormat
1103:                            .format(INCORRECT_MAIN_MODIFIERS_MSG,
1104:                                    new Object[] { targetMainClass })); // NOI18N
1105:                    System.err.println(startupException);
1106:
1107:                    return;
1108:                }
1109:
1110:                // We hope after our checks the only exceptions that can be thrown by the target app are those that it generates for
1111:                // natural reasons, and which we should not report as "failed to start the application"
1112:                status.targetAppRunning = true;
1113:
1114:                synchronized (targetAppRunningLock) {
1115:                    targetAppRunningLock.notify();
1116:                }
1117:
1118:                long startTime = Timers.getCurrentTimeInCounts();
1119:
1120:                try {
1121:                    targetMainMethod.invoke(targetMainClass,
1122:                            new Object[] { mainArgs });
1123:                } catch (IllegalAccessException e1) {
1124:                    startupException = e1;
1125:                    System.err.println(e1);
1126:                } catch (IllegalArgumentException e2) {
1127:                    startupException = e2;
1128:                    System.err.println(e2);
1129:                } catch (InvocationTargetException e3) {
1130:                    Throwable cause = e3.getCause();
1131:
1132:                    if (cause != null) {
1133:                        cause.printStackTrace(System.err);
1134:                    } else { // Can this ever happen?
1135:                        internalError("Target application threw a null exception?"); // NOI18N
1136:                    }
1137:                } catch (Throwable ex) {
1138:                    ProfilerInterface.disableProfilerHooks();
1139:                    internalError(MessageFormat.format(
1140:                            UNEXPECTED_EXCEPTION_MSG, new Object[] { ex }),
1141:                            false); // NOI18N
1142:                    ex.printStackTrace(System.err);
1143:                } finally {
1144:                    int elapsedTime = (int) (((Timers.getCurrentTimeInCounts() - startTime) * 1000) / Timers
1145:                            .getNoOfCountsInSecond());
1146:                    System.out.println(MessageFormat.format(ELAPSED_TIME_MSG,
1147:                            new Object[] { "" + elapsedTime })); // NOI18N
1148:                }
1149:            }
1150:
1151:            private static void waitForShutdownOK() {
1152:                synchronized (shutdownLock) {
1153:                    while (!shutdownOK && !Thread.interrupted()) {
1154:                        try {
1155:                            shutdownLock.wait(500);
1156:                        } catch (InterruptedException e) {
1157:                        }
1158:
1159:                        Thread.yield();
1160:                    }
1161:
1162:                    if (shutdownOK) {
1163:                        return;
1164:                    }
1165:                }
1166:
1167:                System.err
1168:                        .println("ProfilerServer hasn't shut down cleanly. Terminated."); // NOI18N
1169:
1170:                //    while (true) {
1171:                //      if (shutdownOK) {
1172:                //        return;
1173:                //      }
1174:                //      delay(100);
1175:                //    }
1176:            }
1177:
1178:            private int getAgentId() {
1179:                if (agentId == -1) {
1180:                    String id = System.getProperty("nbprofiler.agentid"); // NOI18N
1181:
1182:                    if (id != null) {
1183:                        try {
1184:                            agentId = Integer.parseInt(id);
1185:                        } catch (NumberFormatException e) {
1186:                            System.err.println(MessageFormat
1187:                                    .format(INCORRECT_AGENT_ID_MSG,
1188:                                            new Object[] { id })); // NOI18N
1189:                            // ignore, the agentId will be generated randomly
1190:                        }
1191:                    }
1192:
1193:                    if (agentId == -1) {
1194:                        agentId = (int) (Math.random() * (float) Integer.MAX_VALUE);
1195:                    }
1196:                }
1197:
1198:                return agentId;
1199:            }
1200:
1201:            private static void setLastResponse(Response r) {
1202:                synchronized (responseLock) {
1203:                    lastResponse = r;
1204:
1205:                    try {
1206:                        responseLock.notify();
1207:                    } catch (IllegalMonitorStateException ex) {
1208:                        internalError("IllegalMonitorState in ProfilerServer.setLastResponse()"); // NOI18N
1209:                    }
1210:                }
1211:            }
1212:
1213:            private static String getLocalizedJFluidServerJar(
1214:                    String jfluidServerDir) {
1215:                String localizedJFluidServerJar = null;
1216:
1217:                // normalize provided directory to use forward slashes with slash at the end of path
1218:                String baseDir = jfluidServerDir.replace('\\', '/'); // NOI18N
1219:
1220:                if (!baseDir.endsWith("/")) { // NOI18N
1221:                    baseDir = baseDir + "/"; // NOI18N
1222:                }
1223:
1224:                // check if directory exists
1225:                File baseDirF = new File(baseDir);
1226:
1227:                if (!baseDirF.exists() || !baseDirF.isDirectory()) {
1228:                    return null;
1229:                }
1230:
1231:                // check if locale directory exists
1232:                String localeDir = baseDir + "locale/"; // NOI18N
1233:                File localeDirF = new File(localeDir);
1234:
1235:                if (localeDirF.exists() && localeDirF.isDirectory()) {
1236:                    // locale directory found, try to find jar inside
1237:                    localizedJFluidServerJar = getLocalizedJFluidServerJarInDir(localeDir);
1238:
1239:                    if (localizedJFluidServerJar != null) {
1240:                        return localizedJFluidServerJar;
1241:                    }
1242:                }
1243:
1244:                // locale directory doesn't exist or jar not found in it, try to find jar directly in jfluid dir
1245:                localizedJFluidServerJar = getLocalizedJFluidServerJarInDir(baseDir);
1246:
1247:                return localizedJFluidServerJar;
1248:            }
1249:
1250:            private static String getLocalizedJFluidServerJarInDir(
1251:                    String jfluidServerLocaleDir) {
1252:                LocaleIterator localeIterator = new LocaleIterator(Locale
1253:                        .getDefault());
1254:                String jarFile;
1255:                File jarFileF;
1256:
1257:                while (localeIterator.hasNext()) {
1258:                    jarFile = jfluidServerLocaleDir + "jfluid-server"
1259:                            + localeIterator.next() + ".jar"; // NOI18N
1260:                    jarFileF = new File(jarFile);
1261:
1262:                    if (jarFileF.exists() && jarFileF.isFile()) {
1263:                        return jarFile;
1264:                    }
1265:                }
1266:
1267:                return null;
1268:            }
1269:
1270:            // Does not support branding!
1271:            private static ResourceBundle getProfilerServerResourceBundle(
1272:                    String jfluidPath) {
1273:                ResourceBundle bundle = null;
1274:
1275:                if (jfluidPath == null) {
1276:                    throw new RuntimeException(
1277:                            "ProfilerServer: Unable to initialize ResourceBundle for ProfilerServer, " // NOI18N
1278:                                    + "cannot find path to Profiler libraries" // NOI18N
1279:                    );
1280:                }
1281:
1282:                String jfluidServerJar = getLocalizedJFluidServerJar(jfluidPath);
1283:
1284:                if (jfluidServerJar == null) {
1285:                    throw new RuntimeException(
1286:                            "ProfilerServer: Unable to initialize ResourceBundle for ProfilerServer, " // NOI18N
1287:                                    + "cannot find localized jfluid-server.jar" // NOI18N
1288:                    );
1289:                }
1290:
1291:                try {
1292:                    if (!jfluidServerJar.startsWith("/")) {
1293:                        jfluidServerJar = "/" + jfluidServerJar; // NOI18N
1294:                    }
1295:
1296:                    String bundleJarURLPath = "jar:file:" + jfluidServerJar
1297:                            + "!/"; // NOI18N
1298:                    URLClassLoader loader = new URLClassLoader(
1299:                            new URL[] { new URL(bundleJarURLPath) });
1300:                    bundle = ResourceBundle.getBundle(
1301:                            "org.netbeans.lib.profiler.server.Bundle", Locale
1302:                                    .getDefault(), loader); // NOI18N
1303:                } catch (Exception e2) {
1304:                    throw new RuntimeException(
1305:                            "ProfilerServer: Unable to initialize ResourceBundle for ProfilerServer\n"
1306:                                    + e2.getMessage() // NOI18N
1307:                    );
1308:                }
1309:
1310:                if (bundle == null) {
1311:                    throw new RuntimeException(
1312:                            "ProfilerServer: Unable to initialize ResourceBundle for ProfilerServer" // NOI18N
1313:                    );
1314:                }
1315:
1316:                return bundle;
1317:            }
1318:
1319:            private synchronized void closeConnection() {
1320:                connectionOpen = false;
1321:                status.targetAppRunning = false;
1322:                removeInfoFile();
1323:
1324:                try {
1325:                    socketOut.close();
1326:                    socketIn.close();
1327:                    clientSocket.close();
1328:                    serverSocket.close();
1329:                } catch (IOException ex) {
1330:                }
1331:
1332:                if (status.runningInAttachedMode) {
1333:                    System.out.println(CONNECTION_CLOSED_MSG);
1334:                }
1335:
1336:                preemptExit = false;
1337:            }
1338:
1339:            private boolean connectToClient() {
1340:                try {
1341:                    if (serverTimeout == 0) {
1342:                        System.out
1343:                                .println(MessageFormat
1344:                                        .format(
1345:                                                WAITING_ON_PORT_MSG,
1346:                                                new Object[] {
1347:                                                        "" + serverPort, // NOI18N
1348:                                                        ""
1349:                                                                + CommonConstants.CURRENT_AGENT_VERSION // NOI18N
1350:                                                }));
1351:                    } else {
1352:                        System.out
1353:                                .println(MessageFormat
1354:                                        .format(
1355:                                                WAITING_ON_PORT_TIMEOUT_MSG,
1356:                                                new Object[] {
1357:                                                        "" + serverPort, // NOI18N
1358:                                                        "" + serverTimeout, // NOI18N
1359:                                                        ""
1360:                                                                + CommonConstants.CURRENT_AGENT_VERSION } // NOI18N
1361:                                        )); // NOI18N
1362:                    }
1363:
1364:                    serverSocket = new ServerSocket(serverPort);
1365:                    serverSocket.setSoTimeout(serverTimeout * 1000); // serverTimeout is in seconds
1366:                    createInfoFile();
1367:                    clientSocket = serverSocket.accept();
1368:                    clientSocket.setTcpNoDelay(true); // Necessary at least on Solaris to avoid delays in e.g. readInt() etc.
1369:                    socketIn = new ObjectInputStream(clientSocket
1370:                            .getInputStream());
1371:                    socketOut = new ObjectOutputStream(clientSocket
1372:                            .getOutputStream());
1373:                    wireIO = new WireIO(socketOut, socketIn);
1374:                    connectionOpen = true;
1375:
1376:                    return true;
1377:                } catch (SocketTimeoutException ex) {
1378:                    System.err.println(CONNECTION_TIMEOUT_MSG); // NOI18N
1379:                    connectionFailed = true;
1380:                } catch (IOException ex) {
1381:                    System.err.println(MessageFormat.format(
1382:                            CONNECTION_EXCEPTION_MSG, new Object[] { ex })); // NOI18N
1383:                    connectionFailed = true;
1384:                } finally {
1385:                    //removeInfoFile ();
1386:                }
1387:
1388:                return false;
1389:            }
1390:
1391:            private void createInfoFile() {
1392:                BufferedOutputStream bos = null;
1393:
1394:                try {
1395:                    File f = getInfoFile(serverPort);
1396:                    f.createNewFile();
1397:                    f.deleteOnExit();
1398:
1399:                    Properties props = new Properties();
1400:                    props.setProperty("dynamic", Boolean.toString(dynamic)); // NOI18N
1401:                    props.setProperty("working.dir", System
1402:                            .getProperty("user.dir")); // NOI18N
1403:                    props.setProperty("agent.id", Integer
1404:                            .toString(getAgentId())); // NOI18N
1405:                    props.setProperty("java.version", System
1406:                            .getProperty("java.version")); // NOI18N
1407:
1408:                    FileOutputStream fos = new FileOutputStream(f);
1409:                    bos = new BufferedOutputStream(fos);
1410:
1411:                    props.store(bos, ""); // NOI18N
1412:
1413:                    bos.close();
1414:                } catch (IOException e) {
1415:                    System.err.println(MessageFormat.format(AGENT_ERROR_MSG,
1416:                            new Object[] { e.getMessage() })); // NOI18N
1417:                } finally {
1418:                    if (bos != null) {
1419:                        try {
1420:                            bos.close();
1421:                        } catch (IOException e) {
1422:                            e.printStackTrace();
1423:                        }
1424:                    }
1425:                }
1426:            }
1427:
1428:            /**
1429:             * Some of the commands need to be executed in a separate thread, because they result in the server sending something
1430:             * to the client and awaiting its response. The response, in turn, can only be picked up by the single JFluid communication
1431:             * thread. So we execute these commands in a separate thread to allow the main communication thread to return immediately,
1432:             * and be ready to process client's response.
1433:             */
1434:            private void executeInSeparateThread(int opCode) {
1435:                synchronized (execInSeparateThreadLock) {
1436:                    execInSeparateThreadOpCode = opCode;
1437:
1438:                    try {
1439:                        execInSeparateThreadLock.notify();
1440:                    } catch (IllegalMonitorStateException ex) {
1441:                        System.err.println(THREAD_EXCEPTION_MSG); // NOI18N
1442:                    }
1443:                }
1444:            }
1445:
1446:            //---------------------------------------------------------------------------------------
1447:            // Command/response handling
1448:            //---------------------------------------------------------------------------------------
1449:            private void handleClientCommand(Command cmd) {
1450:                //System.out.println(">>> Got command " + cmd);
1451:                if (cmd.getType() == Command.START_TARGET_APP) {
1452:                    if (status.runningInAttachedMode) {
1453:                        // This is a special case - the user has chosen "Attach on startup" and then "resume application without instrumentation"
1454:                        status.targetAppRunning = true;
1455:                        sendSimpleResponseToClient(true, null);
1456:
1457:                        return;
1458:                    }
1459:
1460:                    // Start target app is handled by a separate thread, since we want to return to the client a synchronous response telling
1461:                    // whether or not the target app was started successfully. To get an answer to this question, we have to wait until the main
1462:                    // class is loaded, its main method is found, etc. Only after that the targetAppRunningLock.notify() is called. Until then
1463:                    // this thread remains blocked. However, if instrumentation root method == main method, class load hook is invoked immediately
1464:                    // when the main class is loaded. Class load hook, in turn, sends a RootClassLoaded command to the server and waits for the
1465:                    // response. But responses are read by the same thread that calls handleClientCommand(). So if we do the below operations in
1466:                    // the same thread, we deadlock - so, a separate thread is needed to allow the main listener thread to handle incoming
1467:                    // commands/responses immediately.
1468:                    class MyThread extends Thread {
1469:                        MyThread() {
1470:                            ThreadInfo.addProfilerServerThread(this );
1471:                            this .setName(PROFILER_SPECIAL_EXEC_THREAD_NAME
1472:                                    + " 4"); // NOI18N
1473:                        }
1474:
1475:                        public void run() {
1476:                            synchronized (targetAppRunningLock) {
1477:                                startTargetApp = true;
1478:
1479:                                try {
1480:                                    targetAppRunningLock.wait();
1481:                                } catch (InterruptedException ex) {
1482:                                    internalError("START_TARGET_APP");
1483:                                } // NOI18N
1484:                            }
1485:
1486:                            if (startupException != null) {
1487:                                sendSimpleResponseToClient(false,
1488:                                        startupException.toString());
1489:                            } else {
1490:                                sendSimpleResponseToClient(true, null);
1491:                            }
1492:
1493:                            ThreadInfo.removeProfilerServerThread(this );
1494:                        }
1495:                    }
1496:                    new MyThread().start();
1497:
1498:                    return;
1499:                }
1500:
1501:                switch (cmd.getType()) {
1502:                case Command.GET_MONITORED_NUMBERS:
1503:                    sendComplexResponseToClient(Monitors.getMonitoredNumbers());
1504:
1505:                    break;
1506:                case Command.INITIATE_INSTRUMENTATION:
1507:
1508:                    // Bugfix 69645: Take snapshot is not enabled after modifying profiling from CPU to memory
1509:                    // http://profiler.netbeans.org/issues/show_bug.cgi?id=69645
1510:                    synchronized (resultsNotifiedLock) {
1511:                        resultsNotified = false;
1512:                    }
1513:
1514:                    try {
1515:                        ProfilerInterface.initiateInstrumentation(
1516:                                (InitiateInstrumentationCommand) cmd,
1517:                                status.targetAppRunning);
1518:                        sendSimpleResponseToClient(true, null);
1519:                    } catch (Exception ex) {
1520:                        sendSimpleResponseToClient(false, ex.getMessage());
1521:                    }
1522:
1523:                    break;
1524:                case Command.INSTRUMENT_METHOD_GROUP:
1525:                    class InstrumentMethodGroupThread extends Thread {
1526:                        final InstrumentMethodGroupCommand methodGroupCmd;
1527:                        String exceptionString;
1528:
1529:                        InstrumentMethodGroupThread(
1530:                                InstrumentMethodGroupCommand cmd) {
1531:                            ThreadInfo.addProfilerServerThread(this );
1532:                            setName(PROFILER_SPECIAL_EXEC_THREAD_NAME + " 8"); // NOI18N
1533:                            methodGroupCmd = cmd;
1534:                        }
1535:
1536:                        public void run() {
1537:                            try {
1538:                                ProfilerInterface
1539:                                        .instrumentMethods(methodGroupCmd);
1540:                            } catch (Exception ex) {
1541:                                exceptionString = ex.getLocalizedMessage();
1542:                            }
1543:
1544:                            ThreadInfo.removeProfilerServerThread(this );
1545:                        }
1546:                    }
1547:
1548:                    InstrumentMethodGroupThread instrumentMethodGroupThread = new InstrumentMethodGroupThread(
1549:                            (InstrumentMethodGroupCommand) cmd);
1550:                    instrumentMethodGroupThread.start();
1551:
1552:                    while (instrumentMethodGroupThread.isAlive()) {
1553:                        delay(2000);
1554:                        sendSimpleCmdToClient(Command.STILL_ALIVE);
1555:                    }
1556:
1557:                    if (instrumentMethodGroupThread.exceptionString != null) {
1558:                        sendSimpleResponseToClient(false,
1559:                                instrumentMethodGroupThread.exceptionString);
1560:                    } else {
1561:                        sendSimpleResponseToClient(true, null);
1562:                    }
1563:
1564:                    break;
1565:                case Command.CHECK_CONNECTION:
1566:                    sendSimpleResponseToClient(true, null);
1567:
1568:                    break;
1569:                case Command.SET_CHANGEABLE_INSTR_PARAMS:
1570:
1571:                    SetChangeableInstrParamsCommand scipCmd = (SetChangeableInstrParamsCommand) cmd;
1572:                    ProfilerRuntimeCPU.setNProfiledThreadsLimit(scipCmd
1573:                            .getNProfiledThreadsLimit());
1574:                    ProfilerRuntimeCPUSampledInstr.setSamplingInterval(scipCmd
1575:                            .getSamplingInterval());
1576:                    ProfilerRuntimeMemory.setSamplingInterval((short) scipCmd
1577:                            .getObjAllocStackSamplingInterval());
1578:                    ProfilerRuntimeMemory.setSamplingDepth(scipCmd
1579:                            .getObjAllocStackSamplingDepth());
1580:                    ProfilerRuntimeObjLiveness.setRunGCOnGetResults(scipCmd
1581:                            .getRunGCOnGetResultsInMemoryProfiling());
1582:                    Classes.setWaitTrackingEnabled(scipCmd
1583:                            .getWaitTrackingEnabled());
1584:                    Classes.setSleepTrackingEnabled(scipCmd
1585:                            .getSleepTrackingEnabled());
1586:                    sendSimpleResponseToClient(true, null);
1587:
1588:                    break;
1589:                case Command.SET_UNCHANGEABLE_INSTR_PARAMS:
1590:
1591:                    SetUnchangeableInstrParamsCommand sucipCmd = (SetUnchangeableInstrParamsCommand) cmd;
1592:                    ProfilerRuntimeCPU.setTimerTypes(sucipCmd
1593:                            .getAbsoluteTimerOn(), sucipCmd
1594:                            .getThreadCPUTimerOn());
1595:                    status.instrScheme = sucipCmd.getInstrScheme();
1596:                    ProfilerRuntimeCPUCodeRegion.setCPUResBufSize(sucipCmd
1597:                            .getCodeRegionCPUResBufSize());
1598:                    sendSimpleResponseToClient(true, null);
1599:
1600:                    break;
1601:                case Command.CPU_RESULTS_EXIST:
1602:                    sendSimpleResponseToClient(ProfilerInterface
1603:                            .cpuResultsExist(), null);
1604:
1605:                    break;
1606:                case Command.DUMP_EXISTING_RESULTS:
1607:                case Command.DUMP_EXISTING_RESULTS_LIVE:
1608:                    // We have to execute the dump in a separate thread to make this call (handleClientCommand()) return immediately.
1609:                    // Otherwise, it would not allow the server to receive a response from the client, that the client sends when it
1610:                    // processes the dumped results. Generally, all commands that may call ProfilerRuntime.dumpEventBuffer() should be
1611:                    // executed in a separate thread.
1612:                    executeInSeparateThread(cmd.getType());
1613:
1614:                    break;
1615:                case Command.GET_CODE_REGION_CPU_RESULTS:
1616:                    sendComplexResponseToClient(ProfilerInterface
1617:                            .getCodeRegionCPUResults());
1618:
1619:                    break;
1620:                case Command.GET_OBJECT_ALLOCATION_RESULTS:
1621:                    sendComplexResponseToClient(ProfilerInterface
1622:                            .getObjectAllocationResults());
1623:
1624:                    break;
1625:                case Command.GET_METHOD_NAMES_FOR_JMETHOD_IDS:
1626:
1627:                    GetMethodNamesForJMethodIdsCommand gmnCmd = (GetMethodNamesForJMethodIdsCommand) cmd;
1628:                    sendComplexResponseToClient(ProfilerInterface
1629:                            .getMethodNamesForJMethodIds(gmnCmd.getMethodIds()));
1630:
1631:                    break;
1632:                case Command.RESET_PROFILER_COLLECTORS:
1633:
1634:                    synchronized (resultsNotifiedLock) {
1635:                        resultsNotified = false;
1636:                    }
1637:
1638:                    // Since the resetProfilerCollectors() eventually invokes the dump results method, which in turn sends a command to the client
1639:                    // and awaits response, we have to execute it in a separate thread. See comments in DUMP_EXISTING_RESULTS above.
1640:                    executeInSeparateThread(cmd.getType());
1641:
1642:                    break;
1643:                case Command.DEACTIVATE_INJECTED_CODE:
1644:                    ProfilerInterface.deactivateInjectedCode();
1645:                    sendSimpleResponseToClient(true, null);
1646:
1647:                    break;
1648:                case Command.GET_THREAD_LIVENESS_STATUS:
1649:                    sendComplexResponseToClient(ProfilerInterface
1650:                            .getCurrentThreadLivenessStatus());
1651:
1652:                    break;
1653:                case Command.SUSPEND_TARGET_APP:
1654:                    ProfilerInterface.suspendTargetApp();
1655:                    sendSimpleResponseToClient(true, null);
1656:
1657:                    break;
1658:                case Command.RESUME_TARGET_APP:
1659:                    ProfilerInterface.resumeTargetApp();
1660:                    sendSimpleResponseToClient(true, null);
1661:
1662:                    break;
1663:                case Command.TERMINATE_TARGET_JVM:
1664:
1665:                    if (ProfilerInterface.getCurrentInstrType() != INSTR_NONE) {
1666:                        ProfilerInterface.deactivateInjectedCode();
1667:                    }
1668:
1669:                    sendSimpleResponseToClient(true, null);
1670:                    closeConnection();
1671:                    preemptExit = false;
1672:                    System.exit(-1);
1673:
1674:                    break;
1675:                case Command.SHUTDOWN_OK:
1676:                    setShutdownOK();
1677:
1678:                    break;
1679:                case Command.INSTRUMENT_REFLECTION:
1680:                    ProfilerInterface.setInstrumentReflection(true);
1681:                    sendSimpleResponseToClient(true, null);
1682:
1683:                    break;
1684:                case Command.DEINSTRUMENT_REFLECTION:
1685:                    ProfilerInterface.setInstrumentReflection(false);
1686:                    sendSimpleResponseToClient(true, null);
1687:
1688:                    break;
1689:                case Command.RUN_GC:
1690:                    GC.runGC();
1691:                    sendSimpleResponseToClient(true, null);
1692:
1693:                    break;
1694:                case Command.GET_DEFINING_CLASS_LOADER: {
1695:                    GetDefiningClassLoaderCommand gdclCmd = (GetDefiningClassLoaderCommand) cmd;
1696:                    int loaderId = ClassLoaderManager
1697:                            .getDefiningLoaderForClass(gdclCmd.getClassName(),
1698:                                    gdclCmd.getClassLoaderId());
1699:                    DefiningLoaderResponse resp = new DefiningLoaderResponse(
1700:                            loaderId);
1701:                    sendComplexResponseToClient(resp);
1702:
1703:                    break;
1704:                }
1705:                case Command.GET_VM_PROPERTIES: {
1706:                    status.jvmArguments = Threads.getJVMArguments();
1707:                    status.javaCommand = Threads.getJavaCommand();
1708:
1709:                    VMPropertiesResponse resp = new VMPropertiesResponse(System
1710:                            .getProperty("java.version"), // NOI18N
1711:                            System.getProperty("java.class.path"), // NOI18N
1712:                            System.getProperty("java.ext.dirs"), // NOI18N
1713:                            System.getProperty("sun.boot.class.path"), // NOI18N
1714:                            System.getProperty("user.dir"), // NOI18N
1715:                            status.jvmArguments, status.javaCommand, System
1716:                                    .getProperty("os.name"), // NOI18N
1717:                            Runtime.getRuntime().maxMemory(), System
1718:                                    .currentTimeMillis(), Timers
1719:                                    .getCurrentTimeInCounts(), getAgentId() // NOI18N
1720:                    ); // NOI18N
1721:                    sendComplexResponseToClient(resp);
1722:
1723:                    break;
1724:                }
1725:                case Command.GET_STORED_CALIBRATION_DATA: { // called in the beginning of remote CPU profiling
1726:
1727:                    int ret = CalibrationDataFileIO
1728:                            .readSavedCalibrationData(status);
1729:
1730:                    if (ret == 0) {
1731:                        CalibrationDataResponse resp = new CalibrationDataResponse(
1732:                                status.methodEntryExitCallTime,
1733:                                status.methodEntryExitInnerTime,
1734:                                status.methodEntryExitOuterTime,
1735:                                status.timerCountsInSecond);
1736:                        profilerServer.sendComplexResponseToClient(resp);
1737:                    } else {
1738:                        sendSimpleResponseToClient(false, CalibrationDataFileIO
1739:                                .getErrorMessage());
1740:                    }
1741:
1742:                    break;
1743:                }
1744:                case Command.RUN_CALIBRATION_AND_GET_DATA: {
1745:                    ProfilerCalibrator.init(status);
1746:                    ProfilerCalibrator.measureBCIOverhead(false);
1747:
1748:                    CalibrationDataResponse resp = new CalibrationDataResponse(
1749:                            status.methodEntryExitCallTime,
1750:                            status.methodEntryExitInnerTime,
1751:                            status.methodEntryExitOuterTime,
1752:                            status.timerCountsInSecond);
1753:                    profilerServer.sendComplexResponseToClient(resp);
1754:
1755:                    break;
1756:                }
1757:                case Command.GET_INTERNAL_STATS:
1758:                    ProfilerCalibrator.init(status);
1759:                    sendComplexResponseToClient(ProfilerCalibrator
1760:                            .getInternalStats());
1761:
1762:                    break;
1763:                case Command.DETACH:
1764:                    // Just in case, normally should be deactivated and cleaned up by client
1765:                    ProfilerInterface.deactivateInjectedCode();
1766:                    ProfilerInterface.disableProfilerHooks();
1767:                    ProfilerInterface.clearProfilerDataStructures();
1768:
1769:                    stopSeparateCmdExecutionThread();
1770:                    Monitors.shutdown();
1771:                    ThreadInfo.clearProfilerServerThreads();
1772:                    detachCommandReceived = true;
1773:                    sendSimpleResponseToClient(true, null);
1774:
1775:                    break;
1776:                case Command.TAKE_HEAP_DUMP:
1777:
1778:                    TakeHeapDumpCommand dumpCmd = (TakeHeapDumpCommand) cmd;
1779:                    String error = HeapDump.takeHeapDump(Platform
1780:                            .getJDKVersionNumber() == Platform.JDK_15, dumpCmd
1781:                            .getOutputFile());
1782:
1783:                    sendSimpleResponseToClient(error == null, error);
1784:
1785:                    break;
1786:                }
1787:            }
1788:
1789:            private void handleIOExceptionOnSend(IOException ex) {
1790:                System.err.println(MessageFormat.format(RESPONSE_EXCEPTION_MSG,
1791:                        new Object[] { ex })); // NOI18N
1792:                ex.printStackTrace(System.err);
1793:                closeConnection();
1794:            }
1795:
1796:            private void initSeparateCmdExecutionThread() {
1797:                separateCmdExecutionThread = new SeparateCmdExecutionThread();
1798:                separateCmdExecutionThread.start();
1799:            }
1800:
1801:            private static void internalError(String message) {
1802:                internalError(message, true);
1803:            }
1804:
1805:            private static void internalError(String message, boolean exit) {
1806:                System.err.println("Profiler Engine Error: " + message); // NOI18N
1807:
1808:                if (exit) {
1809:                    preemptExit = false;
1810:                    System.exit(-1);
1811:                }
1812:            }
1813:
1814:            private void listenToClient() {
1815:                while (connectionOpen && !detachCommandReceived) {
1816:                    try {
1817:                        Object o = wireIO.receiveCommandOrResponse();
1818:
1819:                        if (o == null) {
1820:                            System.err.println(CONNECTION_INTERRUPTED_MSG); // NOI18N
1821:
1822:                            break; // end of connection
1823:                        }
1824:
1825:                        //System.out.println(">>> Profiler Engine: received command or response " + o);
1826:                        if (o instanceof  Command) {
1827:                            handleClientCommand((Command) o);
1828:                        } else {
1829:                            setLastResponse((Response) o);
1830:                        }
1831:                    } catch (IOException ex) {
1832:                        if (connectionOpen && !detachCommandReceived) { // It is not an asynchronous connection shutdown
1833:                            System.err
1834:                                    .println(MessageFormat.format(
1835:                                            COMMAND_EXCEPTION_MSG,
1836:                                            new Object[] { ex })); // NOI18N
1837:                        }
1838:
1839:                        break;
1840:                    }
1841:                }
1842:
1843:                closeConnection();
1844:            }
1845:
1846:            private void removeInfoFile() {
1847:                try {
1848:                    getInfoFile(serverPort).delete();
1849:                } catch (IOException e) {
1850:                    System.err.println(MessageFormat.format(AGENT_ERROR_MSG,
1851:                            new Object[] { e.getMessage() })); // NOI18N
1852:                }
1853:            }
1854:
1855:            private void stopSeparateCmdExecutionThread() {
1856:                separateCmdExecutionThread.terminate();
1857:
1858:                synchronized (execInSeparateThreadLock) {
1859:                    try {
1860:                        execInSeparateThreadLock.notify();
1861:                    } catch (IllegalMonitorStateException ex) {
1862:                    }
1863:                }
1864:            }
1865:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.