Eclipse Maven Tycho Xtext Archetype

Xtext comes with pretty good documentation, but if you want to automate the build for your little new DSL, you’re drifting into deep water. There is some documentation on the Net, but even if you are an advanced Maven user, it’s easy to get lost with the Tycho plugin.

That’s why I made a Maven Archetype that creates a standard multi-module Maven layout and that also includes a P2 repository project, which is missing when you use the standard Eclipse Xtext wizard.

If you just want to use the default settings, simply execute the following on the command line:

mvn archetype:generate \
  -DarchetypeGroupId=org.fuin.archetypes \
  -DarchetypeArtifactId=emt-xtext-archetype \
  -DarchetypeVersion=0.1.0

It will generate the following project structure:

>com.mycompany.mydsl
|-- com.mycompany.mydsl.dsl
|-- com.mycompany.mydsl.repository
|-- com.mycompany.mydsl.sdk
|-- com.mycompany.mydsl.tests
|-- com.mycompany.mydsl.ui
`-- mydsl-test
.mydsl Maven parent project. [Maven project]
.mydsl.dsl Grammar and base classes for the DSL [Tycho ‘eclipse-plugin’]
.mydsl.repository Creates a P2 repository. [Tycho ‘eclipse-repository’]
.mydsl.sdk Eclipse feature project [Tycho ‘eclipse-feature’]
.mydsl.tests Unit test project. [Tycho ‘eclipse-test-plugin’]
.mydsl.ui UI related parts. [Tycho ‘eclipse-plugin’]
.mydsl-test Example DSL project. [Eclipse project]

When you start creating a real project, you should also add the other parameters that are available for the generate command.

For a full description of the archetype, just visit the project page on GitHub: https://github.com/fuinorg/emt-xtext-archetype

Advertisements

EclipseLink: How to get the SQL translated with the arguments for a Query?

The documentation at the EclipseLink Wiki is not very helpful: http://wiki.eclipse.org/EclipseLink/FAQ/JPA#How_to_get_the_SQL_for_a_Query.3F

It says: “To get the SQL translated with the arguments you need a DatabaseRecord with the parameter values.“.

// BEGIN Snippet from the Wiki

Session session = em.unwrap(JpaEntityManager).getActiveSession();

DatabaseQuery databaseQuery = 
  ((EJBQueryImpl)query).getDatabaseQuery();

String sqlString = databaseQuery
  .getTranslatedSQLString(session, 
       recordWithValues);

// END Snippet from the Wiki

But where to get the recordWithValues variable? Actually the solution is hard to find, but simple: databaseQuery.getTranslationRow()

// This does the trick...

String sqlString = databaseQuery
  .getTranslatedSQLString(session, 
       databaseQuery.getTranslationRow());

// ... to replace the '?' 

SLF4J Logging in Eclipse Plugins

Developing with Maven and pure Java libraries all the time, I never thought it could be a problem to issue a few log statements when developing an Eclipse plugin. But it looks like in the imaginary of an Eclipse developer everything is always inside the Eclipse environment and nothing is outside the Eclipse universe.

If you search for the above headline using Google, one of the first articles you’ll find is one about the “platform logging facility”. But what about 3rd libraries? They cannot use an Eclipse-based logging framework.

In my libraries I use the SLF4J API and leave it up to the user to decide what logging implementation (Log4J, Logback, JDK) he or she wants to use. And that’s exactly what I want to do in Eclipse. It was hard to figure out exactly how to do it, but here are the pieces of that puzzle.

Phase 1: Development

This describes the steps during the development phase of your custom plugin.

Step 1: Get your libaries into a P2 repository

Everything you want to use in Eclipse has to be installed from a P2 repository. But most of the libaries I use are in a Maven repository. As far as I know there is no such thing as a main P2 repository similar to the “Maven Central,” and all libraries I found in P2 repositories were pretty old. So you have to create one by yourself.

Luckily there is a Maven plugin called p2-maven-plugin that converts all your Maven JARs into a single P2 repository. You can upload the plugin to a folder of your website or simply install it from your local hard drive.

For this example you’ll need the following libraries:

  • org.slf4j:slf4j-api:1.6.6
  • org.slf4j:slf4j-log4j12:1.6.6
  • log4j:log4j:1.2.17
  • org.ops4j.pax.logging:pax-logging-api:1.7.0
  • org.ops4j.pax.logging:pax-logging-service:1.7.0
  • org.ops4j.pax.confman:pax-confman-propsloader:0.2.2

Format “groupId:artifactid:version” is as used for the “p2-maven-plugin.” To skip this step you could also use http://www.fuin.org/p2-repository/.

Step 2: Install the SLF4J API in the Eclipse IDE

  1. Select “Help / Install New Software…”.
    Eclipse / Help / Install
  2. Add the P2 repository URL and install the “slf4j-api”—you could directly use the folder from Step 1 with a file URL like this: “file:/pathtoyour/p2-repository/”.Instal Slf4J API
  3. Add the freshly installed “slf4j.api” to your MANIFEST.MF.Dependencies in MANIFEST.MF
  4. Start using SLF4J logs in your code as usual.

Phase 2: Production

This describes the tasks a user of your custom plugin has to complete to start logging with Log4J. The following assumes that your custom plugin is already installed.

Step 1: Install the log libraries in the Eclipse IDE

  1. Select “Help / Install New Software…”.Eclipse / Help / Install
  2. Install the “Equinox Target Components” from the Eclipse Update Site.Install Equinox Target Components
  3. Add the P2 repository URL and install the following plugins:
    • Apache Log4j
    • OPS4J Pax ConfMan–Properties Loader
    • OPS4J Pax Logging–API
    • OPS4J Pax Logging–Service

    Install Log Libs

Step 2: Configure PAX Logging

  1. Set the location for your log configuration in the “eclipse.ini” as “vmarg"

    -vmargs
    -Xms40m
    -Xmx512m
    -Dbundles.configuration.location=<config-dir>

  2. Create a folder named “services” in the above “config-dir.”
  3. Create Log4J properties named “org.ops4j.pax.logging.properties” in “services.”

    log4j.rootLogger=INFO, FILE
    log4j.appender.FILE=org.apache.log4j.FileAppender
    log4j.appender.FILE.File=<path-to-your-log>/example.log
    log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
    log4j.appender.FILE.layout.ConversionPattern=%d{yyyy/MM/dd HH:mm:ss,SSS} [%t] %-5p %c %x - %m%n
    log4j.logger.your.package=DEBUG

Step 3: Activate PAX Logging

  1. Open the “Console” view.Show Console View
  2. Select the “Host OSGI Console.”Select OSGI Console
  3. Start the following bundles:
    start org.eclipse.equinox.cm
    start org.ops4j.pax.logging.pax-logging-api
    start org.ops4j.pax.logging.pax-logging-service
    start org.ops4j.pax.configmanager

    Start logging bundles

Now you should be able to see your log statements in the configured “example.log” file.

Step 4: Changing the configuration

If you want to change the configuration in the “org.ops4j.pax.logging.properties”, simply restart the PAX Configmanager in the OSGI console:

stop org.ops4j.pax.configmanager
start org.ops4j.pax.configmanager

Happy Logging!

Maven Tycho uses old JAR files

During the development of SrcMixins4J I faced a strange problem with Tycho: I updated one of the libraries (srcmixins4j-core.jar) without incrementing the version number. I know this is not the standard “-SNAPSHOT” way, but I never had a problem with this before. Maven can handle such updates easily. Inside Eclipse everything was fine, but building with Maven outside Eclipse still referenced the old version and I got compile errors.

It took me some time to figure out that Tycho stores a second copy of the referenced JARs in the Maven repository. There is a folder named “p2/osgi/bundle”.

After deleting the “p2/osgi/bundle/org.fuin.srcmixins4j.core” folder, Tycho finally loaded the new version.