Posted
over 3 years
ago
Do you want to build a web-based tool with more than just a code editor? Is your domain-specific tool based on...
The post Building tools with EMF.cloud – an experience report appeared first on EclipseSource.
|
Posted
over 3 years
ago
Learn how to use Eclipse Collections to solve a Wordle word guessing kataKatas are coding puzzles to keep your skills sharpI love creating and solving code katas. Code Katas are programming puzzles that can help keep your coding skills sharp. I wrote
... [More]
an article titled “Learn to Kata and Kata to Learn” for the “97 Things Every Java Programmer Should Know” book, and the link to the article is available for free here on Medium on the O’Reilly 97 Things publication.Learn to Kata and Kata to LearnThe Wonderful World of WordleWordle is a very popular online puzzle game where you have six chance to guess a five letter word. Each guess results in learning which characters match the characters in the word. You are given hints via colors which let you know if you got a letter correct in the right position, if the letter is in the word but in the wrong position, or if the letter does not match any letter in the word.You can find out more about the Wordle craze in this article.Wordle explained: Everything you need to know to master the viral word gameJLDD = Jet Lag Driven DevelopmentIn the “before times”, when tech conferences and global travel were a more common occurrence, a few Java Champions (José Paumard, Nikhil Nanivadekar, and myself) would share coding challenges on Twitter while we were at the conferences (usually JavaOne/Oracle CodeOne). We all had various levels of jet lag during the conferences, so we decided to use the JLDD hashtag when we posted the coding challenges. Most often the coding challenges were geared towards solving problems with Java Collections or Streams. I would usually post solutions using Eclipse Collections.Throughout the pandemic we have still occasionally shared JLDD challenges with each other on Twitter, even though the jet lag has cleared up a long time ago. A few weeks ago I shared a Haiku Kata using Java Text Blocks and Eclipse Collections.Haiku for Java using Text BlocksJosé Paumard then went above and beyond and live coded the JLDD challenge in a 25 minute JEP Cafe #9 video. He does an amazing job explaining both the Eclipse Collections and Java 17 solutions. Well done!https://medium.com/media/d954992e8ffb899b6ebe8ff504c2facc/hrefThe Wordle KataJosé Paumard sent me a JLDD challenge this week in the form of a test that I needed to write the code to pass. I love this kind of kata, which follows classic TDD style using a test first approach. Here’s the test code for the kata using plain JUnit 5 assertions.Several hidden words and corresponding guesses that result in some outputThe rules based on this test are fairly straightforward.
If a letter in the guess String doesn’t match a letter in the hidden word, then replace the character in the output with “.”
If a letter in the guess String matches a letter in the hidden word and the letter is in the same position, then replace the character with an uppercase letter.
If a letter in the guess String matches a letter in the hidden word but the letter is in a different position, then replace the character with a lowercase letter.
If a letter matches, but appears more times in the guess String than in the hidden word, then replace the additional characters in the output with a “.”.
My first solution using Eclipse CollectionsThe solution I came up with looked as follows, and passed all of the tests.Code for Wordle guessing using Eclipse CollectionsThe code takes the guess, compares each letter to the hidden word and if there is a direct match, prints an uppercase letter, otherwise it prints a lowercase letter if there is an indirect match or a “.” if there is no match or the letter is an extra matching character. The method collectWithIndex on the CharAdapter type transforms the guessChars String one character at a time. I thought at first that no char values would be boxed as Character objects, but it turns out I was wrong. The method collectWithIndex takes a CharIntToObjectFunction, which means the char values for each output character will be boxed as Character objects. This also means we do not have a purely primitive version of collectWithIndex in Eclipse Collections, like we do with collectChar. I think this is probably acceptable in most cases, and should not be too costly for this particular use case. I don’t think adding a purely primitive version named collectCharWithIndex would carry its weight.There is however a bigger problem than boxing char values as Character objects before creating the output String. I discovered there was a missing test case, and an additional rule that we should add to the kata.Rule: Favor direct matches over indirect matchesI added the following test case that causes my first solution to fail.A word that has a direct match at one letter, but indirect matches occur before the direct matchLet me zoom in so you can see the test case more clearly.The output for a word “bbabb” with a guess of “aaaaa” should be “..A..”In this case, the letter “a” will have a direct match in the third position, but the indirect matches in the guess should be ignored in favor of the direct match in the third position.My updated solutionFor folks who know me, you’ll know I am somewhat obsessed with providing good symmetry in the Eclipse Collection API. With this particular use case, it would be ideal if there was an equivalent of selectWithIndex and rejectWithIndex available on the primitive collection types in Eclipse Collections. This particular use case might get me to acquiesce here and add the missing methods.There is however an alternative method that I can use to implement the equivalent of these two methods. That method is injectIntoWithIndex.Here is my updated solution using injectIntoWithIndex to create a CharBag with the remaining characters that do not have direct matches.Wordle guessing solution that handles all rulesIf you want to understand how the injectIntoWithIndex method works, you can read the following blog on injectInto. The method injectInto can be used to implement most iteration patterns, which is also the case with injectIntoWithIndex. They are both mysterious and powerful methods.EC by Example: InjectIntoThe Source for my Final Eclipse Collections SolutionI’ve created a gist for my final Wordle JLDD Kata challenge solution using Eclipse Collections. I’m looking forward to seeing the pure Java 17 solution from José Paumard. I always learn new and interesting things about Java from José that I didn’t know before.https://medium.com/media/20eb47a2688394fd9b3efd90d94539c8/hrefFinal ThoughtsI hope you enjoyed this blog on my solutions to a JLDD Kata challenge using Eclipse Collections. I’d certainly welcome other solutions to these challenges so we can all learn new and different solutions to programming problems. These solutions could be in Java using your favorite libraries, or even in another programming language.Thank you for taking the time to read!I am a Project Lead and Committer for the Eclipse Collections OSS project at the Eclipse Foundation. Eclipse Collections is open for contributions. If you like the library, you can let us know by starring it on GitHub. [Less]
|
Posted
over 3 years
ago
Learn how to use Eclipse Collections to solve a Wordle word guessing kataKatas are coding puzzles to keep your skills sharpI love creating and solving code katas. Code Katas are programming puzzles that can help keep your coding skills sharp. I wrote
... [More]
an article titled “Learn to Kata and Kata to Learn” for the “97 Things Every Java Programmer Should Know” book, and the link to the article is available for free here on Medium on the O’Reilly 97 Things publication.Learn to Kata and Kata to LearnThe Wonderful World of WordleWordle is a very popular online puzzle game where you have six chance to guess a five letter word. Each guess results in learning which characters match the characters in the word. You are given hints via colors which let you know if you got a letter correct in the right position, if the letter is in the word but in the wrong position, or if the letter does not match any letter in the word.You can find out more about the Wordle craze in this article.Wordle explained: Everything you need to know to master the viral word gameJLDD = Jet Lag Driven DevelopmentIn the “before times”, when tech conferences and global travel were a more common occurrence, a few Java Champions (José Paumard, Nikhil Nanivadekar, and myself) would share coding challenges on Twitter while we were at the conferences (usually JavaOne/Oracle CodeOne). We all had various levels of jet lag during the conferences, so we decided to use the JLDD hashtag when we posted the coding challenges. Most often the coding challenges were geared towards solving problems with Java Collections or Streams. I would usually post solutions using Eclipse Collections.Throughout the pandemic we have still occasionally shared JLDD challenges with each other on Twitter, even though the jet lag has cleared up a long time ago. A few weeks ago I shared a Haiku Kata using Java Text Blocks and Eclipse Collections.Haiku for Java using Text BlocksJosé Paumard then went above and beyond and live coded the JLDD challenge in a 25 minute JEP Cafe #9 video. He does an amazing job explaining both the Eclipse Collections and Java 17 solutions. Well done!https://medium.com/media/d954992e8ffb899b6ebe8ff504c2facc/hrefThe Wordle KataJosé Paumard sent me a JLDD challenge this week in the form of a test that I needed to write the code to pass. I love this kind of kata, which follows classic TDD style using a test first approach. Here’s the test code for the kata using plain JUnit 5 assertions.Several hidden words and corresponding guesses that result in some outputThe rules based on this test are fairly straightforward.
If a letter in the guess String doesn’t match a letter in the hidden word, then replace the character in the output with “.”
If a letter in the guess String matches a letter in the hidden word and the letter is in the same position, then replace the character with an uppercase letter.
If a letter in the guess String matches a letter in the hidden word but the letter is in a different position, then replace the character with a lowercase letter.
If a letter matches, but appears more times in the guess String than in the hidden word, then replace the additional characters in the output with a “.”.
My first solution using Eclipse CollectionsThe solution I came up with looked as follows, and passed all of the tests.Code for Wordle guessing using Eclipse CollectionsThe code takes the guess, compares each letter to the hidden word and if there is a direct match, prints an uppercase letter, otherwise it prints a lowercase letter if there is an indirect match or a “.” if there is no match or the letter is an extra matching character. The method collectWithIndex on the CharAdapter type transforms the guessChars String one character at a time. I thought at first that no char values would be boxed as Character objects, but it turns out I was wrong. The method collectWithIndex takes a CharIntToObjectFunction, which means the char values for each output character will be boxed as Character objects. This also means we do not have a purely primitive version of collectWithIndex in Eclipse Collections, like we do with collectChar. I think this is probably acceptable in most cases, and should not be too costly for this particular use case. I don’t think adding a purely primitive version named collectCharWithIndex would carry its weight.There is however a bigger problem than boxing char values as Character objects before creating the output String. I discovered there was a missing test case, and an additional rule that we should add to the kata.Rule: Favor direct matches over indirect matchesI added the following test case that causes my first solution to fail.A word that has a direct match at one letter, but indirect matches occur before the direct matchLet me zoom in so you can see the test case more clearly.The output for a word “bbabb” with a guess of “aaaaa” should be “..A..”In this case, the letter “a” will have a direct match in the third position, but the indirect matches in the guess should be ignored in favor of the direct match in the third position.My updated solutionFor folks who know me, you’ll know I am somewhat obsessed with providing good symmetry in the Eclipse Collection API. With this particular use case, it would be ideal if there was an equivalent of selectWithIndex and rejectWithIndex available on the primitive collection types in Eclipse Collections. This particular use case might get me to acquiesce here and add the missing methods.There is however an alternative method that I can use to implement the equivalent of these two methods. That method is injectIntoWithIndex.Here is my updated solution using injectIntoWithIndex to create a CharBag with the remaining characters that do not have direct matches.Wordle guessing solution that handles all rulesIf you want to understand how the injectIntoWithIndex method works, you can read the following blog on injectInto. The method injectInto can be used to implement most iteration patterns, which is also the case with injectIntoWithIndex. They are both mysterious and powerful methods.EC by Example: InjectIntoThe Source for my Final Eclipse Collections SolutionI’ve created a gist for my final Wordle JLDD Kata challenge solution using Eclipse Collections. I’m looking forward to seeing the pure Java 17 solution from José Paumard. I always learn new and interesting things about Java from José that I didn’t know before.https://medium.com/media/20eb47a2688394fd9b3efd90d94539c8/hrefFinal ThoughtsI hope you enjoyed this blog on my solutions to a JLDD Kata challenge using Eclipse Collections. I’d certainly welcome other solutions to these challenges so we can all learn new and different solutions to programming problems. These solutions could be in Java using your favorite libraries, or even in another programming language.Thank you for taking the time to read!I am a Project Lead and Committer for the Eclipse Collections OSS project at the Eclipse Foundation. Eclipse Collections is open for contributions. If you like the library, you can let us know by starring it on GitHub.A Wordle JLDD Kata Challenge was originally published in Oracle Developers on Medium, where people are continuing the conversation by highlighting and responding to this story. [Less]
|
Posted
over 3 years
ago
I know… I am late for an happy new year but I am not for an Happy New 2022.01.0!
I’m in a dancing mood while I’m writing this… (and poor you) an idea comes to my mind: “Why not associate a song to each new feature?”
It could be funny and it’ll result
... [More]
in a (terrible) soundtrack to play with this new version.
Follow me for a musical ride through the new Sirius Web and OCP features!
Calendar versioning
January, February, March, April, May
June, July
January, February, March, April, May
June, July
—Boney M., Calendar song
For two years now, we have been working hard on Sirius Web in the open. Since the last 2021.12.0 version, Sirius Web released its first stable version. From now on, we will make sure to not break (too much) APIs for our Sirius Components customers. We decided to switch from semantic versioning to calendar versioning to reflect the maturity of the project.
Our development cycle for each release consists of six weeks of active development and two weeks for various minor improvements.
Once a stable release “YEAR.MONTH.0” is done, we will start working on the next one “YEAR.MONTH+2.0”. During the preparation of the next release, we will improve the current branch to prepare for that release. As a result, we will have multiple intermediate releases with a YEAR.MONTH.1, YEAR.MONTH.2… YEAR.MONTH.42, etc. Those releases should be considered as milestones for the next stable one.
The changes made are tracked in the CHANGELOG where you can find a fine grained list of all the API breaks, new features, bug fixes and various improvements.
Magic connector
It's a kind of magic
It's a kind of magic
A kind of magic (No way)
One dream, one CONNECTOR
—Almost Queen, A Kind of Magic
A new “Magic Connector” tool is available on diagrams. It provides an alternative way to create edges between diagram elements:
choose the generic Connector tool from the source node’s palette
select the target node
choose which of the compatible tools to apply in the menu appears. If there is only one tool defined, it will be applied automatically without showing the menu.
DnD for Unsync diagram
Accepts she's out of sync
She's out of sync (sync)
She's out of sync (sync)
She's out of sync
—Devo, Out of sync
Since the 2021.10.0 release, it is possible to create so-called unsynchronized diagrams with Sirius Web. Where a synchronized diagram automatically computes the elements of the model displayed, an unsynchronized diagram allows the user to select the elements he wants (according to the rules defined by the diagram).
We also added support for “Delete from Diagram”, to delete graphical elements without deleting the corresponding semantic element in unsynchronized diagrams.
It is now also possible to drag semantic elements from the explorer to a diagram. The concrete effect depends on how the target diagram is defined, but a typical case is to add a graphical representation of the dropped element to the diagram.
Fit to Screen
Now it fits you good
Oh fits you good
Yeah fits you good
Oh fits you good
—Bryan Adams, Fits Ya good
When a diagram is opened, a “Fit to screen” is automatically performed to ensure all its contents are visible. Previously, depending on the coordinates of the elements it could happen that not all of them were visible when opening a diagram.
Stylish studios!
'Cause we never go out of style,
we never go out of style
—Taylor Swift, Style
Release after release we continue to improve the web studio definition capabilities.
Nodes can now have a dynamically computed size (using Size Expression) which depends on the current state of the semantic model. If the expression is present and produces a positive integer, it will be used as both the width and height of the node, in pixels. Currently it is not possible to compute different values for width and height.
It is now possible to define border nodes in the web studio definition.
And finally, it is possible to configure text style on labels: bold, italic, underline, strike-through.
Next
The Obeo team has started a new iteration to prepare 2022.03.0, during which we focus on three topics:
Support of Component-like diagrams with ports and bendpoints for edges,
Diagram user experience to smoothly edit, move, reconnect and layout diagrams,
And…(drum roll)… Tables! I am really enthusiastic about this one, we are cooking something really cool!
A detailed release notes for 2022.01.0 is available in our online documentation: http://docs.obeostudio.com.
As usual, all these changes are made available thanks to our loved customers sponsoring the Sirius Web open source project! Do not hesitate to join the party and become a Sirius Web supporter, it is as easy as sending me an email, or contact the team.
See you soon for the next Sirius Web and OCP soundtrack release! [Less]
|
Posted
over 3 years
ago
This is a guest post by Coder. Authored by Joe Previte (@jsjoeio), Open Source TypeScript Engineer at Coder.
Near the end of 2021, the code-server Team at Coder made the switch from a custom extension marketplace to the Open VSX Registry.
If you
... [More]
haven’t heard, Coder’s on mission to keep developers in flow wherever they go. How? By taking your developer workstation and moving it to the cloud.
Inside your cloud-based workstation, you have access to code-server, VS Code in the browser. Let's talk about embracing Open VSX.
Embracing Open VSX
We decided to embrace Open VSX as our primary extension marketplace for two reasons:
Maintenance cost
Open standard
When code-server first launched, the team created our own extension marketplace. This was around 4 years ago before Open VSX was popular.Since then, the custom marketplace become more and more difficult to maintain. Things break. Extensions go out of date quickly. The team was reduced in size. Open VSX became more ubiquitous as the optimal extension marketplace solution for VS Code-like editors. That reason alone convinced us to switch.
The second reason was that the Open VSX Registry is an open-source registry and operated by a foundation. This alone shows that it’s not a proprietary product with ulterior motives. It truly serves the community. We wanted to embrace that because it aligns with code-server’s values of putting the community first.
As a result, we embraced Open VSX in November 2021 and it vastly improved the UX of code-server as an IDE.
Our Experience Integrating with Open VSX
Switching to Open VSX was a fairly easy task. It was mostly a matter of switching environment variables. The reason we didn’t do it sooner was because of a minor issue around web extensions.
When GitHub released Codespaces, VS Code introduced a concept called "web extensions". They’re the same as regular extensions, except they run in the browser and don’t have access to Node.js APIs. Open VSX didn’t support these right away. Or rather, they didn’t provide all the necessary information.
After that was fixed and code-server was in a good place to switch over, we did so! It’s only been 3 months since we’ve made the switch but overall, the response from the community has been positive!
What We Hope to See Moving Forward
We hope to see the Eclipse Foundation continue building tools that help extension authors publish to both the Microsoft Extension Marketplace and Open VSX. Oftentimes extensions are in one marketplace but not the other. This causes confusion in the community for products like code-server. With more tools to help authors publish to both, it would be a win-win for everyone.
We are also excited by the fact that users can self-host Open VSX registries to support extensions in restrictive and air gapped networks. We hope to work with Eclipse Foundation to add new authentication and deployment options to make this available to more of our users.
Other than that, we hope the Foundation continues supporting this project for years to come. It’s hard to imagine the IDE/editor space without something like Open VSX.
Summary
Both the Coder and the code-server team are very appreciative of the Eclipse Foundation and the project team that maintains Open VSX! It makes the UX of code-server 10x better and reduces the burden of maintaining our own extension marketplace.
You can read more about Coder on our website or check out code-server’s GitHub page for more information. Feel free to pop in the Discussions and say hello!
[Less]
|
Posted
over 3 years
ago
When we launched our redesigned website last year, we also added a new blog section. We then seeded it with some initial posts that already existed, and have continued to add content.
Now, we are looking for even more great blog content, which is
... [More]
where YOU come in! If you are working with, or on, anything in the Cloud DevTools space, here are the options to get your writings posted.
Guidelines
In lieu of potential guidelines for posts, here are two things to keep in mind before you write.
Firstly, your post has to be related to Eclipse cloud developer tools. It is preferred that they are in direct relation to Cloud DevTools working group work or projects. If not, an indirect relation to them might work, for example mentioning technologies like LSP as used in another environment.
Secondly, here’s a tip for when your post is approved and is ready for publication. In order for it to appear optimally in the listing, we recommend each post has a clear summary of what it is about. The best way to do this is using the HTML summary tag, and most blog platforms have a way of surfacing this up for you and making it easy.
Syndication Options
Here are two ways to get listed.
1. Syndicate your blog feed to Planet Eclipse, and tag posts that you want to appear with ‘ECDTools’.
If your blog, or a category within it, is Eclipse-related then getting listed on Planet Eclipse is a great way to get a larger audience. To add your blog to the feed, please have a look at our guidelines and then open a GitHub issue or create a pull request with your feed-specific information. This is the recommended way for your posts to appear on the Cloud DevTools blog.
2. Create a pull request at the Cloud DevTools website repository.
This is the ideal option if you don’t have your own blog. Posts that live natively on the website are written in markdown, a lightweight text format that can embellish content with formatting features. Before starting your post, please file an issue to seek validation for your idea. We recommend this to avoid the situation where you spend some time writing the post, and then the PR is rejected.
In Conclusion
Over time, we’ll be improving our blog in terms of features as well as attracting more traffic. Our objective is to bring a new audience to the work you are doing. Regardless of which method you choose for getting listed, we welcome your ideas and content on the Cloud DevTools blog. We have a vibrant community and we want to share all the goodness that is happening to a broader audience.
[Less]
|
Posted
over 3 years
ago
Any Eclipse RCP Client applications is a set of OSGi bundles started inside an Equinox framework.
The list of bundles that are started and the order is often controlled by the SimpleConfigurator and its bundles.info file.
The
... [More]
bundles.info file is located inside the configuration folder of the Eclipse RCP application.
For Mac OS, it is located inside the *.app file (use the context menu "Show Package Contents" to open it):
MyApp.app
└── Contents
└── Eclipse
└── configuration
└── org.eclipse.equinox.simpleconfigurator
└── bundles.info
For windows or linux it is next to the *.exe file or bin file:
MyApp
├── myapp.exe
└── configuration
└── org.eclipse.equinox.simpleconfigurator
└── bundles.info
The file describes the list of bundles that will be started. It is more or less a CSV file, that looks like this:
#encoding=UTF-8
#version=1
org.eclipse.equinox.app,1.5.100.v20210212-1143,plugins/org.eclipse.equinox.app_1.5.100.v20210212-1143.jar,4,false
org.eclipse.equinox.common,3.14.100.v20210212-1143,plugins/org.eclipse.equinox.common_3.14.100.v20210212-1143.jar,2,true
For each bundle, the bundles.info file contains one line with this information:
symbolic name
version
location
start level
marked as started
The bundles are alphabetically sorted inside a bundles.info file. This make the comparison between two files easy.
The code that is parsing those files can be found in SimpleConfiguratorUtils.java:
SimpleConfiguratorUtils#readConfiguration(InputStream, URI)
And for one line: SimpleConfiguratorUtils#parseBundleInfoLine(String, URI)
This can be useful to investigate Eclipse RCP startup issues.
[Less]
|
Posted
over 3 years
ago
This article is part of a series to help newcomers to get started with Eclipse Theia development by setting up a local docker-based development environment for Theia.
In the previous article, we have created our first Eclipse Theia extension, changed
... [More]
some code, and used the debugger to set and hit a breakpoint in the frontend.
As a next step, I wanted to demonstrate how to debug the backend. So the best way, I thought, was to create a backend service to provide the "Hello World" message instead of having it hard-coded in the frontend.
As described in the Theia Documentation, a Theia Extension can add logic to both the frontend and the backend. To facilitate communication between both components, any protocol could be used; the backend could register and open its own endpoint and the frontend could access it. But, of course, Theia already provides a JSON-RPC API which can be used quite easily.
All of the code below is available in the hello-world branch of my GitHub repository.
Let’s start by specifying a service which can provide our "Hello World“ message. Since it needs to be known by both the backend and the frontend, we put it in hello-world/src/common/hello-world.ts:
export namespace HelloWorldConstants {
export const SERVICE_PATH = '/services/hello-world';
}
export const HelloWorld = Symbol("HelloWorld")
export interface HelloWorld {
getHelloString(): Promise;
}
This code defines an interface for our very simple service, a Symbol for it (which is required by the dependency injection framework), and a constant for the service path at which we want to publish/consume our service. Note that the service returns a Promise instead of a plain string. Since we are dealing with a remote service, using promises makes the code behave better, because we can consume the result asynchronously as we receive it, as we will see below.
The service implementation in the backend goes into hello-world/src/node/hello-world-impl.ts and is as simple as:
@injectable()
export class HelloWorldImpl implements HelloWorld {
getHelloString(): Promise {
return Promise.resolve("Hello from the backend!");
}
}
We need to annotate the class with @injectable() because we want to use it as an injection binding in the backend module later.
Now, that we have the service and its implementation, let’s use it from the CommandContribution in the frontend (I am only showing the changed class HelloWorldCommandContribution):
@injectable()
export class HelloWorldCommandContribution implements CommandContribution {
constructor(
@inject(MessageService) private readonly messageService: MessageService,
@inject(HelloWorld) private readonly helloWorldService: HelloWorld
) { }
registerCommands(registry: CommandRegistry): void {
registry.registerCommand(HelloWorldCommand, {
execute: async () => {
this.helloWorldService.getHelloString().then(helloString => this.messageService.info(helloString))
}
});
}
}
Note that we have added an injection for the HelloWorld service, and in the execute logic, we chain the Promise with the callback logic via the then() function. So, we request the helloString asynchronously, and as soon as it is received (and the Promise is resolved), we call the messageService to show it.
The next step is to tell the dependency injection framework in the frontend how to provide the HelloWorld service we want to inject and use in the HelloWorldCommandContribution. To do this, we extend the existing hello-world-frontend-module.ts as follows:
export default new ContainerModule(bind => {
// add your contribution bindings here
bind(CommandContribution).to(HelloWorldCommandContribution);
bind(MenuContribution).to(HelloWorldMenuContribution);
bind(HelloWorld).toDynamicValue(ctx => {
const connection = ctx.container.get(WebSocketConnectionProvider);
return connection.createProxy(HelloWorldConstants.SERVICE_PATH);
}).inSingletonScope();
});
What we do here is to create a proxy implementation of the HelloWorld interface that is backed by a WebSocketConnectionProvider, which in turn is instructed to handle requests via the SERVICE_PATH path. Every method call on the proxy is encoded in a JSON-RPC request and sent to the backend via the given SERVICE_PATH.
At the backend-side in hello-world/src/node/hello-world-backend-module.ts, we create and register the peer instance:
export default new ContainerModule(bind => {
bind(HelloWorld).to(HelloWorldImpl).inSingletonScope();
bind(ConnectionHandler).toDynamicValue(ctx =>
new JsonRpcConnectionHandler(HelloWorldConstants.SERVICE_PATH, (_client: any) => ctx.container.get(HelloWorld))
).inSingletonScope()
})
First, we bind the HelloWorld service to its actual implementation HelloWorldImpl. This is not strictly required for our use case, but would make sense as soon as HelloWorldImpl wanted to access other services which are provided via injection.
Next, we create the JsonRpcConnectionHandler which is the counterpart of the WebSocketConnectionProvider above. Like in the frontend, we bind the WebSocketConnectionProvider to the SERVICE_PATH. All incoming method invocation requests are then forwarded to a HelloWorldServiceImpl instance. (Note that there is also a _client argument. We don’t use it here, but we could use it to implement a bi-directional protocol in which the client can be called back by the server).
Now the only thing left to do is to register the backend ContainerModule configuration in the package.json file
"theiaExtensions": [
{
"frontend": "lib/browser/hello-world-frontend-module",
"backend": "lib/node/hello-world-backend-module"
}
]
and we are all set. When we launch first the backend, then the frontend in the browser and click on the Say Hello menu item, the new message will appear: Hello from the backend!
Debugging
Backend debugging is easier than frontend debugging described in the previous article, because we don’t need to deal with a browser debugging engine. The VS Code debugger can natively attach to the backend process and the yeoman code generator already took care of creating a launch configuration for us in launch.json. So, we can just place a breakpoint in the getHelloString() method in the HelloWorldImpl class, launch the Launch Backend configuration, and when we click the menu item in the frontend, we see that the breakpoint is hit.
Besides plain breakpoints, VS Code also supports conditional breakpoints, breakpoints with hit counts, and logpoints. The latter are really useful when trying to find out which part of code is called when. Using a logpoint, you can inject an arbitrary log statement that is executed without the debugger suspending the execution.
To try it out, let’s add a logpoint in the node_modules/@theia/core/src/common/messaging/proxy-factory.ts at line 156 in the onRequest method by right-clicking on the line number and selecting Add Logpoint .... As the expression we enter Request: {method}. The expression inside the curly braces is evaluated when the breakpoint is hit.
Now, we can play around with the frontend and can see the requests that are issues to the backend:
Note: At the time of writing this, there is a bug in the VS Code JavaScript debugger that prevents logpoints from working correctly with Theia. This bug is already fixed when installing the vscode-js-debug nightly as described here, and will hopefully be resolved soon in the next VS Code release.
And with this, I close today’s article. Have fun playing around with logpoints.
[Less]
|
Posted
over 3 years
ago
We are happy to announce the Eclipse Theia 1.22 release! This monthly release contains 39 merged pull requests, including a major...
The post Eclipse Theia 1.22 Release: News and Noteworthy appeared first on EclipseSource.
|
Posted
over 3 years
ago
We are happy to announce the Eclipse Theia 1.22 release! This monthly release contains 39 merged pull requests, including a major...
The post Eclipse Theia 1.22 Release: News and Noteworthy appeared first on EclipseSource.
|