For nearly two years, I've been trying to branch out and add another programming language to my brain.  I read and blogged about Seven Languages in Seven Weeks, by Brian Tate, an excellent book that I blasted through in seven days to save a little time.
I've been experimenting with using Pig on some Fannie-Mae MBS data lately.  While I don't mind writing MapReduce programs to process data (especially the fairly simple tasks I'm doing now), I really do appreciate the "magic" Pig does under the blanket, you might say.
I've recently been writing JMS clients for an application I'm building and keep finding myself having to re-learn some basic configuration.
A few years ago, I posted a how-to on Java-SE-based Web Services. More recently, I've become interested in asynchronous web-service invocation, and, as it turns out, Java SE supports that, too. This post, then, is the asynchronous version of that older post.
In an earlier post, we stepped through the building of an asynchronous web service, deployed in Java SE. I saved my comments for this post to keep things a little cleaner.
As I have mentioned in earlier posts, I am using the Java Debug Interface (JDI) to create a Java process-monitoring tool.
In my Part-1 post on this topic, we actually did all the I/O I'm going to do here. We lazily read in the entire sample data file, a file containing data describing events generated by a process monitor. My next goal was to re-hydrate my Events from the Strings serialized to the file.
I'm about halfway through Real World Haskell, and I've spent a week trying to decide when to write this post. As the authors point out, Haskell I/O is easy to work with.
For the last few weeks, I have been building a Java process monitoring tool based on the Java Debug Interface. Although I've done much of this work before, it has been a few years, and so now I'm retracing my steps.
After my last post scrolled off the bottom of the page, I realized I missed a couple of opportunities: one related to some additional code optimization, and one related to the topic of lazy (or nonstrict) evaluation.

First, let me review what I was doing.
Today I'm going to process a set of structured data using Haskell, tainted by years of Smalltalk, C++, Java and C# experience.
I've been working on a JDI (Java Debug Interface) project lately and have been posting helpful tips as I go along. It has been a few years since I've worked with this API, but although I know there have been a few enhancements, the API is quite consistent with what I remember.
Today I'm looking at Haskell type definition and the use of pattern-matching in functions. Pattern-matching is much more an integral feature of FP, as opposed to OO. But first...
I'm learning Haskell by following O'Sullivan, Goerzen and Stewart's Real World Haskell. I've been writing object-oriented code for well over half my career as a developer, and there are things about functional programming that really stand out to me specifically because of my OO background.
For the last year or so, I've been trying to come up to speed on functional programming, studying bits and pieces here and there. One interesting source was Bruce Tate's Seven Languages in Seven Weeks, which included a number of FP languages.
If you've looked at my recent posts, you know I'm working on a plugin for VisualVM, a very useful tool supplied with the JDK. In one example, I showed how to attach to a waiting Java application using a socket-based AttachingConnector.

If you've looked at my recent posts, you know I'm working on a plugin for VisualVM, a very useful tool supplied with the JDK. In one example, I showed how to attach to a waiting Java application using a socket-based AttachingConnector. At that time I said that there were two primary ways of attaching to a process with JDI -- via shared memory, and with a socket.

It turns out there is a "third way". Following is an example of why this way is useful, and why it was provided.

When I last wrote JDI programs (in Java 5), I would notice that my target application would start up and print (to stdout) the port on which it was listening, as in the following:
Listening for transport dt_socket at address: 55779
In Java 5, if you detached your debugger from this process, you would get another line to stdout in the target's console, like this:
Listening for transport dt_socket at address: 55779
and this would go on for as long as you chose to attach and detach, etc.

At some point (and I don't know when this started happening), the port on which the target is listening started changing on each detach of an external debugger. If in Java 6 (I'm using u20), you repeatedly attach and detach from the target process, you'll see the following out in the target's console:
Listening for transport dt_socket at address: 55837
ERROR: transport error 202: recv error: Connection reset by peer
Listening for transport dt_socket at address: 55844
ERROR: transport error 202: recv error: Connection reset by peer
Listening for transport dt_socket at address: 55846
ERROR: transport error 202: recv error: Connection reset by peer
Listening for transport dt_socket at address: 55911
If you're writing an application that attaches using the debug port, each time you attach you need to find out what port the target is using. This information is not available from the process itself; in other words, you have to play the usual unpleasant game of capturing console output to know what the port is. Even if you specify a port at target start, you still need to get your hands on the value.

You can still find the original request for a feature to attach to a process by its process ID if you search around the old Java bug reports. The long and short of it: a new AttachingConnector was created, one which attaches by PID. As you know, sometimes it isn't much fun finding a process's PID either. In my case, however, I am writing a plugin for VisualVM, and one thing you get for free when you do that is Visual VM's API, which as you might expect includes calls to get the PID. My goal, then, is to use this new connector in my VisualVM plugin, and I thought it might be appreciated if I shared the details.

I've adapted my test program from an earlier post so that it now outputs the details of each AttachingConnector; the changed code fragment is shown here:
List<AttachingConnector> attachingConnectors = vmMgr.attachingConnectors();
for (AttachingConnector ac: attachingConnectors)
{
Map paramsMap = ac.defaultArguments();
Iterator keyIter = paramsMap.keySet().iterator();
System.out.println("AttachingConnector: '" + ac.getClass().getName() + "'");
System.out.println(" name: '" + ac.name() + "'");
System.out.println(" description: '" + ac.description() + "'");
System.out.println(" transport name: '" + ac.transport().name() + "'");
System.out.println(" default arguments:");
while (keyIter.hasNext())
{
String nextKey = keyIter.next();
System.out.println(" key: '" + nextKey + "'; value: '" + paramsMap.get(nextKey) + "'");
}
}
The output from this code is shown below:
AttachingConnector:  'com.sun.tools.jdi.SocketAttachingConnector'
name: 'com.sun.jdi.SocketAttach'
description: 'Attaches by socket to other VMs'
transport name: 'dt_socket'
default arguments:
key: 'timeout'; value: 'timeout='
key: 'hostname'; value: 'hostname=AdamsResearch'
key: 'port'; value: 'port='
AttachingConnector: 'com.sun.tools.jdi.SharedMemoryAttachingConnector'
name: 'com.sun.jdi.SharedMemoryAttach'
description: 'Attaches by shared memory to other VMs'
transport name: 'dt_shmem'
default arguments:
key: 'timeout'; value: 'timeout='
key: 'name'; value: 'name='
AttachingConnector: 'com.sun.tools.jdi.ProcessAttachingConnector'
name: 'com.sun.jdi.ProcessAttach'
description: 'Attaches to debuggee by process-id (pid)'
transport name: 'local'
default arguments:
key: 'pid'; value: 'pid='
key: 'timeout'; value: 'timeout='
A couple of things I hadn't noticed before is that the socket-based connector comes with the hostname argument pre-set to my machine's hostname, and that all three connectors have a timeout default argument. The first observation brings up an interesting point: if you use the local, PID-based connector, remember that you'll only be attaching to processes on your debugger's host.

I changed my test program to use the local connector and it works as before! Well, no, actually, it does not. Here's what I now get:
java.lang.UnsatisfiedLinkError: no attach in java.library.path
Exception in thread "main" java.io.IOException: no providers installed
at com.sun.tools.jdi.ProcessAttachingConnector.attach(ProcessAttachingConnector.java:86)
at com.adamsresearch.jdiDemo.JDIDemo.main(JDIDemo.java:70)
Does this mean the local connector isn't exactly ready for use? No, but I have been burned by the same issue that has plagued a number of others (scroll down in that page -- the issue was found by a reader of that post and was solved, partially, by another reader of that post). I'm working on a Windows platform, and when you do that you have to be a little careful ;-> . In this case, the problem is caused by 1) using the java interpreter as found on the system path, and 2) not making sure that path points directly to your JDK or JRE directory. The executable will look in a path relative to itself for the needed libraries, and when Windows copies the java executable to C:\Windows\system32 (or similar) -- and if you use that executable -- that relative path is broken. I believe this is the true issue, unlike described in the comments on the above post, where the distinction is made between using the JRE java and the JDK java. I don't think that's the issue. For example, below are the results of my attach test in 3 different scenarios:
  1. Using java from my path, the first hit of which comes from C:\Windows\system32:

    java -cp c:\jdk1.6.0_20\lib\tools.jar;. com.adamsresearch.jdiDemo.JDIDemo 10816 863 fileName
    ...
    java.lang.UnsatisfiedLinkError: no attach in java.library.path
    Exception in thread "main" java.io.IOException: no providers installed
    at com.sun.tools.jdi.ProcessAttachingConnector.attach(ProcessAttachingConnector.java:86)
    at com.adamsresearch.jdiDemo.JDIDemo.main(JDIDemo.java:70)

  2. Using the full path to the JRE bin java:

    c:\jdk1.6.0_20\jre\bin\java -cp c:\jdk1.6.0_20\lib\tools.jar;. com.adamsresearch.jdiDemo.JDIDemo 10816 863 fileName
    ...
    Attached to process 'Java HotSpot(TM) 64-Bit Server VM'

  3. Using the full path to the JDK bin java:
    c:\jdk1.6.0_20\bin\java -cp c:\jdk1.6.0_20\lib\tools.jar;. com.adamsresearch.jdiDemo.JDIDemo 10816 863 fileName
    ...
    Attached to process 'Java HotSpot(TM) 64-Bit Server VM'
As you can see, the above seems to support my theory that it's not the JRE vs the JDK, but rather the context-poor placement of the java executable in the "usual" Windows binaries directory, that caused the problem. That posting is several years old, so it is possible that at that time, the needed JDI libraries actually were not included in the JRE, but it is clear that today, you will see the same exception if you use the java executable found in Windows' default binaries directory.

Now, if I run my JDI application against my JarView utility, searching for AttachingConnector in the JDK installation directory, I get the following output:
Breakpoint at line 863:
fileName = 'AttachingConnector.class'
Breakpoint at line 863:
fileName = 'GenericAttachingConnector$1.class'
Breakpoint at line 863:
fileName = 'GenericAttachingConnector.class'
Breakpoint at line 863:
fileName = 'ProcessAttachingConnector$1.class'
Breakpoint at line 863:
fileName = 'ProcessAttachingConnector$2.class'
Breakpoint at line 863:
fileName = 'ProcessAttachingConnector.class'
Breakpoint at line 863:
fileName = 'SharedMemoryAttachingConnector$1.class'
Breakpoint at line 863:
fileName = 'SharedMemoryAttachingConnector.class'
Breakpoint at line 863:
fileName = 'SocketAttachingConnector$1.class'
Breakpoint at line 863:
fileName = 'SocketAttachingConnector.class'
and so have done what I set out to do, which is 1) debug-attach by process ID, and 2) thrash through the inevitable hiccups and share the solutions. Hopefully this will be useful to you, too.

Note: actually, there are even more ways to attach to a Java process. JPDA Connection and Invocation is the definitive guide, from Oracle. If you're going to be writing debuggers, you can't go wrong reading this page first.
Say you've got a good-sized chunk of code, in production, that doesn't always act as expected but it does so often enough that everyone's willing to keep using it (including your customers).
As I mentioned in an earlier post, I noticed recently that the JDK utility VisualVM is extensible, and it was my goal to create a useful extension.
I'm not sure when this happened, but at some point the JDK-included VisualVM utility became extensible. This is really great news for me. Writing a profiler is a lot of work (although admittedly very interesting and fun).
We use DWR (http://www.directwebremoting.org) a lot where I'm working now. It's a Java library used to integrate JavaScript-based web development with Java middleware.
I've reached the 7th and final language of Bruce Tate's Seven Languages in Seven Weeks. While some of the previous languages were functional with some imperative support, Haskell is a purely functional, and statically typed, language.
Today I'm reviewing the discussion of Clojure from Bruce Tate's Seven Languages in Seven Weeks. Clojure is Lisp on the Java virtual machine. Lisp is another language that, despite being around a long time, I have yet to investigate, so this is another new experience.
If you are just dropping in on me, I'm reviewing Bruce Tate's Seven Languages in Seven Weeks, with the slightly lazy (or aggressive, depending on your view) twist of reviewing one language per day.
Scala is the 4th language in Bruce Tate's Seven Languages in Seven Weeks. It is the only language in this book with which I am already familiar, although I've only been learning it for a month or so.
Prolog is the 3rd language covered in Bruce Tate's Seven Languages in Seven Weeks, and is a declarative, rather than imperative, language. Prolog is not new, of course (1972), but I have to admit this is the first time I've taken a look at it.

Like Bruce, I used GNU Prolog (1.3.1).
Io is the 2nd language in Bruce Tate's Seven Languages in Seven Weeks. Io is a prototyping language, where most of the mass exists in the libraries. The syntax itself is refreshingly simple, and he is not exaggerating to say you can grasp it in about 15 minutes.
When I decided to blow through Seven Languages in Seven Weeks in only 7 days, I had yet to read even the introduction to the book.
I recently started learning Scala (you know when the New York Times refers to Java as an "older" language, it's time to update!). As I've started trying to shift my thinking from object orientation to functional programming, I remembered the book Seven Languages in Seven Weeks by Bruce Tate.
Recently I had a repeat of a problem I was unable to solve the first time I encountered it.
Hello, everyone:

I've posted a number of entries in the last year about profiling Java applications. Some of this effort went in to a standalone Java profiler with a Swing interface, called the MonkeyWrench.
DTrace, a dynamic tracing framework on Solaris (see dtrace(1m)) is a valuable and extremely easy-to-use tool if you find yourself analyzing Java performance issues on Solaris.
My entries here are usually about Java, but today I want to call attention to the 1.0 release of FlexMonkey, an Adobe AIR app for testing Flex and Adobe AIR applications (I work for Gorilla Logic, the creator of FlexMonkey).
In recent posts, I've investigated using the java.lang.instrument package to instrument Java classes for a simple profiler.
I've been building a Java profiler lately, partly to address what I think are shortcomings in the current set of free/shareware profilers, and also to enjoy the flexibility of obtaining only the profiling information I need.
Lately I've been looking at profilers and wondering how easy it would be to write one, mostly to be able to provide a little more sophisticated guidance to performance investigations.
About Me
About Me
My Photo
I'm a software architect/consultant in Boulder, Colorado.
Picture
Picture
Blog Archive
Loading
Dynamic Views theme. Powered by Blogger. Report Abuse.