<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Gustavo De Souza</title>
    <description>The latest articles on DEV Community by Gustavo De Souza (@gusthavosouza).</description>
    <link>https://dev.to/gusthavosouza</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1151049%2F9ed26f01-c012-469c-b276-0e6169bf2823.jpeg</url>
      <title>DEV Community: Gustavo De Souza</title>
      <link>https://dev.to/gusthavosouza</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gusthavosouza"/>
    <language>en</language>
    <item>
      <title>The thousand dollars one line mistake - SBT + PlayFramework</title>
      <dc:creator>Gustavo De Souza</dc:creator>
      <pubDate>Mon, 01 Jul 2024 11:28:26 +0000</pubDate>
      <link>https://dev.to/gusthavosouza/the-thousand-dollars-one-line-mistake-sbt-playframework-33i9</link>
      <guid>https://dev.to/gusthavosouza/the-thousand-dollars-one-line-mistake-sbt-playframework-33i9</guid>
      <description>&lt;p&gt;Nowadays everyone talks about how important it is to have a good developer experience, as it will have many good side effects, such as but not limited to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Development speed / Productivity&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Code quality / Maintenance&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Saving costs, etc&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, often we get ourselves working on projects that at some time in the past, a small piece of code was added to make the project faster, or even to fix something, maybe someone was trying to make the build faster, or even trying to give the engineers a better development experience. This was the case in this story.&lt;/p&gt;

&lt;p&gt;A few years back, in a project that we worked on ( before I was even part of the company ) an issue with building SBT, Scala and play framework, was identified, where the compilation time for building the project locally was taking around 3 to 5 minutes depending the machine. An attempt to fix the issue was made. The project structure was split in 2 like below:&lt;br&gt;
&lt;strong&gt;Before&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ProjectA
  /api
 /core
 /app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ProjectA
 /core
 /app

ProjectApi
  /api
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The following was added to the build.sbt&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;lazy val projectA = (project in file("."))
  .enablePlugins(...)
  .settings(commonSettings)
  .aggregate(api)
  .dependsOn(api)

lazy val api = project.settings(commonSettings)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By doing so, it did improve the compilation time, only during the build on the CI pipeline, I'm not sure if it helped during the development phase, however, it added a new and horrible bug that made developers waste thousands of hours of work.&lt;/p&gt;

&lt;p&gt;After this line was added, developers started noticing how long it was taking just to run a simple&lt;br&gt;
&lt;code&gt;sbt run&lt;/code&gt; locally, as for every change in the codebase now, a full compilation was needed.&lt;/p&gt;
&lt;h2&gt;
  
  
  The journey to understand the issue
&lt;/h2&gt;

&lt;p&gt;As per documented in &lt;a href="https://www.scala-sbt.org/1.x/docs/Multi-Project.html"&gt;SBT reference manual - Multiproject&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Is important to note the two definitions of Aggregation and depends on&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Aggregation means that running a task on the aggregate project will also run it on the aggregated projects&lt;/p&gt;

&lt;p&gt;A project may depend on code in another project. This is done by adding a dependsOn method call. For example, if core needed util on its classpath.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;After spending one day or two reading documents and many frustrated attempts to fix the issue, I ended up arriving at this &lt;a href="https://github.com/sbt/sbt/issues/35"&gt;Github - Spurious recompilation in multi-project build&lt;/a&gt; This was not the fix itself, however, gave me light by the end of the tunnel to understand the problem was indeed with the multi project setup.&lt;/p&gt;

&lt;p&gt;And further more, I understood what was happening, and by so, now my build.sbt file was just as simple as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;lazy val projectA = (project in file("."))
  .enablePlugins(...)
  .settings(commonSettings)
  .dependsOn(api)

lazy val api = (project in file("api"))
  .settings(commonSettings)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There was a problem with how we set up projectA in SBT. We told SBT to include the project's API (which was right), but the API definition pointed to the entire project root. This meant that:&lt;/p&gt;

&lt;p&gt;Whenever the API needed compiling, SBT would also try to compile projectA itself.&lt;br&gt;
Since projectA needed the API to compile, it would trigger another API compilation.&lt;br&gt;
This created an endless loop, forcing developers to kill SBT and manually clean and compile everything for every code change.&lt;br&gt;
Here's what happened in simpler terms:&lt;/p&gt;

&lt;p&gt;We told SBT to include the project's API.&lt;br&gt;
The API definition pointed to the whole project.&lt;br&gt;
Compiling the API triggered a full project compilation (including the API again).&lt;br&gt;
This loop made SBT very slow and frustrating for developers.&lt;/p&gt;

&lt;p&gt;The team had worked with this problem for at least 4 years...&lt;/p&gt;

&lt;h2&gt;
  
  
  Aftermath - fixing the issue
&lt;/h2&gt;

&lt;p&gt;After I said to my teammates that I had a surprise feature already merged on master, people did not understand what was happening, however, I wanted to see the happiness on their faces, I told the whole team to pull master into any branch that they were working on, some of them did not notice anything in the first try, other started to notice that after changing any code in the codebase, it was compiling only the affected file in a matter of seconds, not minutes as before. And the best surprise was when one of the teammates noticed and said out of loud in the office.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Gust ... did you fix the compilation loop issue? I'm working in something here and I am getting instant feedback for any changes in the code.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;At that time I had to admit and, share the news with all the other engineers, it made me a happier engineer as now I am happy working on this project and not waiting long period of times for a full compilation on our project.&lt;/p&gt;

&lt;p&gt;If you feel that something is our way, whenever you are, whatever you are doing, remember you have the chance to make it better, never forget what you have started.&lt;/p&gt;

&lt;p&gt;If you like reading this article or would like it to have more content, please let me know in the comments, I am happy to share more about this journey.&lt;/p&gt;

&lt;p&gt;Thank you for reading.&lt;/p&gt;

&lt;p&gt;A few stats from the project:&lt;/p&gt;

&lt;p&gt;Project start:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Around 4 thousand Java files&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Around 300 Twirl templates&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Compile time before improvements 3 to 5 minutes for any change in the code&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Compile time after improvements average of 1 minute and 20 seconds for full compile&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Compile time after improvements average of 5 to 10 seconds for any change with instant feedback ( the most time spent is Playframework restarting the HTTP Server )&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cover image made by AI.&lt;/p&gt;

</description>
      <category>sbt</category>
      <category>playframework</category>
      <category>java</category>
      <category>devrel</category>
    </item>
    <item>
      <title>Building Java Swagger 3 Intellij plugin: Boosting productivity, type safe generation and documentation adoption.</title>
      <dc:creator>Gustavo De Souza</dc:creator>
      <pubDate>Tue, 14 May 2024 14:26:08 +0000</pubDate>
      <link>https://dev.to/gusthavosouza/building-java-swagger-3-intellij-plugin-boosting-productivity-type-safe-generation-and-documentation-adoption-18k7</link>
      <guid>https://dev.to/gusthavosouza/building-java-swagger-3-intellij-plugin-boosting-productivity-type-safe-generation-and-documentation-adoption-18k7</guid>
      <description>&lt;p&gt;Over the past couple of years, I’ve been part of a dynamic team of 12 engineers. Wrangling all our API Dtos, models, and TypeScript objects to stay in harmony has been quite the adventure! Whenever we need to tweak a DTO, it’s like embarking on a treasure hunt: “Where does this ripple effect lead? Will adding a new field here trigger a cascade of chaos elsewhere?”&lt;/p&gt;

&lt;h2&gt;
  
  
  Issue #1: Syncing Struggles
&lt;/h2&gt;

&lt;p&gt;The other biggest issue, is that for each and every DTO on our backend, we need the same TS type for the frontend, and this was often seen as a productivity drainer, as this was leading to duplicated code within the backend and frontend, many bugs due to some changes in the backend not reflecting the types in the frontend and so on.&lt;/p&gt;

&lt;h2&gt;
  
  
  The pluggin
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxzourxt15iu6nrep0abw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxzourxt15iu6nrep0abw.png" alt="Java Swagger 3 Intellij Plugin"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Intellij Swagger 3 Java plugin by Gustavo de Souza&lt;br&gt;
For these reasons and many more. I have adopted Swagger 3 in our project, in fact the frontend team has been really happy getting all types auto generated out of the box with Swagger 3 and OpenAPI specs, however, they were not satisfied with documenting all the current endpoints that they already use and migrating them, for this reason I have build the Java Swagger 3 Generator that added support to a few actions and some “magic” tricks behind the scenes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxtainy9kr1nhs33kxusg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxtainy9kr1nhs33kxusg.png" alt="Java Swagger 3 Intellij Plugin"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Swagger Generator Actions Intellij by Gustavo de Souza&lt;br&gt;
If you’re diving deep into Swagger 3 territory and craving a shortcut to endpoint enlightenment, behold the plugin! Here’s a taste of its powers:&lt;/p&gt;

&lt;h2&gt;
  
  
  Calling All Swagger Fans!
&lt;/h2&gt;

&lt;p&gt;If you feel that you heavily use Swagger 3 to your projects and are trying to find something that will boost documenting endpoints, I would suggest giving a try to the plugin.&lt;/p&gt;

&lt;p&gt;And the most important one is SwaggerGenerate that will auto add Swagger annotations to Models, Dtos, Controllers …&lt;/p&gt;

&lt;p&gt;This action will run a few checks in the current class and define which one it could be e.g&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Controllers&lt;br&gt;
Will add @Tag annotations and map all methods that have any Spring REST annotations and/or Jax-RS annotations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Models / DTO’s&lt;br&gt;
Will add @Schema annotation for any field, and mark them as required or not based on type, validations, and other constraints, fully supporting javax.validation.* or jakarta.validation.*&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The fact that just by creating something simple, that can help you, your team, and even make the engineers a bit more happy, is satisfying and has a nice feeling. Sometimes we tend to focus on solving only our daily tickets, or building things that were planned in the previous spring, however, many times we can step out a bit, and look things from a different perspective, and in fact create something that will benefit everyone around you.&lt;/p&gt;

&lt;p&gt;Sometimes, being a better engineer is as simple as lending a hand to your fellow engineers. Forget the daily grind; let’s sprinkle a little happiness dust on our projects! By thinking outside the code, we can craft solutions that make everyone’s day a little brighter.&lt;/p&gt;

&lt;p&gt;Source code on Github :)&lt;/p&gt;

&lt;p&gt;— — — — —&lt;/p&gt;

&lt;p&gt;So, if you dug this article and crave more tech tales, dive deeper into the world of Swagger and watch the magic unfold! &lt;/p&gt;

</description>
      <category>swagger</category>
      <category>intellij</category>
      <category>java</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
