I used to profile my Java applications with the TPTP Eclipse plugin. It was admittedly a nightmare to install, but once you had it running, it was a fairly efficient tool. Alas, to my dismay, I realized that TPTP is no more. The project was dropped from the latest Eclipse release train (Indigo). And of course, one week after the new Eclipse release, I have a need to profile a remote server.
There are a bunch of efficient solutions to profile a Java application locally (the easiest to use is certainly VisualVM). And as long as you have the possibility to profile your application locally, you should do it. However, there are situations when you have to profile a remote application. In these rare cases, I found the Netbeans was pretty efficient. Since I was a complete newbie in Netbeans (I'm more an Eclipse user), I'll write a complete tutorial to explain the steps to profile a remote application using Netbeans.
The example I give applies for JDK 5 and JDK 6.
The first step is obviously to install NetBeans. I used NetBeans 6.9 on Natty Narwal, but my understanding is that version 7.0 is quite close. Being on Ubuntu Natty Narwall, I just used:
sudo apt-get install netbeans
Once Netbeans is installed, you must start it and install the Profile plugins. To do this, go in Tools -> Plugins, then select Available Plugins -> Java Profiler.
In order to profile a remote application, it must be started with special parameters that will load special profiling classes called the "Remote Pack". You must create a "Remote Pack" for your server, but Netbeans will help you do that. First, in the Netbeans menu, click Profile -> Attach profiler....

In this profiler page, choose the type of profiling you want to do (Monitor / CPU or Memory). In the top section, select <External application> from the drop-down list. In the bottom section, there is an Attach mode parameter. Click to edit this parameter.

In "Target type", select "Application" (unless you are running a web application server). In "Attach method", select "Remote". Then click "Next".

The next screen is pretty obvious, you need to give your server's URL (or IP address), and the server OS. Please be sure to select the right OS, and pay special attention to the number of bits (32 and 64bits are not the same!). Then click "Next" twice.

Netbeans will display a page explaining how to install the "Remote pack" on your server. First, you need to select your exact JVM version on the server (JDK5, JDK6, etc...). Then click the "Generate Remote Pack..." button. This will generate a ZIP file that you will need to install on the remote server. Follow the install steps displayed in this screen, and restart your application with the additional parameters.
Basically, the steps you must do on the server are:
Everything is ok? Then start your application. If your changes worked correctly, your application should not start directly. Instead, it should display a message saying it is waiting for the profiler to connect. Go back to Netbeans, and start the profiler by clicking the "Attach" button.
The most useful profiling is the CPU profiling. It will tell you how much time your application spends in each function. But it will also slow down your application a lot.
For a moderately big application, with hundreds of classes and thousands of method (this can be common if you use many libraries), the profiler will "attach" to the methods in order to get traces of execution time. This can take a very long time (especially if your network connection between Netbeans and your remote host is not blazing fast). On some tests I performed, it took up to 30 minutes to get all the methods "instrumented". To gain some time, you should restrict the set of objects/methods to instrument. You can do this by analyzing a "Part of the application" in the profiler main window.

Also, we highly recommend to add as many filters as possible to opt-out classes from the instrumentation:

With those advices, you should be ready to start your own remote profiling. Happy optimizing!