|
Re: SWTBot hangs at click() [message #1384642 is a reply to message #1384640] |
Thu, 29 May 2014 21:29 |
|
On 29/05/2014 22:42, Robert Munteanu wrote:
> Hi,
>
> I'm trying to automate a simple new project wizard using SwtBot 2.2.1 .
> The code is the one that I've found in the tutorial
>
> bot.menu("File").menu("New").menu("Project...").click();
Hi
after click() is executed what does your test do? Is it getting the
shell corresponding to the dialog?
>
> The problem is that the click() method call never returns. My target
You say that it never returns because you're debugging it? In case
you're debugging it, then I think that method will never return because
you "stole" the focus to the Swtbot test....
> platform is Eclipse Kepler on Linux x86_64 . The new project dialog is
> brought up however, so I'm not sure why the call does not return. Here's
> a screenshot of what the Eclipse instance under test looks like when the
> test hangs
>
>
>
> The stack trace of the main thread is
>
> "main" prio=10 tid=0x00007f12c0006000 nid=0x428b runnable
> [0x00007f12c68d2000]
> java.lang.Thread.State: RUNNABLE
> at org.eclipse.swt.internal.gtk.OS.Call(Native Method)
> at org.eclipse.swt.widgets.Display.sleep(Display.java:4233)
> at org.eclipse.jface.window.Window.runEventLoop(Window.java:827)
> at org.eclipse.jface.window.Window.open(Window.java:802)
> at
> org.eclipse.ui.actions.NewProjectAction.run(NewProjectAction.java:117)
> at org.eclipse.jface.action.Action.runWithEvent(Action.java:499)
> at
> org.eclipse.jface.action.ActionContributionItem.handleWidgetSelection(ActionContributionItem.java:584)
>
> at
> org.eclipse.jface.action.ActionContributionItem.access$2(ActionContributionItem.java:501)
>
> at
> org.eclipse.jface.action.ActionContributionItem$5.handleEvent(ActionContributionItem.java:411)
>
> at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
> at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1392)
> at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1416)
> at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1401)
> at org.eclipse.swt.widgets.Widget.notifyListeners(Widget.java:1187)
> at
> org.eclipse.swtbot.swt.finder.widgets.AbstractSWTBot$2.run(AbstractSWTBot.java:166)
>
> at
> org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable$5.doRun(UIThreadRunnable.java:221)
>
> at
> org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable.run(UIThreadRunnable.java:78)
>
> at
> org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable.asyncExec(UIThreadRunnable.java:223)
>
> at
> org.eclipse.swtbot.swt.finder.widgets.AbstractSWTBot.asyncExec(AbstractSWTBot.java:576)
>
> at
> org.eclipse.swtbot.swt.finder.widgets.AbstractSWTBot.notify(AbstractSWTBot.java:155)
>
> at
> org.eclipse.swtbot.swt.finder.widgets.AbstractSWTBot.notify(AbstractSWTBot.java:136)
>
> at
> org.eclipse.swtbot.swt.finder.widgets.AbstractSWTBot.notify(AbstractSWTBot.java:126)
>
> at
> org.eclipse.swtbot.swt.finder.widgets.SWTBotMenu.click(SWTBotMenu.java:60)
> at
> org.apache.sling.ide.test.impl.ui.NewContentPackageWizardTest.createNewContentProject(NewContentPackageWizardTest.java:55)
>
> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> at
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>
> at
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
>
> at java.lang.reflect.Method.invoke(Method.java:597)
> at
> org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
>
> at
> org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
>
> at
> org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
>
> at
> org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
>
> at org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:48)
> at org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:48)
> at org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:48)
> at org.junit.rules.RunRules.evaluate(RunRules.java:20)
> at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
> at
> org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
>
> at
> org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
>
> at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
> at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
> at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
> at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
> at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
> at
> org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
>
> at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
> at
> org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner.run(SWTBotJunit4ClassRunner.java:54)
>
> at
> org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
>
> at
> org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
>
> at
> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
>
> at
> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
>
> at
> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
>
> at
> org.eclipse.pde.internal.junit.runtime.RemotePluginTestRunner.main(RemotePluginTestRunner.java:62)
>
> at
> org.eclipse.pde.internal.junit.runtime.PlatformUITestHarness$1.run(PlatformUITestHarness.java:47)
>
> at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
> at
> org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:135)
>
> - locked <0x00000000fe4fc480> (a org.eclipse.swt.widgets.RunnableLock)
> at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:3717)
> at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3366)
> at
> org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$9.run(PartRenderingEngine.java:1113)
>
> at
> org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
>
> at
> org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:997)
>
> at
> org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:140)
>
> at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:611)
> at
> org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
>
> at
> org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:567)
> at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:150)
> at
> org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:124)
>
> at
> org.eclipse.pde.internal.junit.runtime.NonUIThreadTestApplication.runApp(NonUIThreadTestApplication.java:54)
>
> at
> org.eclipse.pde.internal.junit.runtime.UITestApplication.runApp(UITestApplication.java:47)
>
> at
> org.eclipse.pde.internal.junit.runtime.NonUIThreadTestApplication.start(NonUIThreadTestApplication.java:48)
>
> at
> org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
>
> at
> org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
>
> at
> org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
>
> at
> org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:354)
>
> at
> org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:181)
>
> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> at
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>
> at
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
>
> at java.lang.reflect.Method.invoke(Method.java:597)
> at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:636)
> at org.eclipse.equinox.launcher.Main.basicRun(Main.java:591)
> at org.eclipse.equinox.launcher.Main.run(Main.java:1450)
> at org.eclipse.equinox.launcher.Main.main(Main.java:1426)
>
> What can I do to make the test run successfully?
>
> (also posted at
> https://stackoverflow.com/questions/23778686/swtbot-hangs-at-click , not
> sure if you watch stackoverflow for questions and thought I'd try here
> as well ).
>
> Thanks,
>
> Robert
--
Lorenzo Bettini, PhD in Computer Science, DI, Univ. Torino
HOME: http://www.lorenzobettini.it
Xtext Book:
http://www.packtpub.com/implementing-domain-specific-languages-with-xtext-and-xtend/book
HOME: http://www.lorenzobettini.it
TDD Book: https://leanpub.com/tdd-buildautomation-ci
Xtext Book: https://www.packtpub.com/application-development/implementing-domain-specific-languages-xtext-and-xtend-second-edition
|
|
|
Re: SWTBot hangs at click() [message #1384671 is a reply to message #1384642] |
Fri, 30 May 2014 08:11 |
Robert Munteanu Messages: 30 Registered: July 2009 |
Member |
|
|
On 05/30/2014 12:29 AM, Lorenzo Bettini wrote:
> On 29/05/2014 22:42, Robert Munteanu wrote:
>> Hi,
>>
>> I'm trying to automate a simple new project wizard using SwtBot 2.2.1 .
>> The code is the one that I've found in the tutorial
>>
>> bot.menu("File").menu("New").menu("Project...").click();
>
> Hi
>
> after click() is executed what does your test do? Is it getting the
> shell corresponding to the dialog?
>
>>
>> The problem is that the click() method call never returns. My target
>
> You say that it never returns because you're debugging it? In case
> you're debugging it, then I think that method will never return because
> you "stole" the focus to the Swtbot test....
>
>> platform is Eclipse Kepler on Linux x86_64 . The new project dialog is
>> brought up however, so I'm not sure why the call does not return. Here's
>> a screenshot of what the Eclipse instance under test looks like when the
>> test hangs
Aaargh, nevermind. I was running the test as a JUnit Plug-In test and
'Run in UI Thread' was checked. Unchecking it makes the test work as
expected.
I only noticed the FAQ entry at [1] now, and I imagine I'm not the only
one. Would it be possible for SWTBot to assert early on that the test is
not running on the UI thread? I can open a bug if needed.
Thanks,
Robert
[1]:
https://wiki.eclipse.org/SWTBot/FAQ#Why_do_I_have_to_run_tests_as_SWTBot_tests.2C_instead_of_PDE-JUnit_tests.3F
>>
>>
>>
>> The stack trace of the main thread is
>>
>> "main" prio=10 tid=0x00007f12c0006000 nid=0x428b runnable
>> [0x00007f12c68d2000]
>> java.lang.Thread.State: RUNNABLE
>> at org.eclipse.swt.internal.gtk.OS.Call(Native Method)
>> at org.eclipse.swt.widgets.Display.sleep(Display.java:4233)
>> at org.eclipse.jface.window.Window.runEventLoop(Window.java:827)
>> at org.eclipse.jface.window.Window.open(Window.java:802)
>> at
>> org.eclipse.ui.actions.NewProjectAction.run(NewProjectAction.java:117)
>> at org.eclipse.jface.action.Action.runWithEvent(Action.java:499)
>> at
>> org.eclipse.jface.action.ActionContributionItem.handleWidgetSelection(ActionContributionItem.java:584)
>>
>> at
>> org.eclipse.jface.action.ActionContributionItem.access$2(ActionContributionItem.java:501)
>>
>> at
>> org.eclipse.jface.action.ActionContributionItem$5.handleEvent(ActionContributionItem.java:411)
>>
>> at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
>> at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1392)
>> at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1416)
>> at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1401)
>> at org.eclipse.swt.widgets.Widget.notifyListeners(Widget.java:1187)
>> at
>> org.eclipse.swtbot.swt.finder.widgets.AbstractSWTBot$2.run(AbstractSWTBot.java:166)
>>
>> at
>> org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable$5.doRun(UIThreadRunnable.java:221)
>>
>> at
>> org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable.run(UIThreadRunnable.java:78)
>>
>> at
>> org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable.asyncExec(UIThreadRunnable.java:223)
>>
>> at
>> org.eclipse.swtbot.swt.finder.widgets.AbstractSWTBot.asyncExec(AbstractSWTBot.java:576)
>>
>> at
>> org.eclipse.swtbot.swt.finder.widgets.AbstractSWTBot.notify(AbstractSWTBot.java:155)
>>
>> at
>> org.eclipse.swtbot.swt.finder.widgets.AbstractSWTBot.notify(AbstractSWTBot.java:136)
>>
>> at
>> org.eclipse.swtbot.swt.finder.widgets.AbstractSWTBot.notify(AbstractSWTBot.java:126)
>>
>> at
>> org.eclipse.swtbot.swt.finder.widgets.SWTBotMenu.click(SWTBotMenu.java:60)
>> at
>> org.apache.sling.ide.test.impl.ui.NewContentPackageWizardTest.createNewContentProject(NewContentPackageWizardTest.java:55)
>>
>> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>> at
>> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>>
>> at
>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
>>
>> at java.lang.reflect.Method.invoke(Method.java:597)
>> at
>> org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
>>
>> at
>> org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
>>
>> at
>> org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
>>
>> at
>> org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
>>
>> at org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:48)
>> at org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:48)
>> at org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:48)
>> at org.junit.rules.RunRules.evaluate(RunRules.java:20)
>> at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
>> at
>> org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
>>
>> at
>> org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
>>
>> at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
>> at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
>> at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
>> at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
>> at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
>> at
>> org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
>>
>> at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
>> at
>> org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner.run(SWTBotJunit4ClassRunner.java:54)
>>
>> at
>> org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
>>
>> at
>> org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
>>
>> at
>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
>>
>> at
>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
>>
>> at
>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
>>
>> at
>> org.eclipse.pde.internal.junit.runtime.RemotePluginTestRunner.main(RemotePluginTestRunner.java:62)
>>
>> at
>> org.eclipse.pde.internal.junit.runtime.PlatformUITestHarness$1.run(PlatformUITestHarness.java:47)
>>
>> at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
>> at
>> org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:135)
>>
>> - locked <0x00000000fe4fc480> (a org.eclipse.swt.widgets.RunnableLock)
>> at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:3717)
>> at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3366)
>> at
>> org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$9.run(PartRenderingEngine.java:1113)
>>
>> at
>> org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
>>
>> at
>> org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:997)
>>
>> at
>> org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:140)
>>
>> at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:611)
>> at
>> org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
>>
>> at
>> org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:567)
>> at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:150)
>> at
>> org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:124)
>>
>> at
>> org.eclipse.pde.internal.junit.runtime.NonUIThreadTestApplication.runApp(NonUIThreadTestApplication.java:54)
>>
>> at
>> org.eclipse.pde.internal.junit.runtime.UITestApplication.runApp(UITestApplication.java:47)
>>
>> at
>> org.eclipse.pde.internal.junit.runtime.NonUIThreadTestApplication.start(NonUIThreadTestApplication.java:48)
>>
>> at
>> org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
>>
>> at
>> org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
>>
>> at
>> org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
>>
>> at
>> org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:354)
>>
>> at
>> org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:181)
>>
>> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>> at
>> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>>
>> at
>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
>>
>> at java.lang.reflect.Method.invoke(Method.java:597)
>> at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:636)
>> at org.eclipse.equinox.launcher.Main.basicRun(Main.java:591)
>> at org.eclipse.equinox.launcher.Main.run(Main.java:1450)
>> at org.eclipse.equinox.launcher.Main.main(Main.java:1426)
>>
>> What can I do to make the test run successfully?
>>
>> (also posted at
>> https://stackoverflow.com/questions/23778686/swtbot-hangs-at-click , not
>> sure if you watch stackoverflow for questions and thought I'd try here
>> as well ).
>>
>> Thanks,
>>
>> Robert
>
>
|
|
|
Re: SWTBot hangs at click() [message #1384703 is a reply to message #1384671] |
Fri, 30 May 2014 14:32 |
|
On 30/05/2014 10:11, Robert Munteanu wrote:
> On 05/30/2014 12:29 AM, Lorenzo Bettini wrote:
>> On 29/05/2014 22:42, Robert Munteanu wrote:
>>> Hi,
>>>
>>> I'm trying to automate a simple new project wizard using SwtBot 2.2.1 .
>>> The code is the one that I've found in the tutorial
>>>
>>> bot.menu("File").menu("New").menu("Project...").click();
>>
>> Hi
>>
>> after click() is executed what does your test do? Is it getting the
>> shell corresponding to the dialog?
>>
>>>
>>> The problem is that the click() method call never returns. My target
>>
>> You say that it never returns because you're debugging it? In case
>> you're debugging it, then I think that method will never return because
>> you "stole" the focus to the Swtbot test....
>>
>>> platform is Eclipse Kepler on Linux x86_64 . The new project dialog is
>>> brought up however, so I'm not sure why the call does not return. Here's
>>> a screenshot of what the Eclipse instance under test looks like when the
>>> test hangs
>
> Aaargh, nevermind. I was running the test as a JUnit Plug-In test and
> 'Run in UI Thread' was checked. Unchecking it makes the test work as
> expected.
>
> I only noticed the FAQ entry at [1] now, and I imagine I'm not the only
> one. Would it be possible for SWTBot to assert early on that the test is
> not running on the UI thread? I can open a bug if needed.
>
> Thanks,
>
> Robert
>
> [1]:
> https://wiki.eclipse.org/SWTBot/FAQ#Why_do_I_have_to_run_tests_as_SWTBot_tests.2C_instead_of_PDE-JUnit_tests.3F
Hi Robert
if you run the test using the SWTBot test launch instead of Plug-in test
launch it will take care of using the right thread
cheers
Lorenzo
--
Lorenzo Bettini, PhD in Computer Science, DI, Univ. Torino
HOME: http://www.lorenzobettini.it
Xtext Book:
http://www.packtpub.com/implementing-domain-specific-languages-with-xtext-and-xtend/book
HOME: http://www.lorenzobettini.it
TDD Book: https://leanpub.com/tdd-buildautomation-ci
Xtext Book: https://www.packtpub.com/application-development/implementing-domain-specific-languages-xtext-and-xtend-second-edition
|
|
|
|
|
|
Powered by
FUDForum. Page generated in 0.03771 seconds