EDT:IDE Test Server
The IDE Test Server is a Jetty-based server which allows users to test their applications on the fly with virtually no configuration, and zero deployment, required. An example is that you can invoke a service directly from its source project without having to deploy the service, or even set up a server for it to run on.
The user never has to define, configure, or start the test server. A test server is created for each project in the workspace, as needed. The test server is started the first time it's requested for a project. If the user wishes to restart the server, for example a classpath change was made, then the user only needs to terminate the server and it will be started back up automatically on the next access. This server lives under the covers, and the only place you see it running is in the Debug view. Since each project has its own test server, each instance is a separate Java process in this view. This allows you to kill/restart a single project's server without affecting the other running servers.
When developing inside the IDE the test server will automatically be used for dedicated service invocations, however for REST service invocations you must use the workspace://serviceProject/package.serviceName URI format in your resource binding. You will also need to make sure the default deployment descriptor for the project containing the REST service has the service part listed in the Service Deployment tab (the only services made available as REST to the test server are those that would be deployed as REST).
A note on the server classpath: each source project will have its own test server instance. This allows each instance to have the appropriate classpath, as well as let you restart a single project's server without having to restart them all. For dedicated services, the "source" project that defines the classpath is the project containing the main RUI handler. For REST services, the "source" project that defines the classpath is the project containing the service being invoked.
The following sections are for EDT developers (not EGL end users); they explain how you can obtain a server instance and how you can actually extend the server itself.
Using the test server in your application
If you want to invoke the test server from your application, you will need to depend on the org.eclipse.edt.ide.testserver project. Since each project has its own test server you will need to know the project for which you want a test server. Once you know this, you should use org.eclipse.edt.ide.testserver.TestServerManager.getInstance().getServerConfiguration(IProject project, boolean debug) to get a org.eclipse.edt.ide.testserver.TestServerConfiguration. You can also directly instantiate TestServerConfiguration but this makes sure there is just one server per project instead of spawning multiple instances, and you will also lose some built-in features (e.g. TestServerManager is what alerts the user when one or more test server classpaths have changed).
Once you have a TestServerConfiguration you can invoke its start(IProgressMonitor monitor, boolean waitForServerToStart) method to start it up. If the server is already started this method will immediately return. An example of invoking this code can be found in org.eclipse.edt.ide.rui.server.EvServer of the org.eclipse.edt.ide.rui plug-in.
Once you have a running server, the TestServerConfiguration can tell you the port on which it is running, which is information you'll need to know when you want to load some URL on the server.
Extending the test server
If you are adding support for some new technology in EDT, you will probably need to also extend the test server. The test server resides in project org.eclipse.edt.ide.testserver and is a barebones Jetty server. The main support that ships with EDT is actually provided as an extension that you can use as a reference. The reference extension provided in EDT is the ability to invoke REST and dedicated services, as well as support JNDI data sources in these services. Be sure to check out the source code for all the classes mentioned on this wiki for lots of documentation.
There are two main pieces you will need to implement: code running inside the IDE that sets up additional arguments, classpath additions, etc; and code running inside the test server process that handles configurations such as registering a new servlet.
The reference implementation of extending the server is located in plug-in org.eclipse.edt.ide.deployment.services; see plugin.xml as well as package org.eclipse.edt.ide.deployment.services.internal.testserver.
To kick this off you will need to add an extension point for org.eclipse.edt.ide.testserver.testServerExtension in your plugin.xml that references a class extending org.eclipse.edt.ide.testserver.AbstractTestServerContribution. Take a look at the source for this class to see the current available API. Every method is optional and you only need to override the methods that are needed in your application (for example you might not have any additional classpath entries to contribue). To see this class in action, refer to org.eclipse.edt.ide.deployment.services.internal.testserver.ServicesContribution.
Note: This class is a singleton for the workspace; the current TestServerConfiguration is passed to each method so that you can maintain state if you need to (see ServicesContribution for how this can be done).
If you need to contribute code running from within the server, you must write a class that extends org.eclipse.edt.ide.testserver.AbstractConfigurator. In order to register this class with the server, you must specify it in AbstractTestServerConfiguration.getConfiguratorClassNames() otherwise the test server will not be instructed to instantiate your class. Be sure that you add the appropriate classpath entry in AbstractTestServerContribution.getClasspathAdditions() so that the class can be loaded! AbstractConfigurator.processNextArgument() will be called when processing the arguments; you will want to handle all the arguments that you added in AbstractTestServerContribution.getArgumentAdditions(). In addition to argument processing, there are several hooks during the lifecycle of the startup process that you can use to configure the server. The order in which the hooks are called is as follows:
- preStartup (called after arguments are processed and the server is created, but before the server is told to start)
- preConfigure (a phase of the Jetty startup lifecycle)
- configure (a phase of the Jetty startup lifecycle)
- postConfigure (a phase of the Jetty startup lifecycle)
- postStartup (called after the server has finished starting up)
To see this class in action, refer to org.eclipse.edt.ide.deployment.services.internal.testserver.ServicesConfigurator.
Other classes and methods of note:
org.eclipse.edt.ide.testserver.ClasspathUtil: Utility methods for building classpath entries in the format expected by JDT.
org.eclipse.edt.ide.testserver.TestServerIDEConnector: A basic server that listens for requests made from the server to the IDE. Check out org.eclipse.edt.javart.ide.IDEBindingResourceProcessor.getConnectionProfileSettings() for how to make a request to the IDE, and ServicesConfiguration.handleServerRequest() for handling the request.
ServicesContribution.resourceChanged(): When a deployment descriptor changes, this will calculate the changes and notify the test server so that the changes can take effect immediately. A servlet is registered as part of this extension that handles the deployment descriptor changes (org.eclipse.edt.ide.deployment.services.internal.testserver.ConfigServlet).
org.eclipse.edt.ide.deployment.services.internal.testserver.DDResourceChangeListener: Keeps track of project-level preference listeners for the development deployment descriptor file.