Home » Modeling » TMF (Xtext) » Synchronizing version numbers between workstations and a server
Synchronizing version numbers between workstations and a server [message #1752137] |
Thu, 19 January 2017 07:58  |
Akira Tanaka Messages: 98 Registered: March 2010 |
Member |
|
|
Hi, I have a question and would like to have suggestions from experts doing similar things. I am currently involved in a project, where Xtext is used as a foundation. We are developing an Xtext DSL targeting for our web platform (runtime).
In this project each developer uses eclipse (NEON DSL package + Gradle IDE Pack) on his/her workstation as a main development environment, and Gradle is used on a server. Most Gradle settings are created on workstation, and passed to the server, and Java code are generated on the server based on the provided Xtext DSL model and Xtend code.
An issue is that we found small differences in generated Java code between on workstation and on server. Probably it comes from the slightly different Xtext, Xtend etc. version numbers, especially the versions deployed from maven repository seems a bit older than for eclipse (am I right?). Is there any reasonable way to (automatically?) force the same version on both ends using any tooling, or do we need to do it manually? [Use of LSP may be a good solution in future, but we need something now]
Thank you very much for any suggestions in advance.
Akira
|
|
| | |
Re: Synchronizing version numbers between workstations and a server [message #1752221 is a reply to message #1752139] |
Fri, 20 January 2017 05:37   |
Akira Tanaka Messages: 98 Registered: March 2010 |
Member |
|
|
Thank you very much for responses.
Actually what we are experiencing is the following. For this post, please forget about server side Grade build stuff for the moment. If needed, I will explain more in the follow-up message.
Workstation Platforms: Windows 7 64bit and Mac OS X
eclipse: DSL package of NEON.1 and NEON.2 with Gradle IDE Pack
Xtext Complete SDK version: 2.10.0.v201605250459 (same to NEON.1 and NEON.2)
Grammar: extended Domainmodel (only relevant part is shown below)
Model:
importSection=XImportSection?
elements+=AbstractElement*;
AbstractElement:
PackageDeclaration | Object | Function;
PackageDeclaration:
'package' name=QualifiedName '{'
elements+=AbstractElement*
'}';
Object:
DomainObject | Primitive | PList;
DomainObject:
'object' name=ValidID '{'
features+=Feature*
'}';
Primitive:
PString | PLong | PInteger | PDate | PDateTime | PDecimal
;
PInteger:
'integerType' name=ValidID '{'
format=Format?
operations+=Operation*
'}'
;
.....
Function:
Service | Repository | Factory;
.....
Repository:
'repository' name=ValidID '{'
operations+=Interface*
'}'
;
.....
Feature:
Property | Initializer | Operation;
Property:
type=JvmTypeReference name=ValidID;
Operation:
'def' type=JvmTypeReference name=ValidID
'('(params+=FullJvmFormalParameter
(',' params+=FullJvmFormalParameter)*)?')'
body=XBlockExpression
;
Interface:
'def' type=JvmTypeReference name=ValidID
'('(params+=FullJvmFormalParameter
(',' params+=FullJvmFormalParameter)*)?')'
;
Initializer:
'init' '('(params+=FullJvmFormalParameter
(',' params+=FullJvmFormalParameter)*)?')'
body=XBlockExpression
;
and JvmModelInferrer code is like the following (just focused on the issue point):
def dispatch void infer(Repository element, IJvmDeclaredTypeAcceptor acceptor, boolean isPreIndexingPhase) {
acceptor.accept(element.toClass(element.fullyQualifiedName)) [
documentation = element.documentation
interface = true
for (feature : element.operations) {
switch feature {
Interface: {
members += feature.toMethod(feature.name, feature.type) [
documentation = feature.documentation
for (p : feature.params) {
parameters += p.toParameter(p.name, p.parameterType)
}
]
}
}
}
]
}
with above setting, and with the following DSL code,
package com.example.model.customer {
// Data Objects
integerType CustomerId {}
// Repositories
repository CustomerRepository {
def CustomerId next()
def Customer get(CustomerId customerId)
}
}
the following Java code #1 (Java Interface part) is generated (again relevant part only).
@SuppressWarnings("all")
public interface CustomerRepository {
public CustomerId next();
public Customer get(final CustomerId customerId);
}
This is the case with our office's development machines with NEON.1 and NEON.2. However I tried at home on my Mac, this was the case only with NEON.1. Another Java code #2 generated from my NEON.2 (as well as with the case of Gradle built) is the following.
@SuppressWarnings("all")
public interface CustomerRepository {
public default CustomerId next(); <- compile error
public default Customer get(final CustomerId customerId); <- compile error
}
And, this is also the case with Gradle built. The difference is whether "default" is generated or not. We do not know what created the difference, and thought it to be Xtext version difference issue. However, I now see this happening with the same Xtext version (#1 with NEON.1 and #2 with NEON.2). Our preference is to not generate "default" in above. If "default" generation happened to be the normal case, we would like to know how to not generate "default" within JvmInferrer code.
Thank you very much for your comments/suggestions again in advance.
|
|
| | | | | | | | | | | |
Re: Synchronizing version numbers between workstations and a server [message #1752477 is a reply to message #1752388] |
Tue, 24 January 2017 09:45   |
Akira Tanaka Messages: 98 Registered: March 2010 |
Member |
|
|
Here is the update.
I was able to reproduce the issue with Xtext's domain model example. Use NEON.1 DSL package as a base, install Gradle IDE Pack, and instantiate Domainmodel example. Replace JvmModelInferrer code with
package org.eclipse.xtext.example.domainmodel.jvmmodel
import com.google.inject.Inject
import org.eclipse.xtext.example.domainmodel.domainmodel.Entity
import org.eclipse.xtext.example.domainmodel.domainmodel.Operation
import org.eclipse.xtext.naming.IQualifiedNameProvider
import org.eclipse.xtext.xbase.jvmmodel.AbstractModelInferrer
import org.eclipse.xtext.xbase.jvmmodel.IJvmDeclaredTypeAcceptor
import org.eclipse.xtext.xbase.jvmmodel.JvmTypesBuilder
class DomainmodelJvmModelInferrer extends AbstractModelInferrer {
@Inject extension JvmTypesBuilder
@Inject extension IQualifiedNameProvider
def dispatch void infer(Entity element, IJvmDeclaredTypeAcceptor
acceptor, boolean isPreIndexingPhase) {
acceptor.accept(element.toClass(element.fullyQualifiedName)) [
documentation = element.documentation
interface = true
for (feature : element.features) {
switch feature {
Operation: {
members += feature.toMethod(feature.name, feature.type) [
documentation = feature.documentation
for (p : feature.params) {
parameters += p.toParameter(p.name, p.parameterType)
}]}}}]}}
Create new eclipse instance by Run -> Run Configuration (as usual). Create Java project, add a model folder and add the following sample model in the folder.
entity Service01 {
op add (Integer x, Integer y) : Integer {
return x + y
} }
With this model, you will see generated Java interface with "default" keyword. Now here comes a tricky part. We put this project into our repository, and when needed, we import it with Gradle(STS), i.e. after putting it into the repository, delete the project, and choose import -> Gradle(STS). You will be guided to build the project with Gradle before selecting the project. build.gradle is shown below.
plugins {
id "eclipse"
id "org.xtext.xtend" version "1.0.0"
id "org.xtext.builder" version "1.0.0"
}
apply plugin: 'java'
repositories {
jcenter()
mavenLocal()
mavenCentral()
}
dependencies {
xtextLanguages 'org.eclipse.xtext.example.domainmodel:jorg.eclipse.xtext.example.domainmodel:1.0.0-SNAPSHOT'
compile 'org.eclipse.xtend:org.eclipse.xtend.lib:2.10.0'
compile 'javax.validation:validation-api:1.1.0.Final'
}
xtext {
languages {
model {
fileExtension = 'dmodel'
setup = 'org.eclipse.xtext.example.domainmodel.DomainmodelStandaloneSetup'
generator.outlet.producesJava = true
}
}
sourceSets {
main {
srcDir 'src/main/model'
}
}
}
BTW please modify srcDir 'src/main/model' if needed. Anyway, after successful import of the project, you will find "default" keyword not shown in generated Java interface code.
So, now we suspect Gradle IDE Pack looks like the cause of the issue (do not know how, though).
|
|
|
Re: Synchronizing version numbers between workstations and a server [message #1752494 is a reply to message #1752477] |
Tue, 24 January 2017 13:38   |
|
the error in the inferrer is this one
members += feature.toMethod(feature.name, feature.type) [
abstract = true // this is the fix
documentation = feature.documentation
for (p : feature.params) {
parameters += p.toParameter(p.name, p.parameterType)
}
]
if you tell the project in eclipse to use java 7 it wil work without the default method
(Properties -> Domainmodel -> Compiler -> project specific settings -> dont inherit from java -> select java7
=> the queston is: why do you have once java 7 and once java 8
as i said JvmModelGenerator does something like
if (!isAbstract && !isStatic && config.getJavaSourceVersion.isAtLeast(JAVA8)
&& eContainer instanceof JvmGenericType && (eContainer as JvmGenericType).isInterface)
appendable.append("default ")
so the question is: how is javaSourceVersion filled in the different usecases.
btw the xtext gradle plugin version you use seems quite old
hmmmm, i dont have the time to reproduce this from scratch,
Need professional support for Xtext, Xpand, EMF?
Go to: https://www.itemis.com/en/it-services/methods-and-tools/xtext
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
|
|
|
Re: Synchronizing version numbers between workstations and a server [message #1752689 is a reply to message #1752494] |
Thu, 26 January 2017 08:24  |
Akira Tanaka Messages: 98 Registered: March 2010 |
Member |
|
|
Thank you very much for the response.
Yes, "abstract = true // this is the fix" is also our tentative solution right now.
"the queston is: why do you have once java 7 and once java 8"
<==
We have no intention to do this. We want to do everything with Java 8 all the time.
"how is javaSourceVersion filled in the different usecases."
<==
Don't know, we do not do that intentionally. As I said, the suspect is old Gradle IDE Pack.
"btw the xtext gradle plugin version you use seems quite old"
<==
Thank you, we will upgrade.
"hmmmm, i dont have the time to reproduce this from scratch,"
<==
OK. Although we do not know how javaSourceVersion was affected, we probably have identified the player in this game. We will use tentative solution for short term, and we would probably move to buildship. So, we can close this case. If, however, something similar happens in the future, we may come back to this thread.
Thank you very much for your help and for your time!
Akira
|
|
|
Goto Forum:
Current Time: Thu Jun 08 06:24:08 GMT 2023
Powered by FUDForum. Page generated in 0.03475 seconds
|