This article assumes a rudimentary familiarity with Eclipse. We will talk about the eBay Development Environment (EDE), which is based on Eclipse V3.2 and requires JDK V5.0 or later (see Resources for links). Some familiarity with Web development, including HTML, JavaScript, and CSS, is useful, but not required.
Eclipse is known for being a Java IDE with a great plug-in system. The Eclipse V3.3 (Europa) release of Eclipse brought with it several specialized distributions of Eclipse. These included Eclipse for Java developers and Eclipse for Java EE developers. In addition, you can use the Eclipse C/C++ Development Toolkit (CDT) and the Eclipse PHP Development Toolkit (PDT).
All of these distributions are simply the base Eclipse platform plus some combination of plug-ins. That is the beauty of Eclipse. Even all of the usual Java development tools that most people think of as being integral to Eclipse are actually just plug-ins. If you are doing PHP development, you don't need to bother with a Java builder after all. Java, C++, and PHP are all programming languages and, thus, pretty broad topics themselves. However, your system is bound to have needs that are much more specialized than some other system that may use the same programming language.
Shouldn't your IDE be as specialized as your system? That is the philosophy behind Eclipse, and that is exactly the principle used at eBay to create the EDE based on Eclipse. Let's take a look at eBay's architecture so we can understand its special needs and how eBay uses Eclipse to fit those needs.
An entire book could be written just to describe the many aspects of eBay's architecture and history. This article will concentrate on eBay's presentation architecture, how it has evolved, and the special needs eBay has addressed using the Eclipse platform. We will take a brief look at this history of the eBay architecture to understand the challenges addressed by the current architecture.
eBay was originally launched as AuctionWeb in 1995. The original site was written in Perl. As the site grew, it was rewritten with a C++ back end and a front end that made use of XSL. Using XSL to generate HTML was very cutting-edge back in the late 1990s. eBay went public in 1998 and continues to see exponential growth.
Constantly mounting pressure from traffic forced a massive rewrite of the back end of eBay in the Java programming language starting in 2001. The front-end architecture was not changed. The Java+XSL architecture is internally referred to as the V3 architecture, with Perl being V1 and C++/XSL as V2. The V3 architecture proved to be massively scalable, allowing eBay to grow to its current size as one of the world's most visited sites. It's not just a high-traffic site but a high-transaction site with millions of people listing, bidding on, and buying items in dozens of countries around the world. Of course, no solution is perfect, and this is especially true of a system that is growing constantly, such as eBay's.
From a back-end perspective, the V3 architecture tackled some of the hardest problems that can be created by a Web application. From a pure data perspective, eBay can be described as having a huge number of frequent writes, as well as reads, with an extremely low tolerance for error or inconsistency. After all, we are talking about people's money here. Not too many people will notice or be upset by a flaw in a search index or a news aggregator, but most people will immediately notice an error when it comes to money they had bid with in an auction. Similarly, it might be acceptable if the amount of time it takes to receive an e-mail or instant message is hard to predict, but people expect to know that they have been outbid on an auction immediately. The V3 architecture addressed these incredibly hard problems, but there are many difficult front-end problems you also face when you are as successful as eBay.
For example, when you have a huge, sprawling Web site, something seemingly as trivial as managing all of the images on that site can become quite complex. Let's say you want to do some house-cleaning and delete an image. How can you tell if it is being used? In an XSL-based system, all you can do is search through millions of lines of XSL (millions of lines of text). Even that can be incomplete since XSL can easily append strings together, so the final string representing the image may not be found in one piece. This is not just true of XSL but it is true of any text-/script-based front-end architecture.
Images are just the tip of the iceberg. As eBay modernized, it made heavier and heavier use of Cascading Style Sheets (CSS). It is often more efficient to put CSS in its own external file, rather than in-line it on a page so browsers can cache it. It's even better if you can reuse these CSS files across pages, again so you can benefit from browser caching. But let's say you need to change a style on one page. How do you tell if this affects other pages? The above scenario can be played out for JavaScript, as well.
Have you ever moved a page on a Web site? You need to make sure you change all the links to that page. Now imagine doing that for a site the size of eBay. Again, you are stuck launching massive text searches for all the variations of the string representation of that link.
Remember when portals started becoming popular? In many ways, they were the precursors to modern mash-ups — sort of like local mash-ups. Typical portal-type pages involve elements from other pages, and that usually means CSS and JavaScript. Now you enter the possibility of conflict: The same-style name-like title could be used in multiple places, but with different values. Similarly, the same JavaScript functions or variables could be defined in multiple places. Even if there is no conflict, you could still have duplication, where the same exact data (CSS or JavaScript) is occurring two, three, or more times on a page. These kinds of problems are not easily solved using eBay's old XSL-based front-end architecture. You must rely on text searches.
Finally, there is perhaps the biggest problem of all: localization. A global Web site like eBay is translated into more than 30 languages. Even on a superficial basis, an XSL-based system requires that every XSL file be localized. You might smirk while thinking, "Just use properties files like Java's ResourceBundles." Think again. How do you account for text that is gender-specific in certain languages? Or even singular variations, such as "There is 1 bid" vs. "There are 2 bids." What about images that must be localized? How about localization that requires different markup (like the placement of a link within a sentence) for different locales?
All of these factors forced eBay to localize each XSL file. Do not forget that XSL is code, so something as trivial as changing the wording on a page required a new code release to be rolled out to thousands of servers.
Few Web sites encounter these problems. Not surprising, since no open source framework solves all of these problems. eBay needed to build a very smart, very specialized tool. And that is exactly what it did.
Just as eBay solved some tricky back-end scalability problems with the V3 architecture, it took to task-solving difficult front-end scalability problems with a new front-end architecture dubbed V4. The V4 architecture took the approach of representing everything that was going to be used on the front end with strongly typed Java objects on the back end. Does your page use an image? Then there is a Java object for that image. If you want to delete that image, it's as simple or as complex as deleting any other Java class. The same can also be said for links, CSS, and JavaScript. V4 does not use servlets or JSPs to create HTML. Instead, the actual HTML DOM is represented in the Java language, so you can wire together CSS and JavaScript on the server.
What about the hardest problem of them all: content? V4's content system is unique and powerful. It uses its own XML-based language to create content contracts. The choice of the word contract is intentional. Contracts define what kind of data is needed to create any variation of a piece (unit) of content. For example, a particular unit may need an integer and a string in English (like "Raymond has 4 cars"), but requires two integers and a string in another language. There may also be multiple variations for gender and cardinality. The contract defines all of this in XML. The contract is then implemented in each language supported by a particular application/page/component. And, of course, it has to be represented as a strongly typed object in Java that requires all of the dynamic data (like "Raymond" and "4" above) to be supplied in order for it to be used. Because everything involved are strongly typed Java objects, everything is enforced at compile time. If an application developer doesn't give the two parameters in his Java code, the code won't compile.
All of these Java representations of everything sound great on paper. However, you can imagine that they could create quite a burden if you had to write a new Java class every time you wanted to use an image or some JavaScript on a page. This is where Eclipse steps in.
Now that we understand the problem space and the desired solution, we can find how Eclipse helped eBay implement the solution. A lot of the code described above — code for representing images, links, styles, and JavaScript — can be thought of as boilerplate code, or at least partially boilerplate code. This is a common problem of frameworks. They require some type of code that is mostly just needed by the framework. Some frameworks use proxy objects or byte-code manipulation for this. This can make for difficult debugging or poor performance. The V4 framework uses a different technique: code-generation tools. If you need a Java object to represent your JavaScript, it is better to actually have that object around, but it is even better if you do not have to write the code for it. Instead, you let an Eclipse plug-in write it for you.
The Java and Java EE editions of Eclipse make heavy use of code generators. They are typically in the form of wizards that generate numerous artifacts for you. For example, if you have used the Java EE, you may have used the New Dynamic Web Application wizard. This creates directory structures and the web.xml file for your Web application, so it can easily be zipped up into a WAR file and distributed to a Web container. The code generators created by eBay serve a similar purpose: They create boilerplate code for you, so you can concentrate on your application code, the oft-hailed "business logic" of your application.
Let's take a look at a couple of the code-generating Eclipse plug-ins created by eBay as part of the tools for the V4 framework.
JavaScript is the language of the Web, and it is very important in V4. The V4 framework allows for JavaScript to be coded in the usual way, but with a few special constructs. It uses an object-oriented syntax native to JavaScript, though not required by it. It also uses the code-commenting syntax from the open source project JsDoc to specify extra meta-data about JavaScript classes. These two things work together to allow the generation of a JavaScript reference (JsRef) class per JavaScript class. This is a Java class that can be referenced inside any V4 DOM tree. Let's take a look at an example.
Listing 1. An eBay JavaScript class
vjo.needs("vjo.samples.classes.Person");
vjo.type("vjo.samples.classes.HelloPerson")
.props({
/**
* @return boolean
* @access public
*/
helloPerson:function(){
var person1 = new vjo.samples.classes.Person();
person1.setName("John");
alert("Hello " + person1.getName());
return false;
}
});
|
The various vjo.* constructs mimic the constructs in Java class file declarations. The JsDoc annotations provide the strong typing JavaScript cannot provide. This allows an Eclipse plug-in to generate a JsRef for the JavaScript class as shown below.
Listing 2. The corresponding JsRef
package vjo.samples.classes;
import com.ebay.dsf.resource.pattern.js.JsType;
import com.ebay.dsf.spec.component.BaseComponentSpec;
import com.ebay.dsf.aggregator.jsref.internals.JsCmpMeta;
import com.ebay.dsf.spec.component.IComponentSpec;
import vjo.bootstrap.VjBootstrap;
import com.ebay.dsf.resource.pattern.js.JsResource;
import com.ebay.dsf.aggregator.jsref.JsObj;
import com.ebay.dsf.aggregator.jsref.JsFunc;
import com.ebay.dsf.jstojava.codegen.JsRefGenerator23;
import com.ebay.dsf.resource.pattern.js.IJsResourceRef;
import com.ebay.kernel.CodeGenerated;
/*
Generator: JsRefGenerator23 version: 2.3
Generated: Mon Jan 28 11:01:13 PST 2008
Source URL: file:/D:/Views/v4flash/v4samplecode/VjoSample/src/vjo/samples/
classes/HelloPerson.js
*/
/**
* <pre>vjo.needs("vjo.samples.classes.Person");
* vjo.type("vjo.samples.classes.HelloPerson")
* .props({
* //*
* * @return boolean
* * @access public
* //
* helloPerson:function(){
* var person1 = new vjo.samples.classes.Person();
* person1.setName("John");
* alert("Hello " + person1.getName());
* return false;
* }
* });
* </pre>
*/
@com.ebay.dsf.resource.utils.CodeGen(JsRefGenerator23.class)
@com.ebay.dsf.jstojava.codegen.JsRefGeneratorVersion(2.3)
public class HelloPersonJsr extends JsObj implements CodeGenerated{
private static final long serialVersionUID = 1L;
public static final JsResource RESOURCE = JsResource.viaName("HelloPerson");
public static class ResourceSpec extends BaseComponentSpec{
public static final IJsResourceRef REF = jsRef(RESOURCE, JsType.DefOnly);
private static volatile IComponentSpec s_instance;
public static IComponentSpec getInstance() {
if (s_instance != null) {
return s_instance;
}
synchronized (
ResourceSpec.class) {
if (s_instance == null) {
s_instance = new ResourceSpec();
}
}
return s_instance;
}
private
ResourceSpec() {
addJsRef(jsRef(RESOURCE, JsType.DefOnly));
addDependentComponent(VjBootstrap.ResourceSpec.getInstance());
addDependentComponent(vjo.samples.classes.PersonJsr.ResourceSpec.
getInstance());
}
}
protected HelloPersonJsr(JsCmpMeta cmpMeta, boolean isProto) {
super(cmpMeta, isProto);
}
/**
* @return boolean
@access public
* @jsfunc helloPerson
*
* function () {
* var person1 = new vjo.samples.classes.Person();
* person1.setName("John");
* alert("Hello " + person1.getName());
* return false;
* }
*/
public static final JsFunc<Boolean> helloPerson(){
JsFunc<Boolean> func = new JsFunc<Boolean> (getInstance(),
"helloPerson",true,true);
return func;
}
public static final JsCmpMeta META = new JsCmpMeta("vjo.samples.classes.HelloPerson",
"HelloPerson", ResourceSpec.getInstance());
private static volatile HelloPersonJsr s_instance;
private static HelloPersonJsr getInstance(){
addResourceSpec(ResourceSpec.getInstance());if (s_instance !=null){
return s_instance;
}
synchronized (HelloPersonJsr.class){
if (s_instance == null) {
s_instance = new HelloPersonJsr(META,false);}return s_instance;}
}
}
|
This is all made simple and straightforward for the developer using Eclipse tools. You can simply right-click on a JavaScript file and generate the Java code you need, as shown below.
Figure 1. Using Eclipse to generate the JsRef
The JsRef can then be used programmatically in Java code. This makes it easy to wire up JavaScript in Java code. For example, maybe you want to call the above JavaScript to validate a form when a user clicks a button.
Listing 3. Wiring up client-side events on the server
DButton button = new DButton("Hello Person - click me");
button.add(EventType.CLICK, HelloPersonJsr.helloPerson());
|
The JsDoc annotations also make it easy to track dependencies, since it winds up just using a Java import structure. You don't have to remember to include other JavaScript libraries your JavaScript relies on. You simply state the dependency in the code. If you change the JavaScript — say, adding a new parameter to a function — this will cause compilation errors on code using it, unless you refactor that code as well. The package syntax also provides an obvious name space for the JavaScript to prevent collisions. You get all of these benefits from having a Java class represent the JavaScript, but with the help of Eclipse plug-ins, minimal extra work is required to get these benefits.
JavaScript is just one of the parts of a Web application that is handled in a unique way by eBay's V4 framework and the Eclipse plug-ins that empower developers to use V4. Another important example is CSS.
The V4 approach to JavaScript is to keep the native JavaScript and just to proxy it with Java code. The approach for CSS is a little different. JavaScript is a complex programming language in its own right. CSS can be complicated, but certainly not at the same level as JavaScript. For CSS, the CSS files are only used as a starting point. They are used to create a Java class that it used at runtime to generate CSS. The original CSS file can be thrown away. It is the Java class that becomes part of source control, whereas, it is the actual JavaScript file that is checked in, and the JsRef is generated by Eclipse on developer systems or by the build system for code being rolled out to production. Still, it is often more natural to start with CSS, maybe from a visual mock-up of some sort.
So eBay has built Eclipse plug-ins for working with the CSS and "bootstrapping" the creation of the Java-CSS (JCSS). In Listing 4, we see a typical CSS file.
Listing 4. A CSS file
* {
margin: 0;
padding: 0;
}
body {
font-size: 100.01%;
font-family: Verdana,sans-serif;
padding: 10px;
text-align: center;
}
h1, h2, h3, h4, h5 {
font-family: Georgia,serif;
}
h1 {
color: #9A351D;
background-color: transparent;
margin: 1em 0;
}
h3 {
font-size: .9em;
}
div h3 {
color: #58B;
text-transform: uppercase;
font-size: .7em;
}
div h3:before {
content: "by";
font-style: italic;
text-transform: none;
color: #000;
display: block;
margin-bottom: 1em;
}
h4 {
text-align: center;
font-style: italic;
color: #666;
margin: 2em 0 0 0;
font-size: .7em;
font-weight: normal;
}
.footer {
color: #999;
font-size: .5em;
font-family: Verdana,sans-serif;
font-weight: normal;
}
|
Once again, we can use a right-click in Eclipse to access the JCSS plug-in and create the JCSS class.
Figure 2. Using the JCSS plug-in
This will generate a Java class.
Listing 5. The corresponding JCSS class
package com.ebay.css.example;
import com.ebay.dsf.css.CssClassConstant;
import com.ebay.dsf.javatocss.JCssDef;
import com.ebay.dsf.javatocss.JCssStyleRule;
import com.ebay.dsf.javatocss.prop.BackgroundColor;
import com.ebay.dsf.javatocss.prop.Display;
import com.ebay.dsf.javatocss.prop.FontStyle;
import com.ebay.dsf.javatocss.prop.FontWeight;
import com.ebay.dsf.javatocss.prop.TextAlign;
import com.ebay.dsf.javatocss.prop.TextTransform;
import com.ebay.kernel.CodeGenerated;
/*
Generator: class com.ebay.dsf.csscodegen.generator.def.JCssDefGenerator
version: 1.0
Generated: Mon Jan 28 17:37:36 PST 2008
Source: com.ebay.css.example cover.css
*/
/**
* <pre>
* {margin:0; padding:0}
body {font-size:100.01%; font-family:Verdana, sans-serif; padding:10px;
text-align:center}
h1, h2, h3, h4, h5 {font-family:Georgia, serif}
h1 {color:#9a351d; background-color:transparent; margin:1em 0}
h3 {font-size:0.9em}
div h3 {color:#58b; text-transform:uppercase; font-size:0.7em}
div h3:before {content:"by"; font-style:italic; text-transform:none;
color:#000; display:block; margin-bottom:1em}
h4 {text-align:center; font-style:italic; color:#666; margin:2em 0 0 0;
font-size:0.7em; font-weight:normal}
.footer {color:#999; font-size:0.5em; font-family:Verdana, sans-serif;
font-weight:normal}
* </pre>
*/
public class CoverJCssDef extends JCssDef implements CodeGenerated {
private static final String SCOPE_NAME = "";
public interface Clz {
/**
* <pre>
* .footer {color:#999; font-size:0.5em; font-family:Verdana, sans-serif;
font-weight:normal}
* </pre>
*/
CssClassConstant footer_ = new CssClassConstant(SCOPE_NAME, "footer");
}
private static CoverJCssDef s_instance= new CoverJCssDef();
public static CoverJCssDef getInstance(){
return s_instance;
}
public static interface DEFAULT {
public static final JCssStyleRule STYLE_RULE_1 = s_instance.rule()
.select(any)
.set( properties()
.margin("0")
.padding("0"));
public static final JCssStyleRule STYLE_RULE_2 = s_instance.rule()
.select(body)
.set( properties()
.fontSize("100.01%")
.fontFamily("Verdana, sans-serif")
.padding("10px")
.textAlign(TextAlign.CENTER));
public static final JCssStyleRule STYLE_RULE_3 = s_instance.rule()
.select(h1)
.select(h2)
.select(h3)
.select(h4)
.select(h5)
.set( properties()
.fontFamily("Georgia, serif"));
public static final JCssStyleRule STYLE_RULE_4 = s_instance.rule()
.select(h1)
.set( properties()
.color("#9a351d")
.backgroundColor(BackgroundColor.TRANSPARENT)
.margin("1em 0"));
public static final JCssStyleRule STYLE_RULE_5 = s_instance.rule()
.select(h3)
.set( properties()
.fontSize("0.9em"));
public static final JCssStyleRule STYLE_RULE_6 = s_instance.rule()
.select(div.desc(h3))
.set( properties()
.color("#58b")
.textTransform(TextTransform.UPPERCASE)
.fontSize("0.7em"));
public static final JCssStyleRule STYLE_RULE_7 = s_instance.rule()
.select(div.desc(h3.pseudoBefore()))
.set( properties()
.content("\"by\"")
.fontStyle(FontStyle.ITALIC)
.textTransform(TextTransform.NONE)
.color("#000")
.display(Display.BLOCK)
.marginBottom("1em"));
public static final JCssStyleRule STYLE_RULE_8 = s_instance.rule()
.select(h4)
.set( properties()
.textAlign(TextAlign.CENTER)
.fontStyle(FontStyle.ITALIC)
.color("#666")
.margin("2em 0 0 0")
.fontSize("0.7em")
.fontWeight(FontWeight.NORMAL));
public static final JCssStyleRule STYLE_RULE_9 = s_instance.rule()
.select(any.with(Clz.footer_))
.set( properties()
.color("#999")
.fontSize("0.5em")
.fontFamily("Verdana, sans-serif")
.fontWeight(FontWeight.NORMAL));
}
}
|
This file represents our style definitions. As a matter of separation of concerns, a separate class is used for realizing the CSS in an HTML document. Of course, this class is also generated by an Eclipse plug-in.
Figure 3. Using plug-in to generate CSS realizer
An example of a plug-in-generated realizer class is shown below.
Listing 6. The generated CSS realizer
package com.ebay.css.example;
import com.ebay.css.example.CoverJCssDef;
import com.ebay.dsf.css.CssClassConstant;
import com.ebay.dsf.csscodegen.generator.realizer.CssRealizerGenerator;
import com.ebay.dsf.csscommon.BaseCssRealizer;
import com.ebay.dsf.html.dom.BaseCoreHtmlElement;
import com.ebay.dsf.resource.pattern.css.CssResource;
import com.ebay.kernel.CodeGenerated;
/*
Generator: class com.ebay.dsf.csscodegen.generator.realizer.CssRealizerGenerator
version: 2.0
Generated: Tue Jan 29 15:20:08 PST 2008
Source: com.ebay.css.example.CoverJCssDef
*/
/**
* <pre>
* {margin:0; padding:0}
body {font-size:100.01%; font-family:Verdana, sans-serif; padding:10px;
text-align:center}
h1, h2, h3, h4, h5 {font-family:Georgia, serif}
h1 {color:#9a351d; background-color:transparent; margin:1em 0}
h3 {font-size:0.9em}
div h3 {color:#58b; text-transform:uppercase; font-size:0.7em}
div h3:before {content:"by"; font-style:italic; text-transform:none;
color:#000; display:block; margin-bottom:1em}
h4 {text-align:center; font-style:italic; color:#666; margin:2em 0 0 0;
font-size:0.7em; font-weight:normal}
.footer {color:#999; font-size:0.5em; font-family:Verdana, sans-serif;
font-weight:normal}
* </pre>
*/
@com.ebay.dsf.resource.utils.CodeGen(CssRealizerGenerator.class)
public class CoverCssr extends BaseCssRealizer implements CodeGenerated {
/** Answers the actual text this realizer was genned from */
public static final String gentext =
"* {margin:0; padding:0}\n"
+ "body {font-size:100.01%; font-family:Verdana, sans-serif; padding:10px;
text-align:center}\n"
+ "h1, h2, h3, h4, h5 {font-family:Georgia, serif}\n"
+ "h1 {color:#9a351d; background-color:transparent; margin:1em 0}\n"
+ "h3 {font-size:0.9em}\n"
+ "div h3 {color:#58b; text-transform:uppercase; font-size:0.7em}\n"
+ "div h3:before {content:\"by\"; font-style:italic; text-transform:none;
color:#000; display:block; margin-bottom:1em}\n"
+ "h4 {text-align:center; font-style:italic; color:#666; margin:2em 0 0 0;
font-size:0.7em; font-weight:normal}\n"
+ ".footer {color:#999; font-size:0.5em; font-family:Verdana, sans-serif;
font-weight:normal}\n"
;
public static final CssResource src = CssResource.viaDef(
CoverJCssDef.getInstance());
public static final Classes classes = new Classes() ;
public static final Utils utils = new Utils() ;
/**
* <pre>
* .footer {color:#999; font-size:0.5em; font-family:Verdana, sans-serif;
font-weight:normal}
* </pre>
*/
public static final class Classes {
private Classes() { /* prevent instantiation */ }
private static final CssClassConstant s_footer = new CssClassConstant("footer");
/**
* <pre>
* .footer {color:#999; font-size:0.5em; font-family:Verdana, sans-serif;
font-weight:normal}
* </pre>
*/
public final CssClassConstant footer = s_footer;
}
public static final class Utils {
private Utils() { /* prevent instantiation */ }
/**
* <pre>
* .footer {color:#999; font-size:0.5em; font-family:Verdana, sans-serif;
font-weight:normal}
* </pre>
*/
public Utils addClass_footer(final BaseCoreHtmlElement element) {
addCssClass(element, Classes.s_footer);
return this;
}
/**
* <pre>
* .footer {color:#999; font-size:0.5em; font-family:Verdana, sans-serif;
font-weight:normal}
* </pre>
*/
public Utils setClass_footer(final BaseCoreHtmlElement element) {
setCssClass(element, Classes.s_footer);
return this;
}
}
}
|
The realizer makes it easy to attach styles to any visual element. Alternatively, you can register one or more JCSS definitions on a page for defining the default styles. An example of both of these techniques is shown below.
Listing 7. Using JCSS
// Create a div, attach a style to it
DDiv footer = new DDiv();
CoverCssr.utils.addClass_footer(footer);
// create DOM, register the CSS for it
HtmlDisplayer2 doc = new HtmlDisplayer2(footer);
doc.registerCss(CoverJCssDef.getInstance());
|
Again, we gain the benefits of having a name space (the JCSS package), so at runtime, our CSS will not collide with anybody else's CSS. We get this advantage while still being able to take advantage of "native" CSS. The key is the use of the Eclipse plug-in to bridge the gap between the CSS and the JCSS.
By now, you are seeing the pattern. V4 needs all of these strongly typed constructs, and Eclipse makes it much easier to provide and work with all of this. We mentioned the most challenging type of resource in V4: content. Let's take a look at how Eclipse helps with that.
The V4 content system relies on content contracts. These have their own XML language, but once again, the use of an Eclipse plug-in makes it possible to get a more intuitive editor for these contracts.
Figure 4. V4 content structured editor
We need Java code to be generated to represent the content contract, and once again, we have Eclipse ready to generate this for us.
Figure 5. Generating Java code for content contract
Content contracts have a powerful syntax, letting them describe the complicated structures found in eBay applications. This leads to an expressive API that is straightforward to use, but would be tedious to write by hand. The plug-ins make that a nonissue.
As you have seen, eBay takes advantage of the Eclipse plug-ins to generate code for developers in numerous scenarios. These aren't the only kind of plug-ins written by eBay. Let's take a look at some of the other types used by eBay and what kind of needs they address.
The V4 system also offers unique ways to run applications and to debug them because of how it uses Java to represent all of the elements of a Web page. This can provide important gains in productivity for you, making it easier to develop applications and debug them once deployed.
Running a Web application from Eclipse
Have you ever wished you could run a Web page without having to deploy to and start or restart a Web server? With eBay's V4 plug-ins for Eclipse, this is possible.
Figure 6. Running a Web application as a "dervlet"
You may be asking, "What is a dervlet?" As the name implies, it is similar to a servlet. The V4 framework allows these to be used as bootstrapping classes for quick prototyping and testing of a Web application. It is similar to having a class with a main method used for testing other classes in the package. All you have to do is right-click and run as dervlet. Obviously, you can also debug as dervlet and step through your code like any other executable. Behind the scenes, the Eclipse plug-in is starting an embedded version of the Jetty servlet container, then opening a Web browser to a URL served by Jetty.
This Eclipse plug-in makes it easier to debug a V4 application during development. The V4 framework and Eclipse can go even further by making it easier to debug an application in production.
Debugging a production application from Eclipse
The V4 framework is a component framework. When you have everything as Java classes, a natural, object-oriented next step is to encapsulate these various classes that are working together as a component. This provides highly reusable components and can further increase developer productivity. If you look at an eBay Web page, chances are, you are looking at a collection of V4 components. This is not only great for creating applications quickly but also lends itself to introspecting a running application.
Figure 7. An eBay page with Spyglass
Notice all of the red boxes? Each of these is a V4 component. Hovering your mouse over any box shows the fully qualified name of the component. If there is some visual defect on the page, it's pretty easy to figure out what piece of code (component) is causing the problem. V4 goes one step further by helping you get to that code instantly. Notice the links in the blue box? eBay developers can go directly to Eclipse from any production eBay V4 page. Try doing something like that with XSL, JSPs, or anything else. This is accomplished by running a listener server from Eclipse. The listener is another plug-in written by eBay that leverages the eBay architecture to help developers using Eclipse.
We talked about the unique challenges faced by eBay. We have seen how eBay has picked a demanding architecture to solve these problems. This kind of architecture could only be employed with powerful tools to keep developers from writing tedious boilerplate code. The Eclipse plug-in system is perfect for providing these kinds of tools, as well many other powerful tools for development and debugging. The problems and solutions described may be unique to eBay in some ways, but the techniques used are not. If your organization requires highly specialized architecture, you can borrow a page from eBay and create Eclipse plug-ins to help address this problem without hurting the productivity of your developers.
Learn
-
Read about a brief history of eBay in "How did eBay start?"
-
Learn about making your own Eclipse plug-ins in "Developing Eclipse plug-ins."
-
Doing Web development with Eclipse? You might want to read "Discover the Ajax
Toolkit Framework for Eclipse."
-
Jump-start your own development by creating Eclipse wizards with "Speed
development with Eclipse wizards."
-
Check out the "Recommended Eclipse reading list."
-
Browse all the Eclipse content on developerWorks.
-
New to Eclipse? Read the developerWorks article "Get started with Eclipse Platform" to learn its origin and architecture, and how to extend Eclipse with plug-ins.
-
Expand your Eclipse skills by checking out IBM developerWorks' Eclipse project resources.
-
To listen to interesting interviews and discussions for software developers, check out check out developerWorks podcasts.
-
Stay current with developerWorks' Technical events and webcasts.
-
Watch and learn about IBM and open source technologies and product functions with the no-cost developerWorks On demand demos.
-
Check out upcoming conferences, trade shows, webcasts, and other Events around the world that are of interest to IBM open source developers.
-
Visit the developerWorks Open source zone for extensive how-to information, tools, and project updates to help you develop with open source technologies and use them with IBM's products.
Get products and technologies
-
Download Java 5 or
Java 6.
-
Check out the latest Eclipse technology downloads at IBM alphaWorks.
-
Download Eclipse Platform and other projects from the Eclipse Foundation.
-
Download IBM product evaluation versions, and get your hands on application development tools and middleware products from DB2®, Lotus®, Rational®, Tivoli®, and WebSphere®.
-
Innovate your next open source development project with IBM trial software, available for download or on DVD.
Discuss
-
The Eclipse Platform newsgroups should be your first stop to discuss questions regarding Eclipse. (Selecting this will launch your default Usenet news reader application and open eclipse.platform.)
-
The Eclipse newsgroups has many resources for people interested in using and extending Eclipse.
-
Participate in developerWorks blogs and get involved in the developerWorks community.





