Monday, March 24, 2008

JDB Example: Generating a Thread Dump

Every once in a while I run into a situation where the usual means for generating a thread dump (stack trace) does not work, making it difficult to track down pesky deadlocks. This seems somewhat more common under OSX, but I’ve seen it happen under Linux as well.

Typically you can type Control-&backslash; (Control-Break on Windows), or send a process the QUIT signal (e.g., kill -QUIT ) to dump a trace of all active threads in the Java VM. Intermittently, however, I have found that this does not work for java processes that are launched via a shell script. The Control-&backslash; is sometimes simply ignored, while the QUIT signal appears to kill the script, but without dumping a stack trace or killing the java process. (This suggests that in either case, the script is probably just intercepting the signal. There’s probably a fix for that, but I haven’t explored it.)

The jdb debugger utility, included as part of the JDK, provides an alternate way to get a stack trace. First, you must pass two additional arguments to the java vm to tell it to listen for connections from the java debugger. On OSX, Linux, or UNIX, this looks like:

java -Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n class 

This will cause the VM to listen for debugger connections on port 8000. You may use any usued port number that the account in which the program is running may listen. For non-priviledged accounts, this typically means any port number over 1024. For security reasons you might not want to include these options on a production system, but for testing and debugging they impose no measurable performance penalty.

As an example, here is a simple DeadlockDemo class that will produce a deadlock at some indeterminate point. It creates three threads, each of which will repeatedly try to randomly acquire two locks. When a thread successfully gets both locks, it will update a counter. Eventually two threads will try to acquire the same two locks in the opposite order, resulting in a deadlock. Deadlock situations are, of couse, not the only cases where stack traces are useful, but are probably the most common:

import java.awt.*;
import javax.swing.*;

/**
* Demo program that should (eventually) produce a deadlock
*/
public class DeadlockDemo extends JFrame implements Runnable {
/**
* Label with counter of iterations before deadlock
*/
private JLabel text = null;

/**
* Counter of number of updates
*/
private int count = 0;

/**
* Set of objects to randomly synchronize on
*/
private Object[] locks = null;

public DeadlockDemo() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
text = new JLabel("Starting up...", JLabel.CENTER);
setLayout(new BorderLayout());
add(text, BorderLayout.CENTER);

locks = new Object[] { new Object(), new Object(), new Object() };
}

public void startSomeThreads() {
for (int i = 0; i < 3; i++) {
Thread runner = new Thread(this);
runner.setName("Runner Thread " + i);
runner.start();
}
}

public void run() {
while (true) {
// Pick two locks at random to synchronize on. Eventually
// two threads will try to acquire the same two locks in
// the opposite order, resulting in a deadlock.
synchronized(locks[(int) (Math.random() * locks.length)]) {
synchronized(locks[(int) (Math.random() * locks.length)]) {
count++;
synchronized(text) {
text.setText("Counter: " + count);
}
}
}
}
}

public static void main(String[] args) {
DeadlockDemo demo = new DeadlockDemo();
demo.setSize(200, 200);
demo.setVisible(true);
demo.startSomeThreads();
}
}


Figure 1. DeadlockDemo, a program that (eventually) deadlocks.

You can run this class from the command line thusly:

java -Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n DeadlockDemo

To get a thread dump, you first need to attach the debugger. In another terminal window, type:

jdb -attach 8000

Note that the port number (8000, in this example) must match the port number that you provided when you launched the virtual machine. You will see:

Set uncaught java.lang.Throwable
Set deferred uncaught java.lang.Throwable
Initializing jdb ...
>

At the jdb prompt, enter “suspend” to temporarily suspend all running threads in the VM. Your program will become unresponsive after you do this. Next, enter “where all” to generate the thread dump. Here is a complete example:

Set uncaught java.lang.Throwable
Set deferred uncaught java.lang.Throwable
Initializing jdb ...
> suspend
All threads suspended.
> where all
DestroyJavaVM:
Runner Thread 2:
[1] DeadlockDemo.run (DeadlockDemo.java:47)
[2] java.lang.Thread.run (Thread.java:613)
Runner Thread 1:
[1] DeadlockDemo.run (DeadlockDemo.java:47)
[2] java.lang.Thread.run (Thread.java:613)
Runner Thread 0:
[1] DeadlockDemo.run (DeadlockDemo.java:47)
[2] java.lang.Thread.run (Thread.java:613)
AWT-EventQueue-0:
[1] java.lang.Object.wait (native method)
[2] java.lang.Object.wait (Object.java:474)
[3] java.awt.EventQueue.getNextEvent (EventQueue.java:345)
[4] java.awt.EventDispatchThread.pumpOneEventForHierarchy (EventDispatchThread.java:216)
[5] java.awt.EventDispatchThread.pumpEventsForHierarchy (EventDispatchThread.java:190)
[6] java.awt.EventDispatchThread.pumpEvents (EventDispatchThread.java:184)
[7] java.awt.EventDispatchThread.pumpEvents (EventDispatchThread.java:176)
[8] java.awt.EventDispatchThread.run (EventDispatchThread.java:110)
Java2D Disposer:
[1] java.lang.Object.wait (native method)
[2] java.lang.ref.ReferenceQueue.remove (ReferenceQueue.java:116)
[3] java.lang.ref.ReferenceQueue.remove (ReferenceQueue.java:132)
[4] sun.java2d.Disposer.run (Disposer.java:123)
[5] java.lang.Thread.run (Thread.java:613)
AWT-Shutdown:
[1] java.lang.Object.wait (native method)
[2] java.lang.Object.wait (Object.java:474)
[3] sun.awt.AWTAutoShutdown.run (AWTAutoShutdown.java:259)
[4] java.lang.Thread.run (Thread.java:613)
AWT-AppKit:
Signal Dispatcher:
Finalizer:
[1] java.lang.Object.wait (native method)
[2] java.lang.ref.ReferenceQueue.remove (ReferenceQueue.java:116)
[3] java.lang.ref.ReferenceQueue.remove (ReferenceQueue.java:132)
[4] java.lang.ref.Finalizer$FinalizerThread.run (Finalizer.java:159)
Reference Handler:
[1] java.lang.Object.wait (native method)
[2] java.lang.Object.wait (Object.java:474)
[3] java.lang.ref.Reference$ReferenceHandler.run (Reference.java:116)


Figure 2. A stack trace produced within jdb.

Here we see that our three “Runner Thread n” threads are all stuck at line 47 in the run method, each waiting for a lock that one of its siblings is holding. The user interface is not blocked, as the event dispatch thread (”AWT-EventQueue-0“) is waiting for another input event. The other threads are handling various background tasks in the VM.

To exit jdb, type “quit“. Your program, with the exception of any deadlocked threads, will become responsive again. If you do not wish to exit out of jdb, you can type “resume” instead of “quit” to undo the effects of “suspend“. Note that you can only generate a thread dump when threads are suspended.

Windows

On Windows, a slightly different mechanism is used for communication between the Java virtual machine and JDB. Rather than specifying a port for the connection, you tell the VM to use shared memory. Here’s what the command would look like for the DeadlockDemo example on Windows:

java -Xdebug -Xrunjdwp:transport=dt_shmem,server=y,suspend=n DeadlockDemo

To connect jdb to the virtual machine, enter:

jdb -attach jdbconn

Once connected, the commands used within jdb (suspend, where all, and quit) are the same as on OSX and Linux.

Another Alternative:

On Windows the 'standard', ie. default, connector uses the shared memory transport.

To connect to a socket, you need to tell jdb to use the socket attaching connector, ie

jdb -connect com.sun.jdi.SocketAttach:port=9000

It is hard to remember the names and params of all the connectors. You can do
jdb -listconnectors

Thursday, March 13, 2008

Comments from Grady Booch on SOA

Grady Booch, a father of UML and now an IBM fellow, made this comment about SOA in his blog in March 2006:

"My take on the whole SOA scene is a bit edgier than most that I’ve seen. Too much of the press about SOA makes it look like it’s the best thing since punched cards. SOA will apparently not only transform your organization and make you more agile and innovative, but your teenagers will start talking to you and you’ll become a better lover. Or a better shot if your name happens to be Dick. Furthermore, if you follow many of these pitches, it appears that you can do so with hardly any pain: just scrape your existing assets, plant services here, there, and younder [sic], wire them together and suddenly you’ll be virtualized, automatized, and servicized.

What rubbish."

Booch is right. The important thing is that SOA is a strategy that requires time and effort. SOA is a multi-year journey. You need some experience to understand what SOA really is about, and where and how it helps.

And, in IT, each system is different. As a consequence, you will have to build your specific SOA—you can’t buy it. To craft it, you’ll need time and an incremental and iterative approach.

进化论与SOA

"It is not the strongest of the species that survive, nor the most intelligent, but the ones most responsive to change."

The key is flexibility. SOA makes enterprises more responsive to changes.

SOA Design Fundamentals

  • A design principle is an accepted design guideline or practice that, when applied, results in the realization of specific design characteristics.
  • A design paradigm represents a set of complementary design principles that are collectively applied in support of common goals.
  • A design pattern identifies a common problem and provides a recommended solution.
  • A design standard is a convention internal and specific to an enterprise that may or may not be derived from a design principle or pattern.

Wednesday, March 12, 2008

Lessons Learned in SOA

  • Start Governance early: SOA Integration and SOA Governance need to work together to give you the benefits of agility, cost-reduction, and reduced risk.
  • Don't do SOA in an IT vacuum: With SOA and BPM ensure that business processes are optimized to realize the benefit of SOA for the entire organization.
  • Start small, but think holistically: Small projects are a great starting point, but services quickly develop into composite services. These composite services need to be managed, designed, and deployed centrally, as well as, work together with the SOA Integration solution.

Tuesday, March 11, 2008

SOA Security


Definition of Terms

Policy Enforcement Point (PEP)
the application-specific element that is physically enforcing access to a resource.

Policy Decision Point (PDP)
where decisions are made based on policies.

Policy Administration Point (PAP)
a tool to provide management to entitlement policy.

Policy Information Point (PIP)
data repository for the PDP, inlcuding attributes and policies.

Representational State Transfer (REST)

Definition: Representational State Transfer (REST) is an architectural style of large-scale networked software that takes advantage of the technologies and protocols of the World Wide Web. REST describes how distributed data objects, or resources, can be defined and addressed, stressing the easy exchange of information and scalability.

In 2000, Roy Fielding, one of the primary authors of the HTTP specification, wrote a doctoral dissertation titled "Architectural Styles and the Design of Network-based Software Architectures". In it, he coined the term “Representational State Transfer” to describe the networking principles that characterize the World Wide Web.

In the broadest terms, REST outlines how to define and address sources of specific information, commonly known as resources. Resources are referred to individually with a universal resource identifier, such as the URL used for Web addresses. The term REST often describes any simple interface used to transmit domain-specific data over HTTP without the need for additional messaging layers or session tracking.

REST is an architectural style, not a standard or implementation specification. The largest REST application is the Web itself, characterized by the use of HTTP for transport and URLs as addressing mechanisms. REST can support any type of media, and XML is the most popular method used to transport and represent structured information. REST is used with HTML, XHTML, RSS and proprietary XML vocabularies.

Systems that follow Fielding’s REST principles can be called RESTful, and some of REST’s advocates call themselves RESTafarians. But REST isn’t the only possible approach to building network applications, and there is some disagreement as to whether another might be preferable.

Basics of REST

REST involves several basic notions:
  • Data elements. Resources (such as data objects), resource identifiers (network addresses, URLs), and representations of resources (HTML documents, JPEG images) are accessed through a standardized interface such as HTTP.
  • Components. Origin servers, gateways, proxies and user agents communicate by transferring representations of resources through the interface, not by operating directly on the resources themselves. This is generally done using well-defined operations such as Get and Put.
  • Connectors. Clients, servers and caches, as well as tunnels such as Socks and SSL connections, present an abstract interface for communication, hiding the implementation details of communication mechanisms.
  • Stateless interaction. All requests made to connectors must contain all the information necessary to understand that request without depending on any previous request. This contrasts with the way many Web sites use cookies to maintain data between sessions. With REST, all messages must include all information necessary to understand the context of an interaction.

Why REST?

Many developers find REST challenging because it requires them to rethink their problems in terms of manipulating addressable resources instead of calling another routine to do something with that data. With RESTful design, Web services can be seen as simply a means of publishing information, components and processes to make them accessible to other users and machine processes. For example, the Atom Publishing Protocol, a RESTful application widely used for blogs, simplifies the process of publishing information and makes processes available to others so they can interact with that information. In general, REST requires less client-side software than do other approaches, because a single, standard browser can access any application and data resource.

Sunday, March 02, 2008

Dont's for SOA

  • Don't boil the ocean. Make sure the SOA project you choose for your starting point is well defined and well confined. Prove SOA successful with something that is small, is achievable in a short time, and will have a significant impact — then build incrementally.
  • Don't confuse SOA with an IT initiative. SOA must be a joint endeavor between business and IT. You have everything to gain — and everything to lose if you persist in such pigheadedness.
  • Don't go it alone. An entire industry is just waiting out there to help you. Don’t ignore it. Beg, borrow, steal, but get help. Reinventing the world is definitely anti-SOA thinking.
  • Don't think you are special. Stick to standards and standard interfaces. The proprietary software you build will be your own downfall. The sooner you part ways from evil temptations, the happier and healthier your software can be. (The happier and healthier your organization will be too, by the way.)
  • Don't neglect governance. SOA governance won’t happen by itself. Address it early. SOA governance is as much about the way you work and the processes you put in place to create a SOA environment as it is about any technology issues. So, don’t just go and buy a bucket full of tools labeled SOA governance. SOA governance is about leadership and thinking through how you are going to get from where you are today to a well-coordinated approach that conforms to your corporate goals and objectives.
  • Don't forget about security. In this brand new world of mixing and matching, it’s easy to get caught up in the euphoria and forget about the nitty-gritty. Pay close attention to the security implications of exposing business services.
  • Don't apply SOA to everything. SOA makes a lot of sense for a lot of things, but not for everything. If you have an application that is so specialized that it is isolated from other aspects of the business and works just fine, leave it alone. At the same time, when you find the software that is appropriate for SOA, you need to prioritize, scrutinize, and make sure you’re looking at the right level of granularity.
  • Don't start from scratch. Chances are, one of the SOA vendors has some sort of blueprint for a company just like yours. Take advantage of work already done. Look for a blueprint or model based on your industry first, such as insurance or financial services or banking — many already exist and more are being created every day.
  • Don't postpone SOA. SOA is a long journey. The sooner you begin, the sooner you’ll get somewhere.