Category Archives: Tips and Tricks

The XImportSection in Xbase 2.4

I know that Xtext 2.4 has not been released yet, but I could not resist blogging about a very cool new feature in Xbase: improved automatic import functionalities!

Actually, import functionalities were already great when using Xbase also in previous versions of Xtext, but now they provide a much better experience for the user of your DSL! Indeed, all the import functionalities you are used to with JDT (like automatic import insertion, and organize imports) are available also for your Xbase language; these features were already available in Xtend, and they have been ported to Xbase itself.

At the time of writing, you need to get the very latest updates of Xtext 2.4, using the update site http://download.eclipse.org/modeling/tmf/xtext/updates/composite/latest/ .

Before you used to do something like

grammar org.xtext.example.helloinferrer.HelloInferrer with 
	org.eclipse.xtext.xbase.Xbase

generate helloInferrer "http://www.xtext.org/example/helloinferrer/HelloInferrer"

Model:
	imports += Import*
	greetings+=Greeting*;

Import:
  'import' importedNamespace = QualifiedNameWithWildcard
;

...

Now, you can use in your grammar the new Xbase rule: XImportSection:

grammar org.xtext.example.helloinferrer.HelloInferrer with 
	org.eclipse.xtext.xbase.Xbase

generate helloInferrer "http://www.xtext.org/example/helloinferrer/HelloInferrer"

Model:
	importSection=XImportSection?
	greetings+=Greeting*;

...

In this post I’m reusing some experiments you can find here (https://github.com/LorenzoBettini/Xtext2-experiments, I had blogged about these experiments in previous posts).

If you now rerun the MWE2 generator, and make sure you merge the plugin.xml_gen with plugin.xml in the .ui project, your editor will provide some interesting features for free (if you use my examples, you can find a project wizard “New Project” => “Xtext” => “HelloInferrer Project”):

Imports with wildcards are deprecated:

use_of_wildcards_deprecated

You now have the context menu “Organize Imports” (Shift + Control + O); try that one in the presence of such deprecation warning and imports are organized for you:

after_organize_imports

Similarly, unused imports are reported as warnings:

imports_never_used

Again, use “Organize Imports” to fix that!

The new feature I like most is the automatic insertion of imports! (just like in JDT and Xtend): try to get content assist for a Java type, for instance,

code_completion

Accept a proposal and the import will be automatically inserted (instead of the fully qualified name):

code_completion2

Xtext rocks! :)

Be Sociable, Share!

Regular Expression Replacement in an Ant Property

I’m quite a newbie in Ant, but I thought it would be straightforward to do a regular expression replacement in a string contained in a property; in my case, I had to replace Windows backslashes with Unix slashes… apparently, unless you use the propertyregex task from Ant Contrib, that is not supported out-of-the-box: you have to pass through a file!

This stackoverflow post shows a possible solution, and starting from that, I created a macrodef to make it easier

<!-- = = = = = = = = = = = = = = = = =
  macrodef: replace_win_slashes          
 = = = = = = = = = = = = = = = = = -->
<macrodef name="replace_win_slashes">
	<attribute name="property.to.process" default="default" />
	<attribute name="output.property" default="default" />
	<sequential>
		<echo message="@{property.to.process}" file="some.tmp.file" />
		<loadfile property="@{output.property}" srcFile="some.tmp.file">
			<filterchain>
				<tokenfilter>
					<replaceregex pattern="\\" replace="/" flags="g" />
				</tokenfilter>
			</filterchain>
		</loadfile>
		<delete file="some.tmp.file" />
	</sequential>
</macrodef>

This macro takes the property value to process (property.to.process) and the property name where to store the result; it outputs the input value to a temporary file, reads it back with a regular expression replacement (which is supported for files) and store it in the specified property (the temporary file is then deleted).

Here’s an example of use

<project name="replace win slashes" >
	<property name="my.prop1" value="file:C:\Users\bettini/my/path1" />

	<!-- = = = = = = = = = = = = = = = = =
          macrodef: replace_win_slashes          
         = = = = = = = = = = = = = = = = = -->
	<macrodef name="replace_win_slashes">
		<attribute name="property.to.process" default="default" />
		<attribute name="output.property" default="default" />
		<sequential>
			<echo message="@{property.to.process}" file="some.tmp.file" />
			<loadfile property="@{output.property}" srcFile="some.tmp.file">
				<filterchain>
					<tokenfilter>
						<replaceregex pattern="\\" replace="/" flags="g" />
					</tokenfilter>
				</filterchain>
			</loadfile>
			<delete file="some.tmp.file" />
		</sequential>
	</macrodef>

	<replace_win_slashes property.to.process="${my.prop1}" output.property="my-prop-1" />

	<echo message="my-prop-1 = ${my-prop-1}" />

</project>

 

Be Sociable, Share!

One Eclipse Installation and Multiple Configurations

I used to have many Eclipse installations in my machines; typically they were different Juno versions downloaded from ecipse.org, for instance, Eclipse for RCP developers, Eclipse for DSL developers, Eclipse Modeling Tools, etc. Moreover, most of them were customized with the same plugins (for instance, Mylyn connectors) which I had to install on all of them. I preferred to have separate installations not to have a monolithic single Eclipse instance (where some features might also interfere with each other).

Then I started to use the ability of Eclipse to deal with multiple configurations, which is really a cool feature.

The idea is that you have a single Eclipse installation with all the features you always used and that you would desire in all of your Eclipse installations; then you have different directories for each “configuration”.

You can start Eclipse with a command line like the following, which uses the command line argument -configuration:

eclipse-main/eclipse -configuration eclipse-other/configuration

Assuming that the main Eclipse installation is in eclipse-main directory, and that the new separate configuration will be stored in eclipse-other/configuration (which will be automatically created if it does not yet exist). What you get is a running Eclipse instance with all the features and plugins of the main Eclipse installation, but all the new features which will be installed from this running instance will go in the new configuration, thus they won’t disturb the main installation!

If you try to install new software from this Eclipse running instance, you’ll see that the list of available software sites is empty, so you will have to fill such list with the typical Eclipse software sites, such as http://download.eclipse.org/releases/juno and http://download.eclipse.org/eclipse/updates/4.2.

And then you can install new features in this Eclipse, and they will be available only in this configuration. You can then check the plugins and features directories in eclipse-other which will contain the new installed features and bundles (which will not be stored in the same directories of eclipse-main); similarly, the plugins and features directories in eclipse-other will not contain the features and bundles which are stored in the same directories of eclipse-main, though they are available in the new Eclipse configuration.

Of course, you’ll have to use the above command line each time you want this Eclipse version (you should have shell scripts to run a specific Eclipse).

Main advantages in this approach are

  1. The features you want to use in all configurations are stored in only one place, and they will be maintained only in the eclipse-main installation (e.g., kept up to date)
  2. you save some space in your hard disk (I had 4 Eclipse installations which required 2.5 Gb; with the new approach, i.e., one Eclipse main installation and 3 configurations I only need 500 Mb!)

If you can still use command line to install new features in the separate configurations (I blogged about that); you just need to adjust the command line with the -configuration parameter.

For instance, to have an Eclipse configuration in eclipse-texlipse/configuration (based on the main Eclipse installation stored in eclipse-main) with the addition of Texlipse and Subversion features I run these commands

./eclipse-main/eclipse \
-configuration ./eclipse-texlipse/configuration \
-application org.eclipse.equinox.p2.director -noSplash \
-repository http://download.eclipse.org/releases/juno,http://download.eclipse.org/eclipse/updates/4.2,\
http://texlipse.sourceforge.net/ \
-installIUs \
net.sourceforge.texlipse.feature.group,\
de.vonloesch.pdf4eclipse.feature.group \
-vmargs -Declipse.p2.mirrors=true -Djava.net.preferIPv4Stack=true

./eclipse-main/eclipse \
-configuration ./eclipse-texlipse/configuration \
-application org.eclipse.equinox.p2.director -noSplash \
-repository http://download.eclipse.org/releases/juno,http://download.eclipse.org/eclipse/updates/4.2 \
-installIUs \
org.eclipse.team.svn.feature.group \
-vmargs -Declipse.p2.mirrors=true -Djava.net.preferIPv4Stack=true

Note that using the command line for installing new features will also store in the Eclipse configuration the specified update sites (so you will find them in the Install New Software dialog).

Be Sociable, Share!

Reduce disk access in Windows 7

Although I’m not a big user of Windows, sometimes I use it to test my software and products. When switching to Windows Vista and Windows 7 I’ve always noticed a huge use of the disk.

Here are some tricks I’ve used to reduce such use

First of all make sure to disable indexing for the whole hard disk (checkbox “Allow files on this drive…”)

Then stop the Windows Search service and…

make sure it is disabled (right click and the Properties)

Finally, make sure that you have no scheduled defragmentation (you can check this by pressing “Defragment now…”

This should reduce disk access, hopefully :)

any comment and suggestion is more than welcome!

 

Be Sociable, Share!

Mirror Eclipse repositories with p2.mirror Ant task

Inspired by this nice blog post, I decided it was time to try to mirror some Eclipse repositories to

  • speed up my builds that depend on target platforms
  • insulate myself from outside servers
  • be able to build also without an Internet connection
  • reduce network traffic :)

To do this I’m using p2 ant tasks for mirroring repositories.

When mirroring eclipse repositories, my main idea is to keep the path structure of the original repository URL. For instance, if you are using something like

http://download.eclipse.org/releases/juno

the mirror should differ only for the base url, e.g., something like

/home/myhome/eclipsemirror/releases/juno

This is useful if the p2 repositories you use for materializing your target platform are parametrized with respect to the base URL. For instance, I’m using Buckminster to materialize my target platforms (see also this post), and in my RMAP files I have something like

<?xml version="1.0" encoding="UTF-8"?>
<rm:rmap xmlns:bc="http://www.eclipse.org/buckminster/Common-1.0" xmlns:rm="http://www.eclipse.org/buckminster/RMap-1.0">

  <rm:property key="eclipse.download" value="http://download.eclipse.org"/>

  <rm:property key="xtext.p2.repository" 
        value="${eclipse.download}/modeling/tmf/xtext/updates/composite/releases/"/>
  <rm:property key="eclipse.target.platform" 
        value="${eclipse.download}/releases/juno"/>
  <rm:property key="swtbot.repository" 
        value="${eclipse.download}/technology/swtbot/helios/dev-build/update-site"/>
  <rm:property key="orbit.repository" 
        value="${eclipse.download}/tools/orbit/downloads/drops/R20120526062928/repository/"/>

...

</rm:rmap>

You see that the URLs are parametrized over the property eclipse.download (which defaults to http://download.eclipse.org). If I mirror those repositories keeping the same structure

then, switching to my local mirror for target materialization it’s just a matter of passing for the property eclipse.download the URL of my local directory, e.g., file:/home/bettini/eclipsemirror, without even changing my RMAP files.

So let’s start mirroring! We need to define an Ant script for the p2 antRunner.

For instance, for mirroring the whole orbit repository (with that particular drops version) we create this script, let’s call it mirror-orbit.xml:

<project name="Create Mirror" default="create-mirror" basedir=".">

  <target name="create-mirror">
    <p2.mirror source="http://download.eclipse.org/tools/orbit/downloads/drops/R20120526062928/repository">
      <destination location="${target.dir}/tools/orbit/downloads/drops/R20120526062928/repository"  />
    </p2.mirror>
  </target>

</project>

Note that we keep in the target dir the same path structure of the original repository.

Since these Ant tasks need to be run via the Eclipse antRunner application, you need a full installation of Eclipse on the machine that will run the task. And you run this task with a command line like the following

/path/to/eclipse -noSplash \
   -application org.eclipse.ant.core.antRunner \
   -buildfile mirror-orbit.xml \
   -Dtarget.dir=$HOME/eclipsemirror

Of course you can choose any target dir; the idea is however to always use the same target dir so that all repositories will be mirrored in that path.

Mirroring an entire repository might not always be the case, especially for Juno main release repository, which is quite huge. But you can specify in the Ant task the installable units you’re interested in; then, the p2 task will only mirror those installable units (and all its dependencies). For instance,

<project name="Create Mirror" default="create-mirror" basedir=".">
  <target name="create-mirror">
    <p2.mirror source="http://download.eclipse.org/releases/juno">
      <destination location="${target.dir}/releases/juno"  />
      <iu id="org.eclipse.sdk.feature.group" />
      <iu id="org.eclipse.equinox.executable.feature.group" />
      <iu id="org.eclipse.emf.sdk.feature.group" />
      <iu id="org.eclipse.emf.query.sdk.feature.group" />
      <iu id="org.eclipse.net4j.sdk.feature.group" />
      <iu id="org.eclipse.net4j.db.feature.group" />
      <iu id="org.eclipse.emf.cdo.sdk.feature.group" />
      <iu id="org.eclipse.draw2d.sdk.feature.group" />
    </p2.mirror>
  </target>

</project>

This task will mirror all the features that should let you define a target platform for RCP development with EMF and CDO.

NOTE: if you try to mirror org.eclipse.platform.sdk from the releases/juno repository, you will see that it will actually mirror the whole repository! (see also this forum post).

If you get some warnings during the mirror about unsolvable dependencies, you can ignore them: basically those dependencies are in a different repositories, and probably you will mirror those repositories too later.

Of course you can use several p2.mirror elements in the same Ant task. For example, this is the one we use in Emf Components, to have a mirror for our target platform: it also mirrors Swtbot and Xtext SDKs:

<project name="Create Mirror" default="create-mirror" basedir=".">

  <target name="create-mirror">

    <p2.mirror source="http://download.eclipse.org/releases/juno">
      <destination location="${target.dir}/releases/juno"  />
      <iu id="org.eclipse.sdk.feature.group" />
      <iu id="org.eclipse.equinox.executable.feature.group" />
      <iu id="org.eclipse.emf.sdk.feature.group" />
      <iu id="org.eclipse.emf.query.sdk.feature.group" />
      <iu id="org.eclipse.net4j.sdk.feature.group" />
      <iu id="org.eclipse.net4j.db.feature.group" />
      <iu id="org.eclipse.emf.cdo.sdk.feature.group" />
      <iu id="org.eclipse.draw2d.sdk.feature.group" />
    </p2.mirror>

    <p2.mirror source="http://download.eclipse.org/tools/orbit/downloads/drops/R20120526062928/repository">
      <destination location="${target.dir}/tools/orbit/downloads/drops/R20120526062928/repository"  />
    </p2.mirror>

    <p2.mirror source="http://download.eclipse.org/modeling/tmf/xtext/updates/composite/releases">
      <destination location="${target.dir}/modeling/tmf/xtext/updates/composite/releases"  />
      <iu id="org.eclipse.xtext.sdk.feature.group" />
      <iu id="org.eclipse.xtend.sdk.feature.group" />
      <iu id="org.eclipse.xpand.sdk.feature.group" />
    </p2.mirror>

    <p2.mirror source="http://download.eclipse.org/technology/swtbot/helios/dev-build/update-site">
      <destination location="${target.dir}/technology/swtbot/helios/dev-build/update-site"  />
      <iu id="org.eclipse.swtbot.eclipse.feature.group" />
      <iu id="org.eclipse.swtbot.ide.feature.group" />
      <iu id="org.eclipse.swtbot.eclipse.test.junit4.feature.group" />
      <iu id="org.eclipse.swtbot.forms.feature.group" />
      <iu id="org.eclipse.swtbot.feature.group" />
    </p2.mirror>

  </target>

</project>

Final warning: it might take some time for the mirror task to complete (usually hours depending on your connection and download.eclipse.org load) and it will also take some hard disk space (for the above mirror it takes about 2 Gb).

You may have to experiment a bit to get all the features you need in the mirror; for instance, I didn’t know about the draw2d above, but I had to add it since during target materialization that feature was requested by some other feature. If you’re lost about that, you can always mirror the whole thing ;)

There’s also a follow up post showing how to run this ant task from Eclipse!

But then your builds will be faster :)

Be Sociable, Share!

Install Adobe Reader in Ubuntu 12.10 Quantal Quetzal 64bit

Acrobat Reader used to be available from Ubuntu Partner repository, but it is not available anymore in Ubuntu 12.10 Quantal Quetzal!

So you have to download the .deb package from adobe.com and install it:

http://ardownload.adobe.com/pub/adobe/reader/unix/9.x/9.5.1/enu/AdbeRdr9.5.1-1_i386linux_enu.deb

However, if you have a 64bit system, do not forget to install also these packages:

sudo apt-get install libxml2:i386 ia32-libs

Otherwise, acroread will fail

acroread: error while loading shared libraries: libxml2.so.2: cannot open shared object file: No such file or directory

Be Sociable, Share!

Accessing your remote Ubuntu machine with VNC and ssh

If you want to access your remote Ubuntu machine with VNC, in particular by tunnelling through ssh, there is already some documentation which can be found here. However, at least for me, the procedure explained there does not work out of the box. So here’s what I had to do to make it work.

First of all you need to install in the machines the following packages:

  • remote machine: xvfb x11vnc openssh-server
  • local machine: xtightvncviewer openssh-client

Then, the script to run on your client machine to access the server has to be slightly modified as follows

#!/bin/sh

ssh -C -f -L 5900:localhost:5900 USER@REMOTEIP \
        x11vnc -safer -localhost -nopw -once \
        -auth /home/USER/.Xauthority -display :0 -create \
        && sleep 5 \
        && vncviewer localhost:0

where you will have to replace USER with your user on the remote machine, and REMOTEIP with the address of your remote machine.

Basically, the changes I had to make to the original script were to add the -auth command line option specifying the path to the .Xauthority, and the command line option -create to actually start an instance of the X server on the remote machine.

Be Sociable, Share!

Installing Eclipse Features via the command line

If you have many eclipse installations (with different features/plugins) and you want to have such installations in several computers (possibly with different operating systems or with different architectures), then being able to install eclipse features from the command line might be quite helpful (at least, it is for me :)

You can find some related posts, like Lars Vogel’s or Paul Webster’s. These are just my two cents :)

What you need to do is to run eclipse from the command line (if you’re using Windows, you need to run eclipsec.exe, note the final ‘c’, instead of eclipse.exe), with these parameters

./eclipse \
-clean -purgeHistory \
-application org.eclipse.equinox.p2.director \
-noSplash \
-repository <repo1>,<repo2>,<repo3> \
-installIUs <feature1>,<feature2>,<feature3>,...

Where the repo URLs are just the same as the ones you use as update sites or p2 repositories when installing a feature in Eclipse (you may want to always put the eclipse distribution main update site, e.g., http://download.eclipse.org/releases/juno), while the feature IDs are the actual identifiers of features you want to install; knowing the correct feature ID might not be immediate to discover, if you’re only used to the names you see in the update manager.

For instance, say that you want to install Xtext SDK, from the site http://download.eclipse.org/modeling/tmf/xtext/updates/composite/releases/ , then in Eclipse you would do something like in the following screenshot

but instead of “Xtext SDK“, in the command line, you should specify org.eclipse.xtext.sdk.feature.group. While in this case it was easy to infer the feature ID, but… at least for me, it was not immediate to know that “Eclipse Java EE Developer Tools” feature is indeed org.eclipse.jst.enterprise_ui.feature.feature.group !!! :)

Fortunately, you can get to know that by clicking that “More…” link in the above screenshot, which leads you an information dialog where you can easily find the identifier of the selected feature:

Of course you can also have the list of all the contents of an update site, by using the option -list:

./eclipse \
-clean -purgeHistory \
-application org.eclipse.equinox.p2.director \
-noSplash \
-repository <repo1> -list

For instance, this is the command line I use to install in the Xtext eclipse distribution (http://www.eclipse.org/Xtext/download.html) additional stuff like the Xpand SDK, some Mylyn connectors, SwtBot and EMF CDO:

./eclipse \
-clean -purgeHistory \
-application org.eclipse.equinox.p2.director \
-noSplash \
-repository \

http://download.eclipse.org/modeling/tmf/xtext/updates/composite/releases/,\


http://download.eclipse.org/releases/juno,\


http://download.eclipse.org/technology/swtbot/helios/dev-build/update-site,\

http://update.atlassian.com/atlassian-eclipse-plugin/e3.8 \
-installIUs \
org.eclipse.xpand.sdk.feature.group,\
org.eclipse.swtbot.eclipse.feature.group,\
org.eclipse.swtbot.eclipse.test.junit4.feature.group,\
org.eclipse.swtbot.feature.group,\
org.eclipse.swtbot.forms.feature.group,\
org.eclipse.swtbot.ide.feature.group,\
org.eclipse.egit.mylyn.feature.group,\
org.eclipse.mylyn.bugzilla_feature.feature.group,\
org.eclipse.mylyn.builds.feature.group,\
org.eclipse.mylyn.context_feature.feature.group,\
org.eclipse.mylyn.discovery.feature.group,\
org.eclipse.mylyn.gerrit.feature.feature.group,\
org.eclipse.mylyn.git.feature.group,\
org.eclipse.mylyn.github.feature.feature.group,\
org.eclipse.mylyn.hudson.feature.group,\
org.eclipse.mylyn.ide_feature.feature.group,\
org.eclipse.mylyn.java_feature.feature.group,\
org.eclipse.mylyn.monitor.feature.group,\
org.eclipse.mylyn.pde_feature.feature.group,\
org.eclipse.mylyn.tasks.ide.feature.group,\
org.eclipse.mylyn.team_feature.feature.group,\
org.eclipse.mylyn.trac_feature.feature.group,\
org.eclipse.mylyn.wikitext_feature.feature.group,\
org.eclipse.mylyn_feature.feature.group,\
org.eclipse.emf.cdo.sdk.feature.group,\
org.eclipse.emf.query.sdk.feature.group,\
com.atlassian.connector.eclipse.jira.feature.group \
-vmargs -Declipse.p2.mirrors=true -Djava.net.preferIPv4Stack=true

The final -vmargs are just some additional arguments which you may want to skip.

Hope this helps :)

Be Sociable, Share!