Monday, April 11, 2016

Why Does 'Building Workspace' Block Launching Programs?

How often have you imported a large project in Eclipse and then immediately tried to launch it? But instead of going straight to the running program, you are stuck with the "User Operation is Waiting" dialog, because Eclipse is still building the workspace...


If you are a Java or C/C++ developer, this may seem absolutely natural. Of course, the code needs to be compiled before running it. But if your project is implemented in JavaScript or PHP, or in any of the myriad of interpreted languages then it is completely valid to ask yourself: "What the heck is Eclipse building?"

Why does this happen?


The term "building" is an abstraction in Eclipse denoting the process of transforming the available resources in the workspace into some result. Any plugin can contribute builders for processing the workspace's resources. Some of the builders are truly compilers that transform the source code into a binary form. But most of the builders in Eclipse are actually validators that just check the source code for problems and add error and warning markers.

Eclipse started as a Java IDE. The primary reason for introducing the builders in the Eclipse Platform was to compile the Java source code into bytecode that can be executed by the JVM. It was important to ensure that the building process has finished before launching the Java program. Otherwise the launched program may be broken because some classes are still being compiled. Therefore, the launching infrastructure was implemented to block if any builders are still running and to wait for their execution to finish.

While the above makes sense for Java, it does not for many other programming languages that Eclipse supports today. The builders that run for a PHP project, for example, are just to validate the code and are not a prerequisite for its successful execution.

So...

What is the solution?


Fortunately, the behavior of the program launching infrastructure can be configured. There is a preference that determines if the program launch should wait for the build to finish. 


The preference is on the "Run/Debug > Launching" preference page. Look for the group of radio buttons with title "Wait for ongoing build to complete before launching". Usually the default value "Always" is selected, which follows the behavior described so far. Selecting "Never" will switch the waiting for the build off, while "Prompt" will display a dialog asking whether to wait for the build or not. The latter option is useful if your workspace contains programs written in both compiled and interpreted languages.

Tuesday, March 22, 2016

Why Does Canceling Operations in Eclipse Never Work?

Well... saying "never works" is too extreme, so let's say "does not work often enough". Often enough, so the majority of users do not trust the red square button for canceling background operations.

Let's have a look at some quotes from a famous web site for collecting (mostly negative) feedback about Eclipse.
When I cancel a task, it hangs and ends up taking longer than it would have taken to let it finish.
Cancelling never works. Trying to build a project. It get's stuck. I cancel it. It cancels for 10 minutes. I have to force quit it again.
Why in gods name do you have a cancel task option if it's never going to cancel the @#$% task?? Is this some kind of sick joke?
There is also a blog post written back in 2006, which gives a more detailed picture of a user experience with the cancel button.

Why does Eclipse provide a cancel button that does not work?


Let's have a look how the Cancel Operation button is implemented. When you click on the red square button, the Eclipse Platform raises a "cancellation" flag for the running background operation. Then it is up to the latter to check if that flag is raised and terminate itself.

In other words, the Eclipse Platform has no power to terminate background operations, but only to send them a request for cancellation. If the operation is implemented in a proper way, i.e. frequently checks for the cancellation flag, it will promptly terminate itself. Alternatively, a poor implementation may totally miss checking the cancellation flag and finish as if the user has not pushed the cancel button.

In an even worse scenario, the background operation may check for the cancellation flag, but instead of terminating itself immediately, it may try reverting everything it has done so far. While this may be a valid approach for some use cases where keeping data consistency is critical, most of the time it is just an over-engineering. This way an operation that was canceled in the middle of the execution, may take longer than if it has not been canceled at all. This leads to even more frustrating user experience.

What is the solution?


Unfortunately, there is no direct solution for you as a user to apply to your IDE. The issue is caused by a weak code implementation in the plugins providing the background operations and it must be fixed there. There is no magic fix that can be implemented in the Eclipse Platform alone.

However, there is still something you can do:
  1. Report the issue - yes, please open a bug if you stumble upon an operation that does not terminate promptly when you hit the cancel button. This is a good small step to make a difference.
  2. Keep your Eclipse up-to-date with the latest version of all plugins with the hope that this kind of issues will be resolved over time.
If you are an Eclipse plugin developer then you should design carefully your background operation, so users are able to cancel them. It is natural to focus on the happy path when implementing a new operation. But it won't be always the case where users will trigger your operation and will patiently wait for it to finish. Quite often users will realize they've trigger your operation accidentally, or it is taking longer than expected and they don't want to wait for it any longer, or they just want to do something else like saving a file or shutting down the IDE, but your operations is blocking them, or... tons of other reason that may make users want to cancel your operation.

And if users cannot cancel your operation within a few seconds, they will open the Task Manager and will kill the IDE. Which is a lose-lose situation - neither your operation will be completed, nor the user will be happy. So, give the user the chance to win :-)

Code tips on improving the implementation of background operations


The most fundamental thing to make your background operations responsive for cancellation is to check if the cancellation flag has been raised. You should have already been provided with an instance of IProgressMonitor in your operation's implementation, whether it is a Job, a WorkspaceJob, a WorkspaceModifyOperation, etc. Checking for the cancellation flag is simply calling the the monitor's isCanceled() method.

The below code examples check for the cancellation flag and interrupts the operation's workflow by returning the CANCEL_STATUS.
if (monitor.isCanceled()) return Status.CANCEL_STATUS;
Checking for the cancellation flag should be done as often as possible. This check is a cheap operation and there should not be any concerns about the performance. In the end, if you have a long running operation, it is more important for users to cancel it promptly than having it a few milliseconds faster.

Very often long running operations are processing lots of items in a loop. As the list of items may grow unpredictably long, there should be a check for cancellation inside the loop on every iteration. This ensures that the operation can be canceled promptly regardless of the number of items that are processed. See the example below:
while (hasMoreWorkToDo()) {
    // do some work
    // ...
    if (monitor.isCanceled()) return Status.CANCEL_STATUS;
}
return Status.OK_STATUS;
Another common issue with unresponsive background operations is when they execute an external process or a long I/O operation and block on it waiting to finish. Waiting on external processes or I/O operations should no be done indefinitely. You should take advantage of any API that allows waiting for a limited amount of time. This way you can wait just for a short time (e.g. one second), then check if your operation is canceled, and if not, wait again for a short time. Below is an example how to wait for an external process to finish and check if your operation is canceled at the same time.
while (!process.waitFor(1, TimeUnit.SECONDS)) {
    // process is still running
    // check if the operation has been canceled
    if (monitor.isCanceled()) {
        process.destroy();
        return Status.CANCEL_STATUS;
    }
}
Finally, some further readings I highly recommend to every Eclipse plugin developer:

Tuesday, March 15, 2016

Why Does Plugin Installation in Eclipse Take so Long?

How often have you tried installing a new simple plugin in your Eclipse and the installation process gets stuck on "Calculating requirements and dependencies" for ages?


Why does this happen?


Eclipse is an extensible software platform comprised of plugins and each plugin depends on other plugins. The successful installation of a new plugin requires its dependencies to be successfully resolved. The ideal situation is when all required plugins are already installed in your Eclipse, but this is often not the case. Therefore, the dependencies must be fetched from an update site and installed together with the plugin you actually want to install.

In order to resolve the above complex task, the Eclipse install manager (the one you invoke using the Install New Software wizard from the Help main menu) scans all update sites registered in the Eclipse workspace. The scanning process involves reading the update site's metadata and then trying to calculate the best match for the required dependencies.

The problem with getting stuck may happen for a number of reasons: the number of update sites registered in the workspace has grown significantly or there is a networking problem with the user connection, one of the update site's server, a proxy or a VPN connection.

What is the relief?


Scanning all update sites is the default behavior of the Eclipse install manager. Fortunately, it can be changed.

First, if you are still waiting on "Calculating requirements and dependencies" then hit the Stop button on the right side of the progress bar. This will immediately stop the installation process (yes - this is one of the rare cases where this button is implemented properly in Eclipse) and it will make the wizard's user interface responsive again.

Now, simply deselect the "Contact all update sites during install to find required software" checkbox. This way the install manager will look for dependencies only on the update site providing the plugin being installed. None of the other update sites, registered in the workspace, will be contacted. This will significantly improve the time spent on the "Calculating requirements and dependencies" phase and it will reduce the size of the metadata that needs to be downloaded.


There is one drawback of deselecting the checkbox. If the update site providing the plugin being installed is not self-contained, i.e. does not provide all the required dependencies, then the installation will fail with an error message for unresolved dependencies. However, this will be a fast failure and you can go back and select the "Contact all update sites..." checkbox again. In such case, I also recommend to go and review all registered updates sites in the Install/Update > Available Software Sites preference page and disable those that do not seem to be related to the plugin being installed.

My personal experience is that the majority of Eclipse plugins install without any need for scanning additional update sites for the required dependencies. My recommendation is to deselect the "Contact all update sites..." checkbox and select it only if the installation process fails without it.

Is there such an option in the Eclipse Marketplace Client?


It's nice that the Install New Software wizard provides a checkbox that can be deselected, but why can't you find a similar checkbox in the Eclipse Marketplace Client?

Well... because you don't need one. The Eclipse Marketplace Client is a smarter and user-friendlier version of the Install New Software wizard. It implements a fallback strategy - first, it tries to resolve the dependencies by only looking at the update site providing the plugin, and only if that fails it will automatically try contacting all update sites.

Effectively, this is an automated implementation of the recommended manual workflow given above for the Install New Software wizard. In case you are curious about the details regarding the implementation of the fallback strategy, you may have a look at the discussion in bug 316362.

Friday, February 19, 2016

Enable the CSS3 Profile in Eclipse

Eclipse has a rich and powerful CSS editor. It provides the expected features like syntax highlighting, content assist and outline. If you have already tried it and you are already on CSS3, you may have noticed that the content assist misses the new CSS3 properties. It looks like the Eclipse CSS editor has somehow stuck on CSS2. But it is not really. The support for CSS3 is there, but ... guess what ... not enabled by default.

Here is how you can enabled the CSS3 features:
  1. Right-click on a CSS file and call the Properties dialog.
  2. Open the Web Content Settings page.
  3. There you will find a field CSS Profile set to "none".
  4. Change the CSS Profile value to "CSS3: Cascading Style Sheets, level 3".
  5. Click the OK button.

Now, try again the content assist in the CSS editor. It will suggest also the CSS3 properties like "border-radius".


This is how to change the CSS profile per file. It is also possible to change it per project using the same steps on the project's Properties page. But it only works if the project is a Dynamic Web Project or a Static Web Project one. The Web Content Settings page is not available for other project types like PHP projects. It is also not available as a workspace-wide preference. So, for the majority of project types it is only possible to change the CSS profile per file.

The good news is that with Neon M6 the default CSS profile becomes CSS3. See bug 438283. So, the above steps won't be necessary in the near future and users will see the CSS3 features off the shelf.

Wednesday, April 22, 2015

Making the Text Editor to be the Default One for All Unknown Files in Eclipse

NOTE. The functionality of the Default Text Editor plugin has been implemented in the Eclipse Platform with the Neon release. Check the release notes for details.

Eclipse users usually work with many different file types. Some of the file types may be opened by default in an external editor instead of in the Eclipse workbench. This happens if Eclipse has no editor available to handle that particular file type, but there is one installed in the operating system. In such case Eclipse assumes that it is better for the user to have the file opened in the external system editor.

Lots of users are quite annoyed by this behavior, especially when it comes to text-based files. They would prefer to have the file opened in the plain text editor of Eclipse instead of switching the context to the external program. Unfortunately, there is no easy way to change this in the preference settings. It's possible to associate a specific file extension with the plain text editor, but this must be done separately for every file extensions. There is no way to say "all text files of unknown type should open in the text editor".

Here comes the Default Text Editor plugin. It takes advantage of the Editor Association Override extension point introduced in Eclipse 3.8. When the plugin is installed it will change the default behavior of Eclipse and will opened all text files of unknown type in the plain text editor. Binary files like images may still be opened in an external system editor. As simple as that.

The plugin is available on the Eclipse Marketplace. It can also be installed through an update site. More info is available on the GitHub project.

Wednesday, April 1, 2015

$150 Bug Bounty for Fixing a Dark Theme Issue

Zend Studio is an IDE based on the Eclipse Platform. The dark theme is an important feature and is very popular among PHP developers. The most annoying issue with the dark theme, we have at the moment, is that the expand/collapse toggle in trees is almost invisible on Windows, because it seems to be unaffected by the dark theme coloring. See Eclipse bug 434201 for details.



We decided to put some money on the table with the hope that someone will step in and fix this bug. This will benefit not only Zend Studio users, but all Windows users in the Eclipse ecosystem who want to use the dark theme.

We created a $150 bug bounty on the FreedomSponsors crowd-funding platform. Follow this link to open the sponsored issue. Since this is a crowd-funding platform, anyone else who is ready to give some money for resolving this issue is welcome to do it, so the offer becomes more attractive.

UPDATE. The bug has been fixed within days and it will be delivered with the Mars M7 milestone. Thanks to Fabio Zadrozny for his great work. Kudos to Lars Vogel for adding $100 more to the bounty.

Tuesday, August 12, 2014

Highlighting Breakpoints Like in Zend Studio 5.5

Looking at the feedback we receive, it seems that lots of our long-time users feel nostalgic to the pre-Eclipse era of Zend Studio. Here is one hint how you can bring the look and feel of the latest Zend Studio a little bit closer to the one experienced with the legendary Zend Studio 5.5.

In Zend Studio 5.5 when adding a breakpoint the complete line was highlighted in pink color. In later releases of Zend Studio this was replaced by the usual way of the Eclipse Platform - a blue bullet appears in the marker area on the left side of the editor's line.


Luckily, this can be configured in the same way it was in Zend Studio 5.5, following these steps:

  1. Call Window > Preferences from the main menu.
  2. Navigate to the General > Editors > Text Editors > Annotations preference page.
  3. Select "Breakpoints" in the list of annotation types.
  4. Select the "Text as" checkbox.
  5. Select "Highlighted" from the drop-down list.
  6. Change the color to #FFC0CB.
  7. (Optional) If you want to remove the blue bullet then deselect the "Vertical ruler" checkbox.
  8. Click the OK button.

Note. You need to upgrade to the latest Zend Studio 11.0.1 Early Access build or wait for the official 11.0.1 release (due in a week) to take advantage of this hint. There was a bug in the PHP editor that prevented breakpoint highlighting in previous releases.