I suppose this is more of a praise of Eclipse plug-in architecture and available documentation than a review of the book per se, but I did not get from Eclipse: Building Commercial-Quality Plug-ins anything I could not by scanning online docs and playing with Eclipse myself. I was up and running with my plug-in project in a very short time without opening this book, and once I did, I did not find anything I have not already learned or known where to turn for more info…
It may be easy to say that many such books are just a rehash of the wealth of online information already freely available, but sometimes the books do have added value, say, by presenting the material for faster learning and/or reference. In this case, there can be no such added advantage – again, because the Eclipse project’s own design and documentation is very clear and thorough… I realized all that before getting the book; in buying it, I was looking for another advantage – hidden tips and tricks, kind of like Covert Java. For example, how do I debug a plug-in project that depends on a non-plugin one? No such luck. I’ll be returning this book to the store now, and maybe trying to see if Contributing to Eclipse: Principles, Patterns, and Plugins is closer to what I want…Ten years since…
After 10 years, I finally finished an old incomplete (from Spring ’96!) in 6.863J.
Who debugs the debuggers, part III
…See also Part II…
I suppose the Javadt approach ran out of steam. For some reason,
it now takes a horribly long
time to invoke the request on an
ObjectReference thatrepresents a
java.sql.Connection.(A horribly long time is time enough to have a smoke, and then to come back, see it’s still not done and go surf the web enough to leave the zone.)
So I decide to bite the bullet and look into creating an Eclipse plugin… …which turns out to be not too hard. And, while I am at it, I will use
Java 6, and undo
the horrific crap I did to get around the lack of MethodExitEvent.returnValue()
feature… However, here’s little but symptomatic discovery (duh!).
Javadt does not like a
null EventSet — it just does notcheck for
nulls (which is ok, I suppose, for a throwaway referenceimplementation). So I was returning an empty
EventSet to it all the while. But Eclipse will indiscriminately call
resume() on it,which is not what I want. So I am back to returning
null. Fine. But how many of such little things would render this “framework” not really a framework… Or should this all be configurable?
JDBC notes
- Executing multi-line statements
Apparently, Oracle’s JDBC driver doesn’t like CR/LF endings. LF itself is ok. So this was needed:
sql = sql.replaceAll("\r", "");
See also: http://forum.java.sun.com/thread.jspa?threadID=669282&messageID=3914430 http://groups.google.com/group/comp.lang.java.databases/browse_frm/thread/ea6e14e596db1546/83f97ffd119eedb2 - “Due to a restriction in the OCI layer, the JDBC drivers do not support the passing of Boolean parameters to PL/SQL stored procedures…”
(no subject)
Nice to know that Sun’s implementation when manipulating ostensibly
insterfaces, in fact, expects them to be implementation classes inside.
For example, com.sun.tools.jdi.MirrorImpl.validateMirrorOrNull()
inside casts things to com.sun.tools.jdi.MirrorImpl rather than
com.sun.jdi.Mirror.
I love it when…
…I spend time working on something under an [reasonable] assumption
that I can do X, spend some more time realizing that I actually cannot,
lots more on cranking out convoluted code for working around that limitation, and
then find
out that this X has in fact been implemented in a later release than
the one I have…
the method, get the value it returned. This feature is there in
JDK
1.6. I don’t need it anymore for now though… Maybe I will…
Oracle and JPDA
I believed that I had to go through the pain to bridge DBMS_DEBUG to JDWP. I’ve already started to look into it, using GNU Classpath’s implementation. But it turns out that Oracle already supports debugging stored procedures with JPDA.
But all it does is that saves work on Dbdb, not makes it irrelevant. While adapting another debugger to JPDA is useful (and I may yet do it for something else), it is not the primary value of this project. It is in the unified call stack.
And David Alpern of Oracle claims they already have something like this, but it’s nowhere to be found. JDeveloper allows debugging stored procedures but the the single call stack, which is what I think is the ultimate value of Dbdb, is not there…
I don’t need no JSR-45…
In the search for debugger to use, I looked at various
debuggers’ source lookup facilities, which led me to realize that I wasn’t
thinking much when I suggested (or thought to suggest? did I miss it? good!) in my proposal to use JSR-45… It is useful for
the implementors of an execution environment that would pretend to be a
JPDA-compliant JVM, not for the developers of a debugger…
Who debugs the debuggers, part II
…See also Part I…
The JDB approach is kind of painful. Perhaps, another already
existing debugger can be used to try my approach? So far, I am
intimidated by Eclipse (or NetBeans), and want something easier. The reason
is that at this point my idea of integrating with a debugger is modifying
it to supply my own implementation of a
Connector –thus, I need the project whose code is easier to beat into an Eclipse project
and modify.
As far as more flexible integration with any debugger (for when
this project is “mature”) that would not require modifying source
of the said debuggers, I am considering the following. Since
every good debugger has a feature to “attach” to an executing
JVM, I will implement a Java-based “tunnel” for
JDWP.
Looks like GNU Classpath
has done all of the annoying work of implementing the spec.
After examining several alternatives, I have decided, for now, to
first use modified Trace, and,
when that runs out of steam, the Javadt.
I noticed have previously reinvented the wheel when I read
about JPDA but did not notice the existence ofTrace! In an effort
to track down a culprit in an execution of an application, I’ve replaced
the JVM called withFoljersCristals— my homegrown version
ofTrace. Do I feel silly now…
Who debugs the debuggers
So, to start with, I decided to go with JDB. First question is, how
Digression
The subject really must be in Latin, n’est pas? While I have no formal instruction in Latin, I should
Should it be “Quis emendabit ipsos emendatra”? I should probably asked someone to translate it, which reminds me of a
come up with one — what withLatin’sVocabula computatralia,
pretty formal structure, my general understanding
of syntax and “feel” for languages, my finishing a Natural Language Processing (6.863J) incomplete 10 years later,
Mike McLarnon’s conjugation applet
and Verbix…
recursive acknowledgment Littlewood
describes in
A Mathematician’s Miscellany. He talks about a translated paper that had three end-notes at the end of it:
- I wish to thank NN for translating this article
- I wish to thank NN for translating the above note
- I wish to thank NN for translating the above note
And that, of course, where it ends, for, though the author did not know the
target language, he was perfectly capable of writing note #3: by copying the second note…
best to use it in development:
-
Getting JDB to work with my own JPDA connector asked on forum
on Sun’s Developer Network
- Getting JDB to work with my own JPDA connector asked
on comp.lang.java.help
Then came home and figured out that I have to:
- put
tools.jar from the JRE’s home (as different
from JAVA_HOME, which, apparently, is assumed to be
JRE’s home — to wit, if you have JDK installed, it’s, e.g.,
D:jdk1.5.0jre rather than D:jdk1.5.0). In other
words, dropping the tools.jar into the jre/lib/ext
folder in addition to it's righteous place in
<JDK_INSTALL_DIR>lib did the trick...
- You should properly override name() of the Connector you're
implementing correctly for diagnostic (so that you're not confused by
the output of jdb -listconnectors) but that's a minor thing...
ProxyPlus?
I am backdating this entry, so I don’t remember quite what this was about…
E-mailed Shane:Got a bounce. So, for now, will do with explicit org.hrum.dbdb.JDBCDriverFactory‘s mechanism of going through drivers loaded, deregistering them and registering, in their stead, org.hrum.dbdb.DbdbDriver‘s that delegate to the registered drivers. P.S. This is what P6Spy doesHi,
I am working on a project that necessitates precisely what you describe — Proxies of classes, not just interfaces. So thank you, that I, apparently, don’t have to delve into BCEL (I will let you know about the project when I have a bit more to show than I do now). However, I’m a bit confused. In a description at http://www.gnufoo.org/java/java.html you point to your
junit.extensions.jfunc.util.ProxyPlus class, but it does not exist in the jcfe.jar I got from http://www.gnufoo.org/jcfe/, nor does it exist in the jfunc project. Where should I look for this functionality? Thanks.
Monkey business
After reading <a
href=http://discuss.fogcreek.com/joelonsoftware/default.asp?cmd=show&ixPost=75607&ixReplies=51>this, I thought I’ll put in my couple of bucks… This is a RANT!
It seems that the orientation in business is towards “monkey”
programmers — those who do not think, but do as they are
told. This is because management, apparently (and justifiably),
believes that at any given time it is easier to hire a hundred
monkeys (those are trained ones, that do not type randomly,
and so less than a million and less than infinite time will suffice,
but this is not a good analogy anyway), than a Shakespeare – or even Dumas
(with his own monkeys, so that’s another bad analogy, woe is me!)
As a result, there are (the list is by no means exhaustive; Java is
the language unless otherwise specified — I think Java has produced
more monkeys who think they are software engineers than anything
else — at least VB does not lend one an air of superiority):
- …monkeys who would rather sharpen the
carpal-syndrome-inducing skills of cutting and pasting the same
thing over and over again, rather than learn something like sed or Perl or a
similar tool —
or, indeed, spend some effort finding out about the existence
of such tools and their availability on the monkey platform of
choice (read: Windows) — or even finding out what plugins are
available for their lovely IDE.
IBM, for example, provides a framework called
EAD4J, Enterprise
Application Development for Java (it is only available with
purchase of IBM IGS consulting services). It includes components
similar to Struts, log4j, etc.
The framework is well designed, but here is a catch — because
of its design, adding or changing a service requires changes to
about 8 files. There are abstract processes, process factories,
interfaces, factories, XML files with queries, files containing constants to
look up these queries, etc., etc. It would really be nice if there was
a simple way to manage it, plugging in your logic where
some IDE plugin or script do the, well, monkey
job. Otherwise it’s overdesigned.Now, there are simple plugins for the current IDE of choice, WSAD, that at
least allow generating these
standard files (if not managing them, which is also important —
change one signature, and you have to change several
files). These plugins are provided by IGS
But nooo, the monkeys here prefer to create all of this by hand. It’s
a painful sight.
- …macaques who cannot fathom how one
could write a client-server application that does not communicate through
XML requests embedded in HTTP, but – o, horror! – actually has its own
application layer protocol.
- …baboons who think that
patterns
are not merely possible (albeit very good) approaches to problems
(and indeed are generalizations of good approaches to common
problems that have arisen). In fact, they
are the only way to solve problems, and that they must be copied from of
the book, or else it wouldn’t work. They wouldn’t know a pattern they
haven’t read about if it bit them on that place their head is
forever hidden in. If GoF didn’t write about it, it ain’t a pattern.
- Ok, I am tired of enumerating primate species. I’ll
just give an anecdote.
I wrote a module used by several teams. Because of the ever-changing
requirements, some methods and classes became
useless. I gave a fair warning by email, then I gave a second one by
marking themdeprecatedin the code. I notice that the
deprecated
tags were periodically removed. I send mail about this, and mark them
deprecated again. And again. And again.A monkey who was the team leader of another team came complaining that
I should remove it, because he cannot perform a build. Everyone else
can,
but he can’t, and so I should remove the single tag (that is probably
more useful to the whole project than anything he’s ever
produced). He cannot be bothered to find out how to make
it work? Why can everyone else make it work? Oh, he’s using some Ant
scripts? What? That’s an excuse? What the hell does that
have to do with anything? Oh, he didn’t write those
scripts. Well, write your own, or take them from those
people for whom they work. Oh, you don’t have time? Well,
I don’t have time to keep giving you warnings you just
ignore, you twit.Screw you, I finally thought, the warning has been there for some
time. I’ll just remove this stuff altogether.
His build promptly crashed. “Not my problem – we talked about this
over 5 weeks ago!”, I gloated, producing the emails from my
appropriately named CYA folder.As Butch said, “that’s what he gets for fucking up my sport.”
In short, they are not
Joel’s kind of programmers,
to put it mildly. Monkeys see and monkeys do. They do not think. They
have been taught a way to do things, and it is beyond them to figure
out that there could be another way. I honestly do not think they
understand what a boolean is (I submit that in their mind there is an
if statement, and then there’s a boolean type)when they write:
if (thingie.isOk()) {return true;
} else {
return false;
}
Then someone they blindly trust (it must be an established authority,
like a book/magazine — only that approved by an already established
authority, because monkeys do not further their education on their
own, — a manager, instructor at a paid course) tells
them about a ternary operator. Now they write:
return thingie.isOk() ? true : false;
The above two examples are from an actual production code. Further, because monkeys do not think, they often reinvent the
wheel, badly. Which is also ironic, because they have been imbued with
all the right (and wrong) buzzwords, including “reuse”. I hesitate
to hazard a guess as to whether there is some meaning in their heads
they associate with this word, or is it just something they cry out
when playing free associations with their shrinks (“OO –
Encapsulation! Polymorphism! Reuse!”). Here are some more anecdotes.
- One programmer on a project wrote his own utilities to convert things
from/to hex numbers, for crying out loud. Here is Java, the only thing
he knows at all, and he can’t be bothered to think that maybe,
just maybe, such a thing is a part of standard API.
- This same monkey took several weeks to write a
parser (for a very simple
grammar, containing only certain expressions and operators such as
ANDs and ORs). When I asked him why he didn’t use a
parser generator (such as ANTLR, CUPS or JavaCC), he replied that
he didn’t know any of them. Now, it is not a crime not to know a
particular technology, but surely a programmer must be a) aware
that there are such things as parser generators, and b) be
able to learn how to use one. Whether he lacked the understanding or the
desire to learn, is this the kind of developer you want?
- Background: We needed to create some scripts doing export from the
database. The export was to be done under some specific
conditions, which were to be specified in the queries
(that is, only export dependent tables if their parent
tables are eligible to be exported, etc.) The logic was
only in SQL queries, the rest were just scripts passing
these queries to DB2 command-line, logging everything.
All of those were written by hand, 80% time spent copying
and pasting things, and then looking for places where the
pasted things needed to be changed a bit (for example,
some things are exported several times into different IXF
files, because they are dependent on different
things. These files need to be numbered sequentially, so
next one does not overwrite the other. What do monkeys do?
Number them by hand. Great.)
When I suggested automating things, in fact, automating
from the first step – even before writing our own queries,
using the metadata to generate the
queries themselves, I was looked at as if I just escaped
from the mental asylum.Monkey But you cannot just rely on metadata, there are also
functional links which are not foreign keys.Me Why are they not foreign keys in the first place?
Monkey Because they are functional.
Me Stop using that word. Tell me why are they not foreign keys?
Monkey Because they are nullable.
Me A foreign key can be nullable! Why is it not a foreign key?
OK, whatever, that’s our DBA’s problem… But there’s a convention for
functional keys anyway (we know they all start with
SFK_, by convention). I’ll use that.Two days pass. My script works. A week later, they have problems
with their original scripts. My approach works,
demonstrably. But ok, they want to keep doing it their
way, fine. They ask for help with their way – those scripts, wrapping
hand-made SQL queries (which are already being automatically
generated, but I’ll hold on that for now…)Monkey What are you doing?
Me Writing a Perl script.
Monkey But there is no Perl on Windows.
Me See, I am sitting at a Windows machine and I have Perl.
Monkey What is it for? I thought Perl was only for the Web?
Me I am writing a script to generate your silly scripts
from the small set of user input. The resulting files, which you
are now doing BY HAND, are cluttered with repetitive stuff, such
as error-handling code and file numbering, and it’s error-prone to do
search and
replace manually. So we’ll generate all these scripts using my script.Monkey But they don’t have Perl on their Windows.
Me Who are “they”?
Monkey The client?
Me First of all, this is for the AIX machine. Second, this is
not for them, we will just deliver the generated shell scripts, the
Perl script is for us only.
It takes several iterations for Monkey to get it. A day passes…Me Hey, where’s my Perl script I wrote to generate the import
scripts?Monkey We have to have only shell scripts.
Me Yes, I used that one to create those shell scripts, dammit!
Monkey (sits writing these shell scripts again by hand. At the
moment, manually replacing some upper-case strings into lower-case) I
removed it from CVS. They only want shell scripts on their machine.Me It wasn’t going on their machine! It’s only for us!!!
Monkey Here, I changed these files already, you change the
rest.Me (giving up) OK.
Monkey Oh, and they have to be K-shell. Change them all to
.ksh.Me Why do they have to be ksh? What’s wrong with sh? They are
all very simple anyway, just call db2 import, check error status,
that’s it.Monkey They have to be K shell. That’s what the DBA said.
Me What the hell does the DBA have to do with it?
Monkey He wants to be able change them, and he doesn’t know sh,
only ksh.Me Ok, fine. I suppose you’re right,
echois
different in K-shell.
Monkey misses the seething sarcasm. Of course.Monkey Right here.
Me I don’t see them. What is this OAD_0035.ksh? Is that it?
Monkey Yes.
Me What does this mean? What do these numbers mean?
Monkey That’s what they said they should be called.
Me Who are “they”???
Silence.Me OK, you have a script called OAD_0035.ksh calling
OAD_0038.ksh, which in turn calls OAD_0038_1.ksh, OAD_0039_2.ksh, etc.
Why are they called this? It’s hard to remember which one is which.Monkey Why do you want to know what it means?
Me Because if I don’t know what it means, it’s much harder for
me to look at the file and see what is supposed to be inside. Ah, I
see
you added the insightful comment inside each file with its meaningful
name. Ah, I see also, you use that stupid name inside of it over and
over again, to write to the logs, instead of just using $0. (deep
breath). I’ll just create some symbolic links to them with meaningful
names, so I know what’s going on…
An hour laterMe Where are my links?
Monkey They only wanted files there that are named like
OAD_0035, etc.
Me What the hell do these numbers mean???Monkey I don’t know. For security.
Me (pause) Who told you to do this?
Monkey The client.
Me The client is a company. Who have you met from the company?
Monkey I don’t know. They said the client wants this.
Me Who said? Where? When?
Now I’m really curious. I turn with this question to
others. Finally I come to the last monkey who knows.
Monkey 5 Uh, the client has guidelines on what they are
supposed to be called. It should start with OAD, and
then underscore, then four characters.Me Why four characters?
Monkey 5 For normalization.
Me What normalization?! What can you possibly
change in a, I mean, normalize in a 20-line shell script?
luminous eggMonkey 5 So they can keep them consistent and do some things to
all of them, regardless of what they are called.Me What can they possibly want to do with shell scripts? Rename
them to some other numeric pattern? There isn’t even any method as to
how they are named, it’s not like a certain number
pattern means it’s dependent on the other. You just
named them randomly…Curtain
But hey, fire one, and the replacement is easy to find. That’s true.
I suppose Henry Ford would be proud, but isn’t this a backward
approach? You don’t need monkeys at all, most of this work can
be automated.Maybe I need another line of work. 🙂
MIT News Office!
MIT News Office on
us: “Alumni operate Internet ‘supermarket'”
Boston Herald!
Boston Herald on us:
Co-op gives Internet surfers food for thought
(copy at http://www.hrum.org/people/debedb/pro/sfc-herald-07-08-95).
Boston Business Journal!
Boston Business Journal
on us:
“HOME NETWORK SHOPPING”.
