-
Notifications
You must be signed in to change notification settings - Fork 1
Building standalone Java applications
Bundling Eclipse plug-ins into Java applications using Maven is non-trivial, as one has to consider both the Maven and OSGi dependencies during the build. In general, Maven does not support loading dependencies from p2 repositories, unless some plug-in, like Tycho makes it available. However, using Tycho to build executable jars is not the best way to go, as a lot of Maven plug-ins (e.g. ones required to build the applications) does have some issues with the classpath created with Tycho.
In general, we follow the following approach:
- During development all functionality that requires the Platform to be loaded should be separated into different classes. This way, a standalone application does not have to load everything (less dependencies, less issues)
- Build all plug-ins with Tycho
- Have a standalone Maven module that represents the executable application. Does not have to contain any code at all; but usually has to redefine dependencies.
- When copying the separate dependency jars into a single directory, make sure the classpath has the same strings as the jar names. Some maven plugins may handle version informations differently, thus the required jars might not get loaded causing
ClassNotFoundException
. We haven't found a solution to this problem, we opted to use fat-jar instead since it doesn't have this problem. A typical case where these issues come forth: - Referred dependency was built with Maven/Tycho, and the resulting artifacts are put into a remote repository.
- The
maven-dependency-plugin
and themaven-jar-plugin
uses the snapshot qualifier differently in this case, thus the filenames of the copied artifacts and the manifest.mf entry are different. - To create fat-jar with maven, use the
maven-shade-plugin
and themaven-jar-plugin
. Themaven-jar-plugin
only provides the main class while themaven-shade-plugin
assembles the jar. Be careful with themiminizeJar
option as it might remove required dependencies from the jar. - When building fat-jar, exclude
*.RSA
,*.DSA
and*.SF
files, otherwise security exceptions may get thrown. This can be done withmaven-shade-plugin
's filters. - The
2.9.0.rc
versions of Xtext limits the upper version of Guava to 14.0.1. This can cause issues since eclipse uses 15.0. To circumvent this issue, exclude the Guava dependency from all Xtext dependencies and add it manually to the pom. See corresponding bug report for details. - Usually, it is a good idea to prevent the Java application to traverse the OSGi dependencies being traversed, instead provide maven dependencies for the Java application. For that, Maven has exclusion rules, but the * exclusion requires recent Maven versions (3.1+) to work correctly; and Maven 3.1 is known to throw warnings for wildcard exclusion rules.
<dependency>
<groupId>org.eclipse.incquery</groupId>
<artifactId>org.eclipse.incquery.querybasedfeatures.runtime</artifactId>
<version>${incquery.version}</version>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
- debug the built application with Eclipse remote debugging: www.onkarjoshi.com/blog/224/how-to-suspend-vm-on-startup-when-remote-debugging-your-java-app/
- register everything manually that would otherwise happen through extensions, this includes, among others:
- resource factories for EMF
- EPackages (XPackage.eInstance.eClass
- URI mappings (pathmaps)
- Xtext standalone injectors
- UML profiles (https://www.eclipse.org/forums/index.php/t/580003/),
UMLPlugin.EPackageNsURIToProfileLocationMap.put(XPackage.eNS_URI, URI.createURI("pathmap://<resourceUri>#_<fragment>"))
- If the type mapping checker is used, make sure that the IncQuery UML standalone setup is performed, otherwise the qualified names of primitive types cannot be resolved.
The standalone EMDW compiler has the following high-level dependencies (and all their transitive dependencies):
- UML (metamodel, profiles, etc.)
- EMF-IncQuery runtime
- VIATRA runtime
- Xtext runtime (for rAlf)
- XSemantics runtime (for rAlf)
The organization of the code allows to reduce the required dependencies of the final application. In general, all classes that are referred by the main application (either directly or indirectly) are required to be available in the classpath; if some classes are not loaded, the Java application can ignore those dependencies for the execution (of course, the Tycho-based compilation requires them). For this reason, the following table collects all dependencies used by the Java application (selected by Tycho), and are categorized by them being readily available as a Maven dependency (OK), currently not available in official maven repositories (NEEDED), unnecessary (DONTCARE!) or unknown (??).
Generally, the dependencies on the Eclipse Platform itself should be minimized (in case of Xtext, it is not possible to remove it entirely; a small subset of classes are used from it); all these dependencies should be used with extra care, as any code from there could require the platform itself being running (not true in standalone Java applications).
status | name |
---|---|
?? | org.eclipse.uml2.codegen.ecore |
?? | org.eclipse.emf.codegen |
?? | org.eclipse.emf.codegen.ecore |
?? | org.eclipse.emf.mapping.ecore2xml |
?? | org.eclipse.uml2.uml.profile.standard |
DONTCARE! | com.ibm.icu |
DONTCARE! | org.eclipse.core.commands |
DONTCARE! | org.eclipse.core.contenttype |
DONTCARE! | org.eclipse.core.expressions |
DONTCARE! | org.eclipse.core.filesystem |
DONTCARE! | org.eclipse.core.filesystem.java7" fragment="true |
DONTCARE! | org.eclipse.core.filesystem.win32.x86_64" fragment="true |
DONTCARE! | org.eclipse.core.jobs |
DONTCARE! | org.eclipse.core.resources |
DONTCARE! | org.eclipse.core.resources.win32.x86_64" fragment="true |
DONTCARE! | org.eclipse.core.runtime |
DONTCARE! | org.eclipse.core.runtime.compatibility.registry" fragment="true |
DONTCARE! | org.eclipse.core.variables |
DONTCARE! | org.eclipse.debug.core |
DONTCARE! | org.eclipse.equinox.app |
DONTCARE! | org.eclipse.equinox.common |
DONTCARE! | org.eclipse.equinox.preferences |
DONTCARE! | org.eclipse.equinox.registry |
DONTCARE! | org.eclipse.jdt.compiler.apt" fragment="true |
DONTCARE! | org.eclipse.jdt.compiler.tool" fragment="true |
DONTCARE! | org.eclipse.jdt.core |
DONTCARE! | org.eclipse.jdt.debug |
DONTCARE! | org.eclipse.jdt.launching |
DONTCARE! | org.eclipse.osgi |
DONTCARE! | org.eclipse.osgi.compatibility.state" fragment="true |
DONTCARE! | org.eclipse.text |
NEEDED! | org.eclipse.incquery.querybasedfeatures.runtime |
NEEDED! | org.eclipse.incquery.uml |
NEEDED! | org.eclipse.incquery.validation.core |
OK! | com.ericsson.xtumlrt.oopl.cpp.model |
OK! | com.ericsson.xtumlrt.oopl.model |
OK! | com.google.guava |
OK! | com.google.inject |
OK! | com.google.inject.multibindings" fragment="true |
OK! | com.incquerylabs.emdw.cpp.app |
OK! | com.incquerylabs.emdw.cpp.bodyconverter |
OK! | com.incquerylabs.emdw.cpp.codegeneration |
OK! | com.incquerylabs.emdw.cpp.common |
OK! | com.incquerylabs.emdw.cpp.transformation |
OK! | com.incquerylabs.emdw.snippet.model |
OK! | com.incquerylabs.emdw.toolchain |
OK! | com.incquerylabs.emdw.umlintegration.queries |
OK! | com.incquerylabs.emdw.umlintegration.trace |
OK! | com.incquerylabs.emdw.umlintegration.transformation |
OK! | com.incquerylabs.emdw.valuedescriptor.model |
OK! | com.incquerylabs.emdw.xtuml.incquery |
OK! | com.incquerylabs.emdw.xtuml.incquery.validation |
OK! | com.incquerylabs.uml.ralf |
OK! | com.incquerylabs.uml.ralf.snippetcompiler |
OK! | it.xsemantics.runtime |
OK! | javax.inject |
OK! | javax.xml |
OK! | org.antlr.runtime |
OK! | org.apache.log4j |
OK! | org.eclipse.emf.common |
OK! | org.eclipse.emf.ecore |
OK! | org.eclipse.emf.ecore.xmi |
OK! | org.eclipse.incquery.patternlanguage |
OK! | org.eclipse.incquery.patternlanguage.emf |
OK! | org.eclipse.incquery.runtime |
OK! | org.eclipse.incquery.runtime.base |
OK! | org.eclipse.incquery.runtime.base.itc |
OK! | org.eclipse.incquery.runtime.evm |
OK! | org.eclipse.incquery.runtime.matchers |
OK! | org.eclipse.incquery.runtime.rete |
OK! | org.eclipse.incquery.runtime.rete.recipes |
OK! | org.eclipse.papyrusrt.xtumlrt.common.model |
OK! | org.eclipse.papyrusrt.xtumlrt.xtuml.model |
OK! | org.eclipse.uml2 |
OK! | org.eclipse.uml2.common |
OK! | org.eclipse.uml2.types |
OK! | org.eclipse.uml2.uml |
OK! | org.eclipse.uml2.uml.resources |
OK! | org.eclipse.viatra.emf.runtime |
OK! | org.eclipse.xtend.lib |
OK! | org.eclipse.xtend.lib.macro |
OK! | org.eclipse.xtext |
OK! | org.eclipse.xtext.common.types |
OK! | org.eclipse.xtext.logging" fragment="true |
OK! | org.eclipse.xtext.util |
OK! | org.eclipse.xtext.xbase |
OK! | org.eclipse.xtext.xbase.lib |
OK! | org.objectweb.asm |