I’m sure many of you are as eager to read about developing Eclipse plug-ins as I am to write about them. But, before you can set out on that exciting trip, you have to take a quick look at what it takes to develop Java applications, in general, using Eclipse. Aside from learning how to use Eclipse’s Java Development Tools (JDT), this second installment of my series on Eclipse will help you develop appreciation of the Eclipse Workbench and its various visual components from a user’s perspective.
Introduction
Installing Eclipse is easy. Unpack the downloaded archive into an arbitrary directory in your filesystem. When done, you will find in it a sub-directory called eclipse, which contains the main eclipse executable (for example, on Windows platforms it will be eclipse.exe). Launch it to start the Eclipse Workbench.
To many companies in the software business, Eclipse is a platform (or Rich Client Platform—RCP, to be precise) on which they can base their products. To most Java developers, Eclipse is an Integrated Development Environment (IDE) with which they write Java software on a daily basis. In fact, Eclipse provides support for development in programming languages other than Java, such as C/C++, PHP, Ruby, Python, and more. Even within the Java family, one can write applications that range from J2EE to rich client to embedded.
In this article, you’ll briefly examine what it takes to create a Java application in Eclipse. To help you along the way, you’ll create a simple console application. Although the outcome is likely to be less than exciting, this exercise will takes you through some of the major concepts and functional groups in Eclipse and its Java Development Tools (JDT).
To follow the discussion in this article, you will need to have the Eclipse SDK 3.1 installed. If you don’t have it yet, you can follow the simple instructions provided in the sidebar.
Downloading The Eclipse SDK
To download a free copy of the Eclipse SDK, visit the Eclipse downloads page at http://www.eclipse.org/downloads. The recommended download—Eclipse SDK 3.1—displayed prominently in the top section, should be suitable for your particular platform and operating system. If you prefer to choose from all available downloads, click Other downloads for 3.1. Make sure, however, that you download the SDK rather than another, trimmed-down distribution package.
Way of the Workbench
Even before you start writing Java code, you need to familiarize yourself with the Eclipse Workbench and its various elements. This is because the Java Development Tools (JDT), as well as many other Eclipse-based development tools (such as PDE), build upon this framework to deliver their own functionality. As you already know, Eclipse is a component-based platform (components in Eclipse-speak are called plug-ins, or bundles) and Eclipse-based applications (such as the Eclipse SDK) are highly modular. Eclipse SDK itself consists of a mixture of plug-ins, which together make it what it is; other Eclipse-based applications may share some of those plug-ins, but usually bring along their own set of plug-ins that differentiate them.
At a high level, you can think of the Workbench as a window (or a set of windows) around which all of the visual elements of an application are organized. It is the window you’ll see when you launch your Eclipse SDK. Not all Eclipse-based applications must necessarily use the Workbench; in fact, it is possible to create “headless” applications that are completely driven from the command-line (or through other, non-visual means). However, complex rich-client applications, such as IDEs, are typically based on the Workbench. (In fact, what you’ll see in an IDE is typically the IDE Workbench, a special flavor of the Generic Workbench provided by Eclipse.)
A typical workbench window consists of the main application menu bar, toolbar, an editor area (into which editors may be opened), and several views. The selection of views and their layout within the window is called a Perspective. Perspectives are typically organized around some functional area or user activity, such as Java development, Resource management, and so on, depending on what your application provides. They are completely user-customizable; you can show any views available (click Window -> Show View) and rearrange them in any way you want (use your mouse to drag the view’s title bar around the window). To customize the perspective’s “Action Set” (in other words, the set of menu and toolbar items), click Window -> Customize Perspective… Many menu and toolbar actions can be invoked using a keyboard sequence, which—you guessed it—is also completely customizable (click Window -> Preferences, then enter your preferences under General -> Keys). When you restart your workbench, all your perspective customizations will be persisted across workbench sessions. You can even save your customized perspective under its own name (click Window -> Save Perspective As…). Figure 1 illustrates a customized layout of the Java perspective.
Other common visual elements you will encounter while working with the workbench are the various types of dialog boxes, or dialogs, for short. You have already seen them if you tried some of the perspective-related menus mentioned above. They are usually modal—meaning that you cannot access any other window or dialog until you close the one that’s currently active. Some dialogs take you through multi-step actions—these are called wizards. The telltale sign of a wizard is the set of Back, Next, Finish, and Cancel buttons at the bottom of it.
Workspace Resource Model
To understand the function of many standard menus and views in the IDE Workbench, you have to take a look at the model that most Eclipse-based tools use when interacting with the filesystem. Elements of this model are referred to as Resources. Resources are organized into a tree hierarchy that very much resembles the filesystem itself. In fact, all Resources are in one way or another linked to a physical filesystem element. The root of this model is called the Workspace. Its main role is to be the singleton instance of the Resource model within the application. It also provides API for workspace-wide management of resources. All Workspace contents are organized into Projects, which in turn contain Folders and Files. The idea behind Projects is to group resources (Files and Folders) that are closely related to each other. For example, the source of a Java application, or a library packaged into a JAR file, may be organized into one project. Projects may be linked together in a dependency graph.
Workspace settings and preferences (including those of all Projects) are stored in a special location in the filesystem called the Workspace location. You were probably asked to choose one right after you started your Eclipse SDK. (You can make your selection default and Eclipse won’t ask next time you run it.) This directory contains a sub-directory called .metadata, which is where all plug-ins’ Resource-related data is typically stored.
The Workspace location is not necessarily where all Projects physically reside. A Project may be assigned a location outside of the Workspace, which will serve as the root directory for all its Files and Folders. Typically, a File’s Project-relative path matches its physical filesystem path relative to its Project’s location (in other words, /myproject/myfolder/myfile.txt could map to c:myworkspacemyprojectmyfoldermyfile.txt, where c:myworkspacemyproject is the project’s location). However, it is also possible to create links to filesystem folders and files that may reside at a location outside of the Project’s subtree.
The Eclipse Resource model also supports the concept of Project builds. Without going into too much detail, plug-ins interested in participating in Project builds must register their Incremental Builder implementations, which will be invoked either directly by the user (through the menu), or automatically when some Resources change. This, for example, is what makes it possible for the Java builder to incrementally compile your Java code. Plug-ins associate their builders with projects by assigning them their Project Natures (for example, a project with the Java Nature has some Java-compilable code, but it could be a simple Java application, an Eclipse plug-in project, an EJB project, and so forth.)
Each Resource may be annotated with various kinds of Markers, which can carry an arbitrary set of properties. These are typically used for representing compilation errors, bookmarks, or search result matches. Markers are usually persisted across workbench sessions.
Projects may be shared among multiple workspaces (and machines and users) with the help of Team Support. This set of plug-ins provides the necessary infrastructure for plugging in various version control system implementations. The Eclipse Platform and SDK come with the default CVS team provider.
The Workspace maintains a limited change history for all its Resources. This makes it possible to recover previous versions of Files even without the use of a version control system (in other words, something like a filesystem-level “undo”). There’s a limit, however, to how much history is kept. Also, this history is local to the workspace and cannot be shared with other workspaces or team members. Therefore, it is not a substitute for a version control system.
Standard Menus
The Eclipse IDE Workbench provides a set of standard functions (typically accessible through the application menu and/or toolbar) and views available in all IDE applications. To see only the base set of menus, please switch to the Resource perspective and close any open editors.
Following the main menu from right to left, the one that I’m sure you’ll find most useful is Help. Choosing Welcome opens up a Web-page-like introduction to your Eclipse product (in this case, the Eclipse SDK). It is presented by default the first time you run the application. Selecting Help Contents will open a separate help window, which provides your application’s user and developer documentation in the form of hyperlinked Web pages. The documentation is fully searchable. Starting with Eclipse 3.1, there is Dynamic Help, which displays a set of topics relevant to your current workbench activity. Key Assist (also invoked by pressing Ctrl+Shift+L) is invaluable when learning the various keyboard shortcuts (the knowledge of which, trust me, is sure to make you look like an expert). Tips and Tricks will bring you to a special Help topic with helpful suggestions on how to make the most out of your application. Lastly, Cheat Sheets will walk you step-by-step through some common but potentially complex tasks.
Because of their plug-in-based architecture, Eclipse applications can usually be updated with the latest patches and new functionality using the built-in Configuration Management facility. It is accessible through Help -> Software Updates. Whether or not you can obtain online updates depends on your application vendor (Eclipse plug-ins typically come with a pre-configured Web site address of where to look for updates).
You already know some of the functions provided under the Window menu. Aside from managing perspectives, selecting views, and navigating between your views and editors, you can choose to open another workbench window—something very useful when working in a multi-monitor environment (note that each new window is based on the same logical workbench—you don’t actually start a new workbench session when you open another window). The very cool New Editor option will open up a new instance of the currently active editor. This will allow you to see (and edit) two or more different parts of the same file which would otherwise not fit into the same window (if you decide to try this and the new editor instance is opened in another editor tab, hiding the original one, just drag the tab to the bottom portion of the editor area—this will “tile” the two editor windows so that you can see both at the same time).
The ability to customize your application can sometimes be a mixed blessing—you have to make your way through a myriad of pages of settings, each often with its own tabs. However, the ability to customize preferences is very important to Eclipse, and thus its Preferences dialog (accessible through Window -> Preferences) has been optimized to support easy navigation and keyword filtering of the various preferences used by the application. All preferences are organized into logical groups, accessible through a tree-like navigator on the left-hand side. Because many preference settings depend on one another, links are provided to easily jump from one to another without having to search through the entire preference tree. The browser-like ability to trace your way back to previously visited preference pages saves you from having to remember the structure of your preference tree. Note that you can share your preference settings with other team members by exporting and importing them using the corresponding wizard (choose File -> Import/Export, then select the Preferences wizard).
The next menu in the main application menu bar is Run. The only standard function it provides is the ability to configure and run external tools—a very important integration point between Eclipse and other tools (if all else fails, you can integrate external tools into Eclipse using this function). The Run menu is typically populated with plug-in-specific functions, depending on the current perspective.
The Project menu is related to the Eclipse Resource model. It provides functions to open and close selected projects, as well as to manage project builds; if you choose not to have Eclipse run your projects’ builders incrementally whenever resources change, you can Clean or Build all (or a subset of) your projects manually, at your convenience. The last menu option enables you to open the selected project’s Properties dialog.
The Search menu’s top option brings up the Search dialog, which gives you the ability to search your workspace for different kinds of resources. Different search tabs provide options specific to the type of resource (for example, Java files) being searched. The type of search supported by default is a simple file search. Search results are displayed in a special view, which is opened as needed. The rest of the Search menu items provide shortcuts to specific search tabs in the Search dialog.
The Navigate menu provides functions that let you navigate through your workspace resources as well as editors, edit locations, and annotations. Because of that, most of its functionality is editor and tool-specific.
The Edit menu groups the typical editing functions, such as Undo, Redo, Cut, Copy, Paste, Delete, Select All, and Find/Replace (also referred to as Global Actions). These are typically available at all times (regardless of what editor is currently active), but exactly what they do depends on the particular editor. (For example, a text editor may allow you to copy the selected text into your clipboard, whereas a drawing editor will copy the selected graphic figures, and so on.)
The last menu in your inverse sequence, albeit one that you’ll probably frequent the most, is the File menu. Many of its options are resource-oriented. Others, such as Close, Close All, Save, Save As…, Revert, and Print are editor-related (each editor type provides its own implementation of these). New, Import, and Export options bring up their corresponding wizard selection dialogs. The New sub-menu exposes shortcuts to wizards most relevant in the current perspective. (For example, Java perspective will have a new Package, Class, Interface, and the like.) Exactly which New, Import, and Export wizards are available depends on your application and/or the set of installed plug-ins. At a minimum, you can create new Projects, Folders, and plain text Files; import projects from an external location in the filesystem, and import and export preferences and resources to/from archive files or the filesystem. Rounding up the contents of the File menu, Switch Workspace allows you to switch your workspace without having to restart Eclipse, and Exit will let you go home after a good day’s work.
Standard Views
In addition to a standard set of menus, the IDE Workbench provides a number of standard views. Unlike editors, which typically allow you to modify instances of a certain type of resource (such as Java files), views are typically designed to help you find your way around the workbench, workspace, or some other application-specific model. Ordinarily, there’s only one view of the same kind that’s open at the same time. Although views are not strictly read-only (in fact, many do allow you to make modifications to whatever it is they display), they usually don’t provide the same type of editing support as editors do. Both views and editors may provide a context menu that is displayed when their content area is right-clicked (this is something that typical Web users tend to be less accustomed to because Web pages don’t provide application-specific context menus). Some context menu options depend on the view’s or editor’s selection.
In the Resource perspective, the most important view is the Resource Navigator. It displays the contents of your workspace—the projects, folders, and files in an expandable tree. It also lets you manipulate them (rename, delete, and so on). Double-clicking a file will open it in the appropriate editor. Other perspectives, such as the Java perspective, have equivalent views (for example, Package Explorer) that let you navigate the portion of your workspace relevant to that perspective.
Editors may choose to use the Content Outline view to present a simplified structure of the file being edited, such as the structure of your Java file with its classes, fields, and methods. Thus, this view is highly editor-specific.
Bookmarks, Tasks, and Problems show elements of the Resource model commonly referred to as Markers. In short, the application may choose to annotate certain resources with these markers; for example, you can create a bookmark at a specific line in a file, so you can get back directly to it later; you can create a task related to some Java code (for example, log exceptions in a catch block); and lastly, the Java editor may annotate your source file with problem markers, denoting compilation errors or warnings. These are then summarized in their corresponding views.
The Properties view is a universal kind of view, which shows select properties exposed by the currently selected object somewhere in the workspace (be it an editor or another view). Exactly what properties are shown depends on the application.
As I previously mentioned, results of a search invoked through the Search dialog are automatically displayed in the Search Results view. This view lets you filter and organize the results, as well as open an editor at the denoted location. The view remembers results of several previous searches.
The Console shows the output of programs and external tools invoked through Eclipse. You’ll see this view in action when you launch the simple program you’ll develop using JDT.
Lastly, the Progress view shows the progress of long-running operations, such as application builds, searches, and so on. It is related to Eclipse concurrency support—whenever a progress dialog is displayed as a result of some user action, the user may click “Run in Background” button, which will close the dialog and allow the user to continue with another activity (rather than blocking the whole application). Results of operations running in background can be tracked in the Progress view.
Feel free to continue exploring the menus, dialogs, and views on your own. When doing so, remember that because the main application menu and toolbar are shared with the currently active editor, you will likely find additional functionality as you edit different types of files.
Here Comes Java
The JDT plug-ins build nicely upon the foundation described above. In fact, the JDT team provides significant input into the Eclipse Platform itself, thus ensuring that the various abstractions embodied in the Eclipse Platform are actually useful to a “tool vendor” such as JDT. If you switch back to your Java perspective and re-examine the menu bar, you will find several additional menus, as well as menu items added to the standard menus. To provide a comprehensive guide to Eclipse’s Java Development Tools would require a rather thick book. (I do recommend some in the Resources section at the end of this article.) What I’ll do instead is rely on your intuition as a developer, as well as your experience with other IDEs, and only take you through some basic steps and concepts necessary to get started with developing Java applications (and ultimately, Eclipse plug-ins) on your own. To help you along the way, you’ll develop a single-class application, which will remind many of you of your first program that you ever wrote, be it in Basic or Pascal or whatever else was hot at the time.
First, create a simple Java project (make sure you are in your Java perspective):
- Click File -> New -> Project.
- In the New Project wizard, select Java Project and click Next.
- Enter sandbox as the Project’s name, check Create separate source and output folders, and click Finish.
What you should see now is your new Java project appearing in the Package Explorer view. Look at its Project properties—right-click it and choose Properties (at the bottom of the context menu). This will bring up a Properties dialog, with the Project’s properties grouped in categories on the left-hand side. Some of the common property pages (such as those under Info and Builders) are not Java-specific, others are. Look at Java Build Path. This set of properties greatly influences how your Java project will behave in the workspace.
The Source tab shows a list of Source folders on your project’s build path. These are specially designated folders that contain your Java source files (in their respective package hierarchies). Even though you may place Java source files outside of your Source folders, those will not compile (and will not be converted into executable byte-code). Note that you may configure more than one Source folder per project, but typically all of them produce output into a single Output folder. In special circumstances, you can choose to have a separate output folder per each source folder, as well as specify source folder inclusion/exclusion filters.
The next tab is labeled Projects. Currently, it’s empty, but in a multi-project workspace, it would show other Java projects, whose exported code may be placed on this project’s classpath (and thus, your classes could reference that project’s code).
The Libraries tab shows your project’s library dependencies—local or external JARs, libraries, and class folders (containing compiled *.class files). In this project, the only library required is the JRE System Library.
The Order and Export tab enables you to specify which of your source folders will be exported, and which of your dependencies will be re-exported. To “export” something in this context means to make it visible to other projects that reference this project in their respective properties page (the Projects tab). In your case, you’ll leave the source folder exported (although no other project in this workspace will need it).
Other property pages, such as Java Code Style or Java Compiler, enable you to override your workspace-wide Java preferences at the project level.
Close the Properties dialog and right-click the src folder in your Package Explorer. Choose New -> Class. This will bring up a New Java Class dialog. Note that you could have invoked this dialog by choosing File -> New Class from the main application menu (and there are several other ways to do that). Type com.developer.sandbox in the Package field, and Main in the Name field. Click Finish. This will create a new, empty class in the specified package and open it in the Java Source Editor. Notice how the Outline view now reflects the structure of your Java file.
Editing Java Source Code
The Eclipse Java Editor provides many productivity maximizing functions that you’d expect from a top-of-the-line Java IDE, such as syntax coloring, code formatting, templates, folding, info pop-ups on hover, and so on. When writing your application, you’ll take a brief look at two very useful features—the Content Assistant and Refactoring support.
The next step in your development quest is to create the main method that will represent the core of your mini-application. Place the cursor in the body of the Main class, type main and press Ctrl+Space. You’ve just activated the Java Content Assistant. The top entry in the displayed list box is the main template. Templates are configurable, named snippets of text that can help you with some repetitive patterns of Java code. Choose main – main method and press Enter. It’ll generate an empty main method and place the cursor inside its body.
Your code will consist of an infinite loop, the first part of which will prompt the user for some numeric input, and the second part will echo it back (clever, ain’t it?). So, start by instantiating an InputStreamReader to read from System.in: Type new, press Ctrl+Space and choose the new – create new object template. Enter InputStreamReader in the first box (in other words, the first template argument), then press the Tab key and enter in as the variable name. Press the Tab key again and enter System.in as the constructor argument. Press Enter. The code looks fine, except you’ll notice a wavy red line under both instances of InputStreamReader. You’ll also notice a red error marker in the editor’s left margin. Behind the marker is a lightbulb, indicating that content assistance is available—click it and choose Import InputStreamReader (java.io). This will import the unresolved class and the error marker will go away (it’ll actually be replaced by a yellow warning marker, indicating that the new local variable is not used anywhere—that’s okay for now). Programming in Java can be that easy!
Finish the method implementation by adding the following snippet of code:
BufferedReader reader = new BufferedReader(in);while (true) {
System.out.print(“Enter a number: “);
String input = reader.readLine();
System.out.println(“You entered: “ + Integer.parseInt(input));
}
You can press Ctrl+Shift+O to import all unresolved types at the end. Notice that as you type some method invocations, for example, System.out.print, the Content Assistant continues to present you with options, such as members of the object whose method you want to invoke (for example, System.out.—note the dot—will bring up a list of members of PrintStream; typing print will narrow the list down to those starting with “print”).
There is one last error to be resolved—apparently, reader.readLine() throws an IOException (if you save the file now and activate the Problems view, you’ll see the error listed there). Click the lightbulb in the editor’s left margin (or press Ctrl+1, which is another way to activate the Content Assistant) and choose Surround with try/catch. This will wrap the offending line in a try/catch block, taking the variable declaration out of it and providing a default catch block, which simply prints the exception’s stack trace. But this creates another problem—the local variable input may not have been initialized. This will happen if an exception is thrown. In this case, the Content Assistant will recommend initializing the variable.
While you’re at it, note the // TODO Auto-generated catch block line in the catch block. If you activate the Tasks view, you’ll notice a task with precisely that description; for every single-line comment starting with TODO, the editor creates a task (this is, by the way, also configurable).
Look at some code refactoring support provided by JDT. Select the lines that prompt the user for input, starting with the first System.out.print call and ending with the catch clause. Right-click the selection and choose Refactor -> Extract Method… Enter prompt as the method name and click OK. You’ll see that the entire block of code was moved off to another method, with a signature that allows the reader instance to be passed in. The method’s invocation is now in place of the extracted code.
More refactoring functions are available, depending on your context (for example, some apply to classes, some to interfaces, some to methods, and so on.) New ones are usually added with each new release. In addition to refactoring, you can find some useful source code manipulation functions under the Source sub-menu of the Java editor’s context menu (or in the main menu bar). For example, you can generate getters/setters for your fields, create constructors based on fields, generate delegate methods, and more.
Launching Java Applications
Now that you are finished with the code, you can test-run the application to see how it works. From the main menu, choose Run -> Run As -> Java Application. You can also right-click the Main class in Package Explorer and choose Run As -> Java Application, if you prefer. You should see the Console view at the bottom of your screen become active, with the familiar prompt asking you to enter a number. Before entering your input, make sure to click the Console view so it has the input focus. To terminate the program, press Ctrl+C, or hit the red-square stop button in the Console view.
The Console view is typically customized for the type of launch configuration whose output it displays. For example, output of Java applications is annotated in such a way that exception stack traces contain clickable links to the referenced source code. To see this in action, enter a word (say, blah) at the program’s prompt instead of a valid integer (if you already terminated it, you can quickly re-launch the last run configuration by pressing Ctrl+F11). What you should see is an exception stack trace, caused by a NumberFormatException resulting from an attempt to parse the word “blah” as a number. At the bottom of the stack trace you’ll see the offending line in our Main class, underlined. Click the link, and you’ll be taken to the specified line in the editor.
Eclipse provides broad support for launching and debugging code of any kind, be it Java or another language. The necessary launch configuration information is stored in your workspace; to examine what was created for this program, click Run -> Run… This dialog will show all launch configurations in your workspace, grouped by category. You can examine all properties related to this program’s configuration, such as the main class, program arguments, runtime classpath, and so on. Typically, you can launch the same configuration in debug mode; instead of choosing Run…, choose Debug… in the Run menu.
Conclusion
In this article, you took a brief tour of the Eclipse IDE Workbench and its standard menus and views. You also learned about workspaces and the Resource model used by many Eclipse-based tools. While developing a simple Java application, you examined some useful JDT features, such as the Content Assistant and Java Refactoring support. You also saw a little bit of Eclipse’s Launch framework at work. In the next installment of this series, you will take a look at the Plug-in Development Environment (PDE) and create your first Eclipse plug-in.
Resources
- A very useful and most easily accessible resource for learning about Eclipse is its on-line Help, also available at http://help.eclipse.org/help31.
- There are many useful books on the subject, such as the Eclipse IDE Pocket Guide, and Java Developer’s Guide to Eclipse.
- The full source code for this article is available here.
About the Author
Peter Nehrer is an independent software consultant living in Toronto, Ontario. He specializes in Eclipse-based enterprise solutions and J2EE applications. His professional interests include development tools, model-driven software development, and information sharing. He is the author and contributor to several Eclipse-related Open Source projects. Peter is an IBM Certified Solutons Developer for XML and related technologies. He holds an M.S. in Computer Science from the University of Massachusetts at Amherst, MA.