<?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: 7ouki&amp;7rairi</title>
    <description>The latest articles on DEV Community by 7ouki&amp;7rairi (@7oukiw7rairi).</description>
    <link>https://dev.to/7oukiw7rairi</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%2F1897395%2Fa6279061-6871-4c41-80c9-196009250f2e.png</url>
      <title>DEV Community: 7ouki&amp;7rairi</title>
      <link>https://dev.to/7oukiw7rairi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/7oukiw7rairi"/>
    <language>en</language>
    <item>
      <title>Why i created a lightweight mini spring alternative and how I did it</title>
      <dc:creator>7ouki&amp;7rairi</dc:creator>
      <pubDate>Tue, 13 Aug 2024 17:25:17 +0000</pubDate>
      <link>https://dev.to/7oukiw7rairi/why-i-created-a-lightweight-mini-spring-alternative-and-how-i-did-it-1a93</link>
      <guid>https://dev.to/7oukiw7rairi/why-i-created-a-lightweight-mini-spring-alternative-and-how-i-did-it-1a93</guid>
      <description>&lt;p&gt;In this small article I will try to explain why I created this library ? and how it's implemented ?&lt;/p&gt;

&lt;h2&gt;
  
  
  why I created this library ?
&lt;/h2&gt;

&lt;p&gt;I worked with Java EE framework on many project and in most of them there was no limitation on the available resources to run the application but in some rare cases we had a limited resources especially the memory to deploy the application on a deployment service, so when the application exceed the limit the deployment service will slow down the application at first then if it continue the service will shut it down. We were using legacy spring framework without even spring boot, we tried to use different library but the difference was minimal and worthless, and this is where the idea ,to create a lightweight spring alternative focusing on reducing the memory consumption as much as possible, started.&lt;/p&gt;

&lt;p&gt;there was only two goals in my mind when i started designing the library :&lt;br&gt;
1 - reducing the Memory consumption as much as possible&lt;br&gt;
2 - try to use existing Java EE API as much as possible to make the transition to the library easy from learning point of view and from the complexity of the transition in itself.&lt;br&gt;
and with these 2 goals I managed to reduce the memory footprint of one of my application around 40% and make the transition easy and fast since it's similar to the existing solutions.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I created this library ?
&lt;/h2&gt;

&lt;p&gt;Here's &lt;a href="https://github.com/7oukiW7rairi/lazy-project" rel="noopener noreferrer"&gt;GitHub repository&lt;/a&gt; so you can check the code while reading.&lt;/p&gt;

&lt;p&gt;The library as a whole has many parts (screenshot below), most of the implementation in the main module which is also divided in three kind of independent modules : Core, JPA, Web. The App modules is mainly for integration, the Plugin module is a maven plugin to help create the necessary files inside the package archive for the library to work properly&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3uy2v5rpkdks4pbwkg3k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3uy2v5rpkdks4pbwkg3k.png" alt="Library structure" width="550" height="962"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Core Module
&lt;/h2&gt;

&lt;p&gt;So we will start with the core module which as the name suggest contains the core functionality of the library which is the dependency injection or the inversion of control. &lt;br&gt;
In order to achieve this fonctionality, first it start by scanning the class path of the application during the compile phase for  all the annotated class the library should manage to create a component definitions for annotated classes. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F717kqj3tls00g1llc8ue.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F717kqj3tls00g1llc8ue.png" alt="List of annotation to scan" width="800" height="354"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjc2h14no5ack48gsecem.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjc2h14no5ack48gsecem.png" alt="Annotation processeur" width="800" height="448"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The component definition contain basically all the information that we will need to instantiate an object from this class later, like the constructor information, if there are some setters with inject annotation (only constructor and setter injection are supported) if the class has some interface or extend some other class, we will have all the information that we need to create an object from this class (screenshot below).&lt;br&gt;
And then, after we scan all the class path annotation and we create all the component definition that we need we will store them in the class path as JSON file.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8eam1gkb5iv2sz3dcjjv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8eam1gkb5iv2sz3dcjjv.png" alt="Component definition structure example" width="800" height="528"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The second and main functionality of the core module is the dependency injection and inversion of control which based on factory design pattern, so we have &lt;strong&gt;ApplicationContext&lt;/strong&gt; interface which in it self extend the &lt;strong&gt;ComponentFactory&lt;/strong&gt; interface and the main method of this interface is &lt;strong&gt;getComponent&lt;/strong&gt; method which will return the object from the name of the component.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnprcib5d57pekovktfez.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnprcib5d57pekovktfez.png" alt="ApplicationContext getComponent method implementation" width="800" height="520"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see in the screenshot above first, we try to check if the component exist in the already initialised Singleton components, if it's not then we start by getting the component definition from the JSON file then we start the while loop to get all the dependencies of the component before passing the component definition and its dependencies to the component assembler to get a full object ready to be injected.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffwuu3ipukm0ouunwcpcd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffwuu3ipukm0ouunwcpcd.png" alt="Component assembler implentation" width="800" height="520"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  JPA module
&lt;/h2&gt;

&lt;p&gt;The implementation of JPA module is very similar to spring data JPA but very minimal, the reason it's very similar because I used spring data in many project and I found it easy to use and as I said before I wanted the transition to the library to be smooth and require less work as much as possible so implementing my own mini spring data version was the best choice. &lt;/p&gt;

&lt;p&gt;The implementation is around the JpaRepository interface which contain most common operation for database like save, delete and findAll... and in order to use the JPA module you need to extend this interface and provide the entity that this interface should manage and it's id, then after you extending the interface and annotate with Repository annotation you can define your methods and annotate them with Query annotation and provide the JPQL query, and then the library at the compile phase will create a fully functional class that implement this interface.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsrooaerk9y28sj2h618a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsrooaerk9y28sj2h618a.png" alt="JpaRepository interface" width="800" height="694"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv148scirck3k2bnv9dms.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv148scirck3k2bnv9dms.png" alt="Example of JpaRepository" width="800" height="477"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl5769hw6z0lqq5b0dmyo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl5769hw6z0lqq5b0dmyo.png" alt="the generated class of ExampleRepository" width="800" height="338"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The library will also manage the transactional part of the application, so all repository interface and any class annotated with transactional will be managed by the library from transaction point of view. so for any transactional component the library will create proxy to manage the transaction based on the &lt;strong&gt;Transactional&lt;/strong&gt; annotation and will also manage the entity manager life-cycle.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftqocprcialncv70vjyev.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftqocprcialncv70vjyev.png" alt="Asemble component nd create proxy" width="800" height="561"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm67y8fg215ahuljeykhg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm67y8fg215ahuljeykhg.png" alt="Jpa Transaction manager" width="800" height="742"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Web module
&lt;/h2&gt;

&lt;p&gt;The web model is responsible for managing all the web part of the application and by design it's an independent module which mean it can be used independently from the rest of the modules in the library, as usual it's very similar in usage to some familiar Java EE library like Spring web or Jax-rs.&lt;/p&gt;

&lt;p&gt;The implementation is based on annotation, you have classes annotated with &lt;strong&gt;Controller&lt;/strong&gt; annotation and inside this controller you will find method annotated with the &lt;strong&gt;PathMapping&lt;/strong&gt; and these methods will handle specific path or specific request based on some criteria like the type of the request, the content type... &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3kn0sfiuhvfhf7prdcp0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3kn0sfiuhvfhf7prdcp0.png" alt="Example controller" width="800" height="557"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0b0f89hfs6gfy7nq3o3k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0b0f89hfs6gfy7nq3o3k.png" alt="more Controller example" width="800" height="429"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From the outside it will look very similar to the other library but from the inside it's a different because the library will change these &lt;strong&gt;Controller&lt;/strong&gt; classes at run time to make all of them extend the &lt;strong&gt;BaseHttpServlet&lt;/strong&gt;, which also extends the &lt;strong&gt;HttpServlet&lt;/strong&gt; and they will work as a regular servlet.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs5n2ua7qkmrpn9b9dzpl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs5n2ua7qkmrpn9b9dzpl.png" alt="BaseHttpServlet handleRequest" width="800" height="472"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see in the screenshot above, first we initialize the component in the &lt;strong&gt;init&lt;/strong&gt; method to inject all the dependency using the &lt;strong&gt;WebApplicationContext&lt;/strong&gt;,  and then we will handle all the request coming to this Controller using the &lt;strong&gt;handleRequest&lt;/strong&gt; method, with this approach we will use the existing servlet api to manage the controllers, this will help keep the memory footprint low and also reduce the overhead since the library act as a plugin to complement the servlet API work.&lt;/p&gt;

&lt;p&gt;First, we try to map the request to the right method and after that, we try to inject all the requested information inside the method by getting the information either from the context or the &lt;strong&gt;HttpServletRequest&lt;/strong&gt; like the request parameter or headers or path variable or the body of the request...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz5w4mpui34mk71r8dhl1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz5w4mpui34mk71r8dhl1.png" alt="PathParamHandler" width="800" height="463"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs0cx663792zi1exzdg1g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs0cx663792zi1exzdg1g.png" alt="Image description" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We convert all of these informations and then inject them as a parameter to the method when it's requested and then we execute the method and convert the outcome or the result based on &lt;strong&gt;PathMapping&lt;/strong&gt; produces or content type (by default it's application/Json) and then we write the content to the &lt;strong&gt;HttpServletResponse&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Last if something goes wrong in the process and an error got thrown, we catch this error or the exception and we try to handle it based on the type of the exception, we have exception handler to handle different type of exception and the user can also provide more handler to handle any exception the way he want.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftowjfzta896m1pbaxk71.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftowjfzta896m1pbaxk71.png" alt="Exception handling in BaseHttpServlet" width="800" height="513"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9mp6gb6tt0njybtn2on1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9mp6gb6tt0njybtn2on1.png" alt="ExceptionHandlerFactory" width="800" height="513"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Maven plugin
&lt;/h2&gt;

&lt;p&gt;The last and important part is the maven plugin that will create all the necessary files for the application to work properly and also to build the jar or war package.&lt;br&gt;
First the plugin will scan the class path and the dependencies to search &lt;strong&gt;component-definitions-json&lt;/strong&gt; files, from this files it will generate:&lt;br&gt;
&lt;strong&gt;lazy-application.json&lt;/strong&gt;: contains all the component and their dependencies for the application&lt;br&gt;&lt;br&gt;
&lt;strong&gt;lazy-application.properties&lt;/strong&gt;: contains the list of controllers and entities so we don't need to scan the class path at run time.&lt;br&gt;
and last if the packaging is jar we will get the main class.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fng0f09lmdjedt37n0slf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fng0f09lmdjedt37n0slf.png" alt="Generate dependencies file" width="800" height="507"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnt91yn6rrw8nygi0tndx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnt91yn6rrw8nygi0tndx.png" alt="generate properties file" width="800" height="423"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and last we build the package archive file that will contains application code with its dependencies and the files we generated in the step before. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fboyrtcl7biw1pxibd9u4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fboyrtcl7biw1pxibd9u4.png" alt="Build Jar archive" width="800" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxxhsho5o8kl5xggt0h5o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxxhsho5o8kl5xggt0h5o.png" alt="Build war archive" width="800" height="623"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I tried not to dive in details to keep the articles short and not so complicated to understand, of course the code is available on &lt;a href="https://github.com/7oukiW7rairi/lazy-project" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; so you can play with it as well.If you have question drop them below and I will try to answer them.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>java</category>
      <category>softwaredevelopment</category>
    </item>
  </channel>
</rss>
