ON THIS PAGE
    ARCHIVES
    CATEGORIES
    BLOGROLL
    LINKS
    SEARCH
    MY BOOKS
    DISCLAIMER
 
 Thursday, March 22, 2007
RedHat, Inc: The Next Microsoft?

Think that RedHat is still the open source capital of the Internet, all happy-happy-joy-joy with its supporters and liberal-minded in its goals? Take a look at this and tell me if your mind isn't changed a little:

Enclosed is a copy of the form letter they sent out to many companies that offer Hibernate consulting and training. 

Dear Sir or Madam: 

Red Hat, Inc. has become aware that your company is offering Hibernate training courses. Red Hat does not allow the use of its trademarks without a written agreement. 

Red Hat is the owner of numerous trademarks, including but not limited to, its Hibernate mark, U.S. Federal Registration Number 3135582. RedHat has made extensive use of its Hibernate marks in interstate and international commerce in connection with the advertising, promotion, and sale of its goods and services. Due widespread use, advertising and extensive marketing, the RedHat marks have become famous. 

Red Hat requests that you immediately cease offering Hibernate branded training, as well as any other training that may contain Red Hat marks 
or marks that are confusingly similar. Although you may offer object 
oriented relational database mapping training, you may not use the Hibernate name to promote and advertise your products and services. 

We trust you will understand Red Hat's interest in protecting its valuable intellectual property and ensuring that consumers are not misled as to the source and sponsorship of goods and services sold and/or distributed under the RED HAT marks. We trust this matter can be resolved promptly and amicably and appreciate your attention to this matter. 

We look forward to your reply and request a response no later than {WITHHELD}. 

Sincerely, 

Meredith K. Robertson 
Legal Specialist 
Red Hat, Inc. 

Folks, RedHat has officially moved into the "Big Corporate Entity Seeking Profit At Any Expense" category. So much for the Open-Source-Can-Really-Make-Money-Too-We-Swear poster child, if you ask me...


UPDATE: Apparently, people at eWeek and Yahoo! News posted articles referencing this entry, so let me post some responses to the comments sent in.

First, I don't think this issue is about copyright law whatsoever or IP issues; it's a deeper, more fundamental issue than that. We can certainly argue whether "Hibernate" is a trademarked name or a generic name (such as the discussion over "Kleenex" or the act of copying a paper known as "Xeroxing" it), but that's not the interesting point here either--the point is that RedHat somehow feels that the use of the term "Hibernate" in Bill Dudney's training curriculum is somehow going to imply that Bill has received special blessing from RedHat to do so. Does that mean, then, that I need special blesing from Sun in order to offer "Java" training, or special blessing from Microsoft to offer ".NET" training? If that's the case, then there are a lot of training companies who'd better pull their training courses off the shelf and rethink offering training at all, because there's some serious copyright violations going on out there.

Besides, I thought OSS was a reaction against copyright law.

There's the deeper issue, too, of RedHat's heavy-handedness in this: why is it that companies continually feel that the best way to start these discussions is with cease-and-desist letters? It's pathetic when a corporation like Sun does this (as I went through with my small riff with them over "javageeks.com"), but even more so when an open-source company--who for years has proudly proclaimed their allegiance to "the community" and paraded it around as a compelling reason over commercial "evil corporation" solutions like Solaris or Windows or HP-UX--takes the same path.

I like the OSS stack, and when I write something that's worth putting into play, I will do so. (Arguably, I've already done so--the Java attributes facility I wrote years ago before JSR 175 and JDK 5 shipped was finished by Mark Pollack and used in several OSS projecs, but I call that more Mark's work than my own.) But it's time that we start making the critical realization that an industry cannot rest on the backs of volunteer work. And I, for one, do not want this industry to surrender its commercial aspects; I cannot pay for my house with "community spirit", and frankly, I don't want to give up doing what I love (writing software, and teaching others how to do the same) just because of an idea proposed by a guy who now makes his living from delivering keynotes and ranting about the evils of closed-source. I submit that Stallman would sing a different tune were he in fact still a working programmer with a mortgage and a family to feed.

If RedHat continues with this, they will simply demonstrate that they are, in fact, no better than any of the other "evil corporations", that they are in fact first and foremost concerned with turning a profit. And maybe that's not a bad thing in the long run. I'm certain the employees at RedHat are no more evil than anybody who works at Microsoft or Sun or Oracle. I'm certain RedHat is just as concerned with their image and their standing in the community as those other companies. I'm also certain that, at the end of the day, the people who work at RedHat want to make money doing what they love, just as I and thousands--if not millions--of other programmers do. Why do we think it's wrong for them to do so?

RedHat, you are under no obligation to retract your C-and-D letters. You are perfectly justified in defending your copyright and trademark. But it definitely puts a crimp on the socialistic tendencies that come out of the mouths of the most virulent OSS evangelist for you to do so, and almost puts the whole open-source argument into a strange discussion where now we're just arguing over the quality of the code and the costs... which is maybe where the argument should have been from the beginning, not over "free as in speech" or "free as in beer".


.NET | C++ | Conferences | Java/J2EE | Ruby | Windows | XML Services

Thursday, March 22, 2007 12:56:27 AM (Pacific Daylight Time, UTC-07:00)
Comments [16]  | 
 Friday, February 23, 2007
Avoiding Ruby/Rails Grief

Scott Hanselman (the Zen master himself) posted an interesting piece about coming through the five stages of programming language grief, while wrestling with a .NET project written in Boo (a .NET language based on Python). That Scott should fall prey to the temptation to "doing things in the old way" (meaning he tried to port the project to C# because C# is, of course, the GOPL: God's Original Programming Language) is a touch surprising, because I tend to think more highly of Scott than that, but I have to admit having fallen into the same trap myself, so of course his sins are forgivable.

Amazing, isn't it, how we can forgive or excuse people's actions when we find ourselves doing the same thing?

Anyway, Scott's post highlights the importance of understanding the "Zen" of a particular programming language--its idioms, its approaches, and its strengths/weaknesses/quirks--when you move into it. For most of us, it's always easier to move into new territory with an experienced guide to show you the way. For Java developers, a guide--or, rather, a pair of them--have just made themselves available to you. Stu Halloway and Justin Gehtland (both ex-DevelopMentor instructors and, I'm privileged to say, friends of mine) have published "Rails for Java Programmers", a Java-centric guide to using Rails and Ruby, and a book I highly recommend, on the grounds that it helps "make Rails make sense" for developers used to the traditional Model/View/Controller approach in Java web apps. Weighing in at a pretty reasonable 300+ pages, it's probably one of the most gentle introductions to Rails that I've yet seen, and it's minus all the distractions of Why the Lucky Stiff's intro to Ruby.

Have a look--there's a sample chapter on InfoQ.




Friday, February 23, 2007 5:21:30 PM (Pacific Standard Time, UTC-08:00)
Comments [4]  | 
 Tuesday, January 30, 2007
Interop Briefs: In-proc Interoperability

(This piece is currently live on InfoQ.com; when sufficient time has passed, I'll repost it here.)


.NET | C++ | Java/J2EE | Windows

Tuesday, January 30, 2007 9:11:37 PM (Pacific Standard Time, UTC-08:00)
Comments [1]  | 
Important/Not-so-important

Frank Kelly posted some good ideas on his entry, "Java: Are we worrying about the wrong things?", but more interestingly, he suggested (implicitly) a new format for weighing in on trends and such, his "Important/Not-so-important" style. For example,

NOT SO IMPORTANT: Web 2.0
IMPORTANT: Giving users a good, solid user experience. Web 2.0 doesn't make sites better by itself - it provides powerful technologies but it's no silver bullet. There are so many terrible web sites out there with issues such as
- Too much content / too cluttered http://jdj.sys-con.com/
- Too heavy for the many folks still on dial-up
- Inconsistent labeling- etc. (See Jakob Nielsen's site for some great articles )
Sometimes you have to wonder if some web site designers actually care about their intended audience?

I love this format--it helps cut through the B/S and get to the point. Frank, I freely admit that I'm going to steal this idea from you, so I hope you're watching Trackbacks or blog links or whatever. :)


.NET | C++ | Conferences | Development Processes | Java/J2EE | Reading | Ruby | Windows | XML Services

Tuesday, January 30, 2007 3:17:23 AM (Pacific Standard Time, UTC-08:00)
Comments [1]  | 
 Friday, January 26, 2007
More on Ethics

While traveling not too long ago, I saw a great piece on ethics, and wished I'd kept the silly magazine (I couldn't remember which one) because it was just a really good summation of how to live the ethical life. While wandering around the Web with Google tonight, I found it (scroll down a bit, to after the bits on Prohibition and Laughable Laws); in summary, the author advocates a life around five basic points:

  1. Do no harm
  2. Make things better
  3. Respect others
  4. Be fair
  5. Be loving

Seems pretty simple, no? The problems occur, of course, in the interpretation and execution. For example, how exactly do we define "better", when we seek to make things better? Had I the power, I would create a world where all people are free to practice whatever religious beliefs they hold, but clearly if those religious beliefs involve human sacrifice, then it's of dubious belief that my actions made the world "better". (Of course, said practitioners would probably disagree.)

It's also pretty hard to actually follow through on these on a daily basis. The author, Bruce Weinstein, makes this pretty clear in this example:

For example, how often do we really keep “do no harm” in mind during our daily interactions with people? If a clerk at the grocery store is nasty to us, don’t we return the nastiness and tell ourselves, “Serves them right?”  We may, but if we do, we harm the other person. In so doing, we harm our own soul—and this is one of the reasons why we shouldn’t return nastiness with more of the same.

Ouch. Guilty as charged.

There's a quiz attached to the article, and I highly suggest anyone who cares about their own ethical behavior take it; some of the questions are pretty clear-cut (at least to me), but some of them fall into that category of "Well, I know what I *should* say I would do, but...", and some of them are just downright surprising.

Personally, I think these five points are points that every developer should also advocate and life their life by, since, quite honestly, I think we as an industry do a pretty poor job on all five points. Clearly we violate #1 when we're not careful with security measures in the code; too many programmers (and projects) fail to realize that "better" in #2 is from the customers' perspective, not our own; too many programmers look down on anyone who's not technical in some way, or even those who disagree with them, thus violating #3; too many consultants I've met (thankfully none I can call "friends") will take any excuse to overbill a client (#4); and so on, and so on, and so on.

Maybe I'm getting negative in my old age, but it just seems to me that there's too much shouting and posturing going on (*cough* Fleury *cough*) and not enough focus on the people to whom we are ultimately beholden: our customers. Do what's right for them, even if it's not the easy thing to do, even when they don't think they need it (such as the incapcitated friend in the quiz), and you can never go wrong.


.NET | C++ | Conferences | Development Processes | Java/J2EE | Reading | Ruby | Windows | XML Services

Friday, January 26, 2007 5:34:23 PM (Pacific Standard Time, UTC-08:00)
Comments [3]  | 
Programming Promises (or, the Professional Programmer's Hippocratic Oath)

Michael.NET, apparently inspired by my "Check Your Politics At The Door" post, and equally peeved at another post on blogs.msdn.com, hit a note of pure inspiration when he created his list of "Programming Promises", which I repeat below:

  • I promise to get the job done.
  • I promise to use whatever tools I need to, regardless of politics.
  • I promise to listen to the Closed Source and Open Source zealots equally, and then dismiss them.
  • I promise to support, as long as I am able, any closed source applications I may release.
  • I promise to release open source any applications I can not, or will not, support.
  • I promise to learn as many languages and libraries as possible, regardless of politics.
  • I promise to engage with as many other programmers as possible, both in person and online, in order to learn from them; regardless of politics.
  • I promise to not bash Microsoft nor GNU, nor others like them, everyone has a place in our industry.
  • I promise to use both Windows and Linux, both have their uses.
  • I promise to ask questions when I don't know the answer, and answer questions when I do.
  • I promise to learn from my mistakes, and to try to the first time.
  • I promise to listen to any idea, however crazy it may sound.

In many ways, this strikes me as fundamentally similar to the Hippocratic Oath that all doctors must take as part of their acceptance into the ranks of the medical profession. For most, this isn't just a bunch of words they recite as entry criteria, this is something they firmly believe and adhere to, almost religiously. It seems to me that our discipline could use something similar. Thus, do I swear by, and encourage others to similarly adopt, the Oath of the Conscientious Programmer:

I swear to fulfill, to the best of my ability and judgment, this covenant:

I will respect the hard-won scientific gains of those programmers and researchers in whose steps I walk, and gladly share such knowledge as is mine with those who are to follow. That includes respect for both those who prefer to keep their work to themselves, as well as those who seek improvement through the open community.

I will apply, for the benefit of the customer, all measures [that] are required, avoiding those twin traps of gold-plating and computing nihilism.

I will remember that there is humanity to programming as well as science, and that warmth, sympathy, and understanding will far outweigh the programmer's editor or the vendor's tool.

I will not be ashamed to say "I know not," nor will I fail to call in my colleagues when the skills of another are needed for a system's development, nor will I hold in lower estimation those colleagues who ask of my opinions or skills.

I will respect the privacy of my customers, for their problems are not disclosed to me that the world may know. Most especially must I tread with care in matters of life and death, or of customers' perceptions of the same. If it is given me to save a project or a company, all thanks. But it may also be within my power to kill a project, for the company's greater good; this awesome responsibility must be faced with great humbleness and awareness of my own frailty. Above all, I must not play at God, and remain open to others' ideas or opinions.

I will remember that I do not create a report, or a data entry screen, but tools for human beings, whose problems may affect the person's family and economic stability. My responsibility includes these related problems, if I am to care adequately for those who are technologically impaired.

I will actively seek to avoid problems that are time-locked, for I know that software written today will still be running long after I was told it would be replaced.

I will remember that I remain a member of society, both our own and of the one surrounding all of us, with special obligations to all my fellow human beings, those sound of mind and body as well as the clueless.

If I do not violate this oath, may I enjoy life and art, respected while I live and remembered with affection thereafter. May I always act so as to preserve the finest traditions of my calling and may I long experience the joy of the thanks and praise from those who seek my help.

I, Ted Neward, so solemnly swear.


.NET | C++ | Conferences | Development Processes | Java/J2EE | Reading | Ruby | Windows | XML Services

Friday, January 26, 2007 4:51:53 PM (Pacific Standard Time, UTC-08:00)
Comments [2]  | 
Two more interviews...

Two more of the interviews I did at JavaPolis 2006 in Belgium are now online... first, Eric Evans (of "Domain-Driven Design" fame), talking about, quite naturally, domain-driven design, and the second, the pair that brought Ruby to the JVM, Charles Nutter and Thomas Enebo. (Charles was just recently added to the No Fluff Just Stuff tour, so I'm looking forward to hanging out with him and playing more with JRuby.)


Conferences | Java/J2EE | Ruby

Friday, January 26, 2007 2:23:05 AM (Pacific Standard Time, UTC-08:00)
Comments [0]  | 
 Sunday, January 21, 2007
Interop Briefs: Out-of-proc interop using Intrinsyc's J-Integra

(This piece originally appeared on TheServerSide under the title "Interop Across the Wire" on 16 November 2006. I've fixed the--again--horrendous formatting problems and touched it up slightly. Changes are in italics.)

Welcome to the next installment of “As the Interop World Turns”. In this particular bit, we’re examining interop across the wire, but before we do, let’s acknowledge the major news in the interoperability arena, the announcement of the formation of the Interoperability Alliance, bringing together Microsoft, BEA, Sun, and another dozen or so vendors, all focused on making it easier to play nicely between the platforms.

Practically speaking, however, at this point the Interop Alliance hasn’t significantly changed the interop landscape, so while it’s important to note that they exist, there’s nothing more to report. Whether this will turn into Something Big, or just another meaningless consortium of vendors remains to be seen—for now, it remains as a “potential” industry-affecting move.

On to more practical matters.

In recent years, most focus about interoperability between Java and .NET has been directly on the WS-* stack, AKA “Web Services”. For almost a decade now, the various vendors involved in the various WS-* standardization efforts (and even those who don’t participate directly but graft on to the edges somehow) have promised that as soon as the standards are here, and the implementations all implement the standards, seamless and ubiquitous interoperability across all platforms will be ours.

We’re waiting...

In the meantime, however, it turns out–-according to those incredibly insightful people at Gartner and other “analysis agencies”--that most of the time, the only two platforms that principally draw interop interest are the JVM and the CLR. Hardly a surprise, for those of us who actually work for a living. And, as it turns out, if you’re looking to limit your interoperability to those two platforms, numerous toolkits abound already to make this happen.

While open-source toolkits also exist, in general they aren’t quite “up to speed” against the commercial toolkits, so in this entry we’ll focus on those, mainly the tools offered by J-Intrinsyc. Other commercial tools include JNBridgePro and Borland's Janeva. (In the time since this article's publication--which is a pretty short window, making me wonder if this wasn't the case before publication--attempting to download a trial of Janeva results in an error on Borland's site. More interestingly, Borland's latest release of VisiBroker claims .NET support, so it's possible that Janeva is being discontinued in favor of slipping .NET support into VisiBroker.) Each effectively provides a binary RPC-based interop approach, in which you follow a development process that’s (deliberately) similar to what’s done when working with the native ORPC stack (CORBA or RMI for Java, .NET Remoting for .NET). In several cases, the toolkits use the wire syntax and format of one of the two platforms (IIOP, JRMP or the .NET Remoting format), meaning that for one of the two platforms, the experience is seamless. (Which platform gets to be the seamless experience is up to you, of course, but practical considerations—and a desire to continue to do business with your clients—generally dictate that your clients have the better experience. Choose wisely.)

In the case of Janeva, (or any other CORBA tool, for that matter) the definitions are done in CORBA IDL, a language strikingly and deliberately similar to Java/C++/C# interface declarations. Developers familiar with CORBA will know what to do with these definitions on a .NET platform: simply run the ORB's code-gen tool over the IDL file, which will generate stubs (client-side proxies) or skeletons (server-side proxies) as necessary. For existing CORBA systems, this is likely to be the easiest thing for a .NET client to do to hook in, but remember that CORBA IDL is an entire language and type system in of itself, and CORBA itself represents a fairly sizable stack to get used to - easily dwarfing what’s in the .NET Remoting stack in both size and complexity.

For simpler scenarios, it’s generally easier to use something a little less intimidating (and, correspondingly, less powerful), such as the JaNET or JNBridge tools. Each is equally useful in my opinion, so I’m picking one at random here to use as a demo. JNBridge lost the toss (seriously!), so I’m going to use the J-Integra tool for this demo. This is actually taken from one of the demos shipping with their product, so if you feel like following along, grab the eval demo off their website, install, and look for the HelloWorld demo in the examples directory.

J-Integra takes a “.NET-friendly” perspective, meaning that the development experience is a bit easier on the .NET developer than the Java developer. (JNBridgePro take the opposite tack, for what that’s worth.) Thus, for the C# developer, developing an interoperable scenario is as simple as writing a typical .NET Remoting component—build a class that extends System.MarshalByRefObject:

// Copyright 2001-2003 Intrinsyc Software Inc.
// All rights reserved.
using System;
namespace HelloWorld
{
  public class HelloWorldClass: System.MarshalByRefObject
  {
    private String name;

    public HelloWorldClass(String name) {
      this.name = name;
    }

    public String getMessage() {
      return “Hello World, from ” + name;
    }
  }
}

From a .NET Remoting perspective, there’s absolutely nothing interesting about this class, which is exactly the point—any existing .NET Remoting servers can be flipped to be interoperable by doing exactly nothing. (In this particular demo, Intrinsyc has the HelloWorldClass instances being hosted by ASP.NET, but obviously we could just as easily self-host it if desired—see Ingo Rammer’s “Advanced .NET Remoting” from APress for details if you’re not “up” on your .NET Remoting.)

To get Java to call this guy, we need to do run J-Integra’s “GenJava” tool to create Java client proxies and compile them. Once those proxies are generated and compiled (and unfortunately I don’t see any custom Ant tasks to do this, so you’ll likely have to write an “exec” task to do it), drop them into your client .jar file, and call the proxies by name:

// Copyright 2001-2003 Intrinsyc Software Inc.
// All rights reserved.

import HelloWorld.*;

public class HelloWorldMain {
  public static void main(String[] args) throws Exception {
    HelloWorldClass helloWorldClass = new HelloWorldClass(”Fred”);
    System.out.println(helloWorldClass.getMessage());
  }
}

Again, nothing special, which is the point—the “magic” takes place inside the generated proxy, which (based on the settings in the GenJava tool) knows how to call over HTTP to the ASP.NET server hosting the HelloWorld instance, execute the call, and send back the returned String to the client.

(Before the JNBridgePro folks get peeved at me, let me quickly point out that the development experience there is going to be much the same: point their code-gen tool at the Java RMI server objects you want .NET to communicate to, and use those proxies as-is from C#.)

While tempting, there are some caveats to this approach. First, be careful when considering binary RPC-based approaches to interop, because the interface-based code-gen approach carries with it a nasty side effect: once published, a given interop endpoint can never be modified again without requiring all of its clients to also change with it. While this isn’t a major consideration during development of the project initially, it can be devastating when attempting to refactor code later, after the system has been initially released. This kind of tight coupling works against many agile projects, so choose your interfaces (whether Java or .NET based) with care. (And before the comments start flying, let’s be very clear about this: the tight coupling descends from the proxy-based code-generation approach, and not anything to do with the tools themselves. WSDL-based code-generated proxies fall into the same trap.)

Secondly, using either of these tools assumes that you will never need to branch beyond the Java and .NET platforms; should you have to incorporate Ruby or “legacy” C++ into the mix, for example, you’re out of luck. This is where the “open-ended” interoperability of the WS-* stack (or its conceptual predecessor, CORBA) holds its own, and if there’s any reason to suspect that you’ll need to reach beyond the JVM and CLR, you should consider an IIOP-based or WS-*-based solution. (Be careful, however, since as of this writing I’m not aware of any Ruby-CORBA packages, so even CORBA could be a dead end if you need to plug Ruby into the mix.)

Thirdly, remember that out of the box, these tools generally focus on cross-process communication, and so that means that each method call across the boundary is not only a platform shift, but also a network traversal. Loosely translated, that means “hideously expensive” in performance terms. Even those toolkits that offer support across shared memory channels still go through the marshaling/unmarshaling process, so it’s still not as cheap as an in-proc method call. As with most interoperability scenarios, try to minimize the amount of back-and-forth between the two platforms. (That having been said, however, the JNBridge blog shows how to embed Swing components inside of a WinForms form, which represents a powerful idea and one that shouldn’t be discarded out-of-hand. Just be sure to perf-test.)

The tight-coupling concern is a biggie, however, so in future installments we’ll look at ways to avoid it by using messaging tactics, instead of RPC-based ones. Until then, remember, Java and .NET are like your kids: you love them both… “the same”.

(Shortly after publication, Wayne Citrin of JNBridgePro posted a comment that I felt merited reprinting here. Unedited, it appears below.)

Ted –

Thanks for writing about JNBridgePro. I do have a couple of comments on the interop post.

- You mention that J-Integra is “.NET-friendly” and we (JNBridgePro) are the opposite. (Presumably, “Java-friendly”.) I don’t think that’s the case, since (1) our proxy tool is written in .NET, and J-Integra’s is written in Java, and (2) J-Integra exposes the low-level details of .NET Remoting to the user, while we hide those details (which is friendly no matter where your development experience lies). In any case, we try to make the product user-friendly whether your background is in Java or in .NET.

- While both JNBridgePro and J-Integra both use .NET Remoting, there are more differences between the two products than might be evident from your post. Enumerating them is beyond the scope of this comment, but one that jumps out from your J-Integra example is that for Java-calling-.NET scenarios, J-Integra requires that the accessed objects be .NET-Remotable components: either MarshalByRefObject (if they’re being accessed by reference) or ISerializable (if they’re being accessed by value).JNBridgePro allows the Java code to call _any_ .NET object (MarshalByRefObject, ISerializable, or anything else).

- Similarly, for .NET-to-Java directions, with JNBridgePro the .NET code can access _any_ Java object or class; it doesn’t need to be RMI-remotable.

- The “in-process” vs. “RPC-interop”/”across-the-wire” dichotomy doesn’t entirely hold up. (You do touch upon this at the end of your post, but I wanted to elaborate.) While JNBridgePro does support “across-the-wire” (what we call “socket-based”) interop, as you mention we also offer a shared-memory communications mechanism that allows the CLR and the JVM to run in process. This mechanism is very popular with our users, and is much faster than the socket-based approach. (You’re correct that it still needs to go through the marshalling/unmarshalling mechanism, so there’s overhead, but you avoid the overhead of traversing the socket stack and doing process switching.) Unlike IKVM, our shared-memory approach is still a bridging solution, and still uses .NET Remoting, which is evidence of the power and flexibility of the .NET Remoting mechanism.

- Thanks for pointing out the GUI-embedding blog entry. The support code mentioned in that blog entry has now been integrated into our new version 3.1, which makes this type of embedding a lot simpler. We’ve updated the blog entry to reflect that.

Wayne

(Readers are, of course, encouraged to download both and form their own opinions.)




Sunday, January 21, 2007 5:43:39 PM (Pacific Standard Time, UTC-08:00)
Comments [0]  | 
Interop Briefs: In-proc interop with IKVM

(This originally appeared on 8 November 2006 as an entry on TheServerSide's blog. The title there was erroneously called "A look at out-of-proc or RPC interop", which is completely nonsensical, since this entry had nothing at all to do with out-of-proc or RPC. I've since corrected the title, and fixed the horrendous formatting problems that appeared there, as well.)

For years, the concept of “Java-.NET interoperability” has been wrapped up in discussions of Web services and the like, but in truth there are a bunch of different ways to make Java and .NET code work together. One such approach is to host the JVM and the CLR inside the same process, using a variety of tools, such as the open-source project IKVM (a part of the Mono project).

IKVM isn’t a “bridge” tool, like other interop technologies—instead, IKVM takes a different path entirely, doing bytecode translation, transforming Java bytecode into CIL instructions, and feeding them through the traditional CLR as such.

This means that Java classes basically become .NET assemblies, and executed using the CLR’s execution engine. The JVM itself, technically, is never loaded—instead, the CLR essentially becomes a JVM, capable of executing Java classes. This also means, then, that the various features that accompany the JVM, such as Hotspot execution of Java bytecode, the JVM garbage collectors, and the various JMX-related monitoring tools that are part of Java5 and later, will not be present, either.

IKVM comes in two basic flavors—a runtime component that’s used to load and execute Java classes from .class binaries, and a precompiler/translator tool, ikvmc, that can be used to translator (or cross-compile, if you will) Java binaries into .NET assemblies. While the second option generally yields faster execution, the first is the more flexible of the two options, as it doesn’t require any preparation on the part of the Java code itself.

Using IKVM to load arbitrary Java code and execute it via Java Reflection turns out to be fairly easy to do; so easy, in fact, that you can use it from Visual Basic code. After adding the IKVM assembly to a VB.NET project, write:

Imports IKVM.Runtime
Imports java.lang
Imports java.lang.reflect

Imports jlClass = java.lang.Class
Imports jlrMethod = java.lang.reflect.Method

The first line just brings the IKVM.Runtime namespace into use, necessary to make use of the “Startup” class without having to fully-qualify it. The next two lines bring in parts of the Java runtime library that ship with IKVM (the GNU Classpath project, precompiled to CIL using ikvmc and tweaked as necessary to fit the CLR’s internals). Similarly, the last two lines create an “alias”, such that now the types “jlClass” and “jlMethod” are now synonyms for “java.lang.Class” and “java.lang.Method”, respectively—we want this because otherwise we’ll run into name clashes with the CLR Reflection APIs, and because it helps cut confusion about which Reflection we’re working with.

Module Module1
  Sub Main()
    Dim properties As Hashtable = New Hashtable
    properties("java.class.path") = "."
    Startup.SetProperties(properties)

Next, we create a Hashtable object to hold a set of name-value pairs that will be passed to IKVM in the same manner that we pass “-D” properties to the Java Virtual Machine on the command-line. In this particular case, I’m (redundantly) setting the CLASSPATH to be the current directory, causing the JVM to look for code there along with the usual places (rt.jar and the Extensions directory inside the JRE). “Startup” is a static class, meaning there’s no instance thereof.

    Startup.EnterMainThread()

To quote the vernacular, we’re off and running. By calling “EnterMainThread”, IKVM is now up and running, ready to start taking on Java code. Our next task is to find the code we want to execute via the standard Java ClassLoader mechanism, find the “main” method exposed thereon, create the String array of parameters we want to pass, and call it, all via traditional Java Reflection APIs, but called through IKVM instead of through Java code itself.

    Dim sysClassLoader = ClassLoader.getSystemClassLoader

    Dim cl1 As jlClass = jlClass.forName("App", True, sysClassLoader)

    Dim paramTypes As jlClass() = { _
      jlClass.forName("[Ljava.lang.String;", True, sysClassLoader) _
    }
    ‘ java.lang.Class has an implicit conversion operator to/from Type
    ‘Dim paramTypes As jlClass() = { _
    ‘ GetType(String()) _
    ‘}

    Dim main As jlrMethod = cl1.getDeclaredMethod("main", paramTypes)

In the lookup for the “main” method, notice how there are two different ways to specify the method parameters: one, using the JVM syntax to specify an array of Strings (“[Ljava.lang.String;” as given in the Java Virtual Machine Specification), and the other using IKVM’s ability to translate types from .NET to Java, which allows us to specify it as a “String()” in VB (or “String[]” in C#).

    Dim parms As Object() = { _
      New String() {"From", "IKVM"} _
    }

    Dim result = main.invoke(Nothing, parms)

We create the array of Strings to pass, then call invoke(), passing “Nothing” (the VB synonym for C#'s null) for the object instance, as per the usual Java Reflection rules. At this point, the “App.main()” method is invoked, and when it returns, the Java code has completed execution. All that is left is to harvest the results and display them, and shut IKVM down appropriately.

    If result <> Nothing Then
      Console.WriteLine(result)
    Else
      Console.WriteLine("No result")
    End If

    Startup.ExitMainThread()
  End Sub

End Module

Using IKVM is not a silver bullet, but it does offer some powerful in-proc interoperability options to the development team looking to leverage both .NET and Java simultaneously, such as calling out to Java EJB servers from within Excel or Word documents, or loading Spring into Outlook in order to evaluate incoming mail messages and process them for local execution.


.NET | Java/J2EE | Windows

Sunday, January 21, 2007 12:38:25 AM (Pacific Standard Time, UTC-08:00)
Comments [0]  | 
 Saturday, January 20, 2007
Javapolis 2006 Interview w/Neal Gafter available

The first of the interviews I did at Javapolis 2006 is now available, this one with Neal Gafter. It's an interesting chat, particularly the parts where he discusses the two closures proposals being tossed around the Java space.


.NET | Conferences | Java/J2EE | Ruby

Saturday, January 20, 2007 8:56:59 PM (Pacific Standard Time, UTC-08:00)
Comments [0]  | 
 Thursday, January 18, 2007
Interop Briefs: Begin at the Beginning...
(Originally appeared as a DevelopMentor article on TheServerSide.com; updates and changes to the piece have been made in accordance with the time difference, roughly two years since its original publication, and some changing beliefs on my part, which I will elucidate further in a future piece.)

In the halcyon days of my youth, a major candy manufacturer ran an advertising campaign. It was destined to be a timeless classic, one that sticks with you for the rest of your life: a scene would be some typical meeting place (like a park or a street), one actor would walk from one end of the scene towards the other emerging from the other side. One would be carrying a jar of peanut butter, the other a chocolate bar, and of course, they would bump into each other, the chocolate falling into the peanut butter, and thus a new candy bar was "born". The tagline, of course, was "two great tastes taste great together".

So it goes with Java and .NET. Individually, each is a great platform, but together, a practical necessity in the modern enterprise. With enterprise development market share of 35-40% each, and the Microsoft/Sun settlement agreement of earlier this month, it's fairly obvious that neither of these two platforms is "going away" any time soon. Analysts estimate that by 2005, up to 90% of all IT shops will have both platforms running side by side. It's clear to even the most zealous Java or .NET devotee that working with both platforms is going to become the norm.

This means that developers will be facing an interesting task in the coming years: "make our .NET inventory management system talk to our J2EE customer relationship system", or "our sales staff wants to access our CRM system (written in J2EE) from Outlook", and so on. And while it would be nice to be able to hold up the Web services software stack, point to it and say, "Here's the answer to all your interoperability concerns", the practical and brutal reality of the situation is that it's nowhere near that simple an answer.


Making two platforms interact is at once a simple and difficult problem. Simple, in that it's a fairly closed-requirements solution: if I can work out a few technical details, interaction is achieved. It's also fairly easy to achieve success--if they can talk, you did it, if not, there's still work to go. In fact, once you've worked out low-level issues like byte order, file/data format, and hardware compatibility, basic interaction between any two platforms is pretty straightforward. (As a matter of fact, on this basis was the Internet built.)

But the problem of integration still presents hardships, owing to the rich complexity of systems that build on these basic low-level concepts. Merely because I can exchange TCP/IP packets between a Windows machine and a Solaris server does not mean that getting .NET code to exchange data with a J2EE server will be easy--far from it. Numerous hazards lie in wait for the budding integration developer.

Before we get too deep into the interoperability hazards, let's take a moment to revisit Enterprise Application Architecture in general, so as to get our bearings in the discussion to follow.

Historically, we've preferred "n"-tier systems to client/server 2-tier ones, because of the increased scalability intrinsic to "n"-tier systems. An "n"-tier system can scale to much higher user counts, due (among other things) to the shared database connections from a central middle tier to which clients connect. We also prefer the "n"-tier approach because it tends to allow for better separation of responsibilities in code: presentation-layer code goes on the client tier, business logic goes on the middle tier, and data-access code (largely represented by SQL) goes on the resource tiers either on or behind the middle tier machines. 3-tiers, 3 layers, but not always mapped one-to-one.

Drawing a distinction between the tiers and the layers is necessary for good interoperability between the platforms, because interoperability across layers is going to necessitate very different decisions than interoperability within layers. For example, if you have a Windows Forms .NET application that wants to display a Swing applications as a child window, very different decisions are in order than if you want that same Windows Forms applications to talk to a J2EE back end. Web services might suffice for the second requirement; it'll be an unmitigated disaster if you use Web services for the first. (See Fowler's "Patterns of Enterprise Application Architecture" or my "Effective Enterprise Java" for more about the layers-vs-tiers discussion.)


Interoperability can take one of three possible shapes: in-proc, out-of-proc, and resource sharing.

Of the three, resource sharing is perhaps the easiest to understand and recognize: using JDBC or ADO.NET, for example, a Java application can write data to a relational database that the .NET program can access via ADO.NET. The database access layers each deal with the necessary details to make the data comprehensible to the appropriate platform, leaving the programmer free to focus on working with the data itself. Unfortunately, a great deal of time is consumed in doing so, and trying to implement a short round-trip request/response cycle using an RDBMS is going to be difficult. Still, as an interoperability mechanism, it's by far the simplest and easiest approach to take, and as a result is the vast majority of the interoperability in production. In essence, we're exchanging data through some well-understood format and easily-accessible medium, in this case the relational database format described by SQL and a central database.

We can extend this raw data exchange in other ways, however, by leveraging the world's most popular interoperable data format, XML, as the format for data exchange and a variety of different data stores as the medium through which the exchange takes place. For example, it's relatively easy to take an XML document and store it to the filesystem from a servlet application for a .NET application to come around and pick up via a filesystem watcher thread. Or, thanks to the growing XML-in/XML-out capabilities of recent database releases, we can use the database as the exchange medium. Or anything else that's handy, for that matter; the key here is that the exchange format is XML data.

This presents its own problems, by the way--XML doesn't deal well with certain aspects of the object-oriented nature of Java and/or C#/.NET programs, such as the ability of objects to create cyclical relationships and bidirectional associations. Imagine, for a moment, a Person class like such:

public class Person
{
  private Person mother;
  private Person father;
  private ArrayList siblings;
  private Person spouse;
  private ArrayList children;
}
While this looks relatively simple to serialize to XML in the simple cases, remember that objects have identity, which means that "Jed's" wife could also be "Jed's" sister (in certain parts of the world). Serializing her twice in the XML document breaks object identity and creates further chaos.

SOAP Section 5 of the 1.1 specification sought to correct for this lack, but forgot that not all platforms that can consume XML are object platforms--a good number of them lack any concept of object references whatsoever, in fact. For this reason, SOAP Section 5 encoding (the "encoding" in "rpc/encoding") is deprecated in later Web services specifications, in favor of XML Schema Definitions (XSD) as a descriptive language for XML data (and "document/literal" as the means by which the services operate). When building systems that will need to interoperate against any and all possible platforms, it's been recommended to always start from schema definitions first, and build object definitions to match against that. (We'll visit this topic again in a future Interop Briefs piece fairly soon. --Ted) Both .NET and Java have libraries and/or specifications to deal with this: the XSD.exe utility and XmlSerializer in .NET (and now WCF and contracts in NetFX 3.0), and the Java API for XML Binding (JAXB) and Java API for XML Web Services (JAXWS) in Java.

This may all seem redundant--after all, who hasn't heard of XML as the suggested data exchange format? Take careful note, however, that we're talking about data exchange, not the use of XML as a communications stack, which of course brings us to the discussion of interoperability through Web services.

Web Services, as a technology, were born of the basic desire to "replicate a call stack in XML" (Don Box, private communication). At the time, it seemed natural enough: take the marshaled parameters from a remote call, and represent them using XML rather than a proprietary binary protocol, thus making it (theoretically) possible for other languages to consume that call without having to write a huge pile of parsing code. Initially, SOAP was available from DevelopMentor and Microsoft in Perl, Java, and COM-based formats.

But as time has progressed, so has the sophistication and scope of Web services. SOAP was rewritten to be a framing and extensibility specification, deferring all question of how to represent data to XSD. Description of Web services endpoints fell to WSDL. Discovery of services was left to UDDI. But within the last two years, things exploded in complexity; by latest count there are well over 30 specifications from a variety of author entities (Microsoft, IBM and BEA being three of the largest sponsors) covering everything from binary attachments (The recently-approved MTOM being the winner) to business process flow. More are coming.

More importantly, when Web services began to sweep the industry as the Next Big Thing, vendor toolkits began to offer extensions that allowed developers to start from the language interface and generate WSDL definitions to make it easy to reuse your existing technology investment by slapping angle brackets around the data traveling across the wire. Unfortunately, any out-of-process remoting API that suggests starting from a language-based interface (whether that be Java or C#) should be taken very skeptically (or, perhaps more accurately, carefully). Consider, for a moment, the following Java interface:

public interface Calculator
{
  public BigDecimal add(BigDecimal lhs, BigDecimal rhs);
}
what, precisely, should an XML-marshaled BigDecimal instance unmarshal to in .NET?

So often, demos done on the expo show floor clearly prove that the product knows how to talk to the same vendor's product on the other side of the wire, but rarely if ever demonstrates working with another vendor's product. So, for example, an ASMX Web Methods Web service can easily declare itself as returning a Hashtable, for example, but once marshaled and sent across the wire, what format should it resemble in the J2EE space? While Java certainly has its own implementation of Hashtable, there's no love lost between them in implementation details. As a result, it's a fair bet (barring special code to the contrary), the .NET Hashtable will get rendered into a custom data format that has little to no bearing on the .NET Hashtable in widespread use.

For these reasons, just as with data exchange using XSD, when writing WSDL-based services, always start with the "parts in the middle": in this case, the WSDL.

What's worse, few if any of these Web service specifications have a concrete implementation to work with, and fewer still have any sort of "work history" (that is to say, beta-testing and/or field-use) behind them. WS-Routing, for example, exists as an add-on to the Microsoft .NET Framework (Web Services Extensions 1.0), but as of yet no Java Web services software package currently has support for it. Neither Microsoft nor IBM or BEA have any implementation of WS-AtomicTransaction, and so on. (Note: at the time this was published, that was the case; both Microsoft and BEA have WS-AT implementations now, and WS-Routing has been dropped in favor of WS-Addressing. That said, though, a good number of the remaining specifications have shockingly little field use behind them, it seems.)

More importantly though, even a perfect Web services picture still leaves the story incomplete. Web services intrinsically imply remote process communication--no WS-* specification currently describes a way for two platforms to coexist in the same process space, for example. (In point of fact, there's really very little that Web services could say; how do you mandate an in-proc API for Python running in the same process as the CLR, or the JVM?) Interoperability within a given layer (presentation, business logic or data access) sometimes requires the ability to share data in the same process, yet all of the Web services space is focused on simply slinging angle brackets between endpoints across process boundaries. Making things even more interesting, interoperability at the resource tier--the database or the filesystem--is often "just enough" interoperability to make a system work without requiring a major investment.

The most intrusive approach to interoperability is the in-process approach, where a single process hosts both the JVM and the CLR simultaneously. At heart, both managed environments consist of a set of DLLs (JVM.dll in the case of Java, mscoree.dll in the case of .NET), making it fairly trivial to create a single process hosting both. One simple way to do this in Java, for example, is to write a Java Native Interface-defined method using Microsoft's Managed C++: write the Java native method in the usual manner, generate the C header using javah, then implement and compile the C++ code using the "/clr" switch. Because the JNI DLL is a managed code assembly, the .NET framework will automatically be loaded into the process, as usual, thus bringing both managed environments into the same process. Hosting Java from the CLR is a bit trickier, since it requires the explicit use of the JNI Invocation API, but again it's not rocket science.


There's obviously more to the Web services story than what's been covered here; discussions of particular RPC toolkits and ORBs, messaging frameworks/utilities, SOAP, and more, all even before getting into the Web services discussion. And, what's more, variations and hybrid approaches are quite feasible: a JMS consumer pulling TextMessages out of a Queue that contain a SOAP packet which is delivered via MSMQ by doing JNI methods to Managed C++.... and so on. Just bear in mind when considering your needs and options for your next Java/.NET integration project that multiple options are available to you beyond the traditional "Just set up a WSDL endpoint...."




Thursday, January 18, 2007 12:13:13 AM (Pacific Standard Time, UTC-08:00)
Comments [1]  |