<?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: Fırat Küçük</title>
    <description>The latest articles on DEV Community by Fırat Küçük (@fk).</description>
    <link>https://dev.to/fk</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%2F101694%2F2f42a191-aa63-4573-ab26-2150e40834b6.jpg</url>
      <title>DEV Community: Fırat Küçük</title>
      <link>https://dev.to/fk</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/fk"/>
    <language>en</language>
    <item>
      <title>Be Strict in Software Development</title>
      <dc:creator>Fırat Küçük</dc:creator>
      <pubDate>Mon, 04 Dec 2023 11:09:53 +0000</pubDate>
      <link>https://dev.to/fk/be-strict-in-software-development-21c6</link>
      <guid>https://dev.to/fk/be-strict-in-software-development-21c6</guid>
      <description>&lt;h2&gt;
  
  
  BE STRICT
&lt;/h2&gt;

&lt;p&gt;“Being strict” might not hold true in all areas of life: "Bend, so you don't break." However, I am going to talk about software development. Besides watching cat videos, it's kind of my only hobby.&lt;/p&gt;

&lt;p&gt;Yes, “be strict” in software development. Draw lines, restrict users, restrict yourself. Until AI writes software for us, we need to be strict. Human nature is error-prone, and we tend to forget. Standards and metrics make us better engineers.&lt;/p&gt;

&lt;p&gt;Also, our software quality fluctuates between mood swings. If you're not well-caffeinated or it's Monday morning, you might not be proud of your craftsmanship. I could list many bullet points, but let's stick to the 7 deadly sins of software development. Well, not deadly, but let's keep them in mind.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Constraints on Persistence Layer
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--A5vu8Y_F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zthmhwmhjbr1khzm7jdr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--A5vu8Y_F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zthmhwmhjbr1khzm7jdr.png" alt="Constraints on Persistence Layer" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Your data is one of the most valuable parts of your software system. Imagine a user ordering -3 smartphones on your online webshop. You'd probably need to give those phones for free. Or imagine a user uploading a 1GB profile image.&lt;/p&gt;

&lt;p&gt;Our persistence layer, in other words, our database, data warehouse, data lake, or whatever you call it, should be clean and consistent.&lt;/p&gt;

&lt;p&gt;In some companies I've worked with, I've witnessed engineers intentionally avoiding the use of database constraints or foreign key relations because they might slow down write operations. Theoretically, that might be true, but the cost of inconsistent data could be much bigger, and the consequences might be really painful.&lt;/p&gt;

&lt;p&gt;Another trend is "schema-less" NoSQL databases. In the real world, nothing is schema-less. You don't want to put your products in your user collection (table). In most cases, everything is well-defined. The only difference is that if you add some additional fields (columns), your database won't complain about it.&lt;/p&gt;

&lt;p&gt;I can say they are mostly schema-flex (yes, I made it up) databases. Most of the time, schemas are our best friends—XML schema definitions, JSON schemas, or database schemas. Being strict about your data will reward you.&lt;/p&gt;

&lt;p&gt;To sum up, be a good developer and use schemas, constraints, and relations if possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Data Validation
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vYP8smJD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wwms6yqcklsonsvrrs8g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vYP8smJD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wwms6yqcklsonsvrrs8g.png" alt="Data Validation" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The internet is not a safe place from the very beginning of your website's life journey. People will try to enter the most ridiculous inputs you can ever imagine. Some users will do this on purpose, and for some, they were born like that. They will try to put emojis as usernames because who doesn't love unicorns, or they will try some JavaScript inside a textarea because JavaScript is their favorite programming language.&lt;/p&gt;

&lt;p&gt;No matter what the intention is, the solution is restricting user input; otherwise, it might cause serious problems in your system. The most crucial part is backend validation because it directly affects your system. This input can be a form, REST API, GraphQL, or any other kind of protocol data. Also, data can come from the outside world, inside your company, or from another microservice.&lt;/p&gt;

&lt;p&gt;Winter is coming. Prepare your backend. For better UI/UX, use frontend validation as well. Imagine you're filling out 5 pages of a form, and you realize you made some mistakes after sending the data to the server. Surprise! Form data is also lost. It is understandable that sometimes people want to beat up developers.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Separated Layers
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--L_DlGWpI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/og87pk0wsdhha4yqpdpd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--L_DlGWpI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/og87pk0wsdhha4yqpdpd.png" alt="Separated Layers" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;While developing, we have some logical boundaries. They can result from Domain Driven Design or a software architecture you have followed. If your code is inside a single file with 6000 lines, it might not be a good indicator.&lt;/p&gt;

&lt;p&gt;Separating your business logic and transactional part might be a wise decision. I assume I first saw it in a Quarkus project. It allows you to create some architectural layer communication tests. For example, when we call the repository method directly from the controller layer, these layer tests will fail.&lt;/p&gt;

&lt;p&gt;Modern IDEs have powerful tools for checking coupling and cohesion between packages, layers, and namespaces. Also, some automated plugins check that kind of layer testing.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Security Hardening
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---LY3X9WW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/en28zshycf676e94o74y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---LY3X9WW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/en28zshycf676e94o74y.png" alt="Security Hardening" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Most of us have some insecurities, but that doesn't mean we aren't going to help poor apps rise and shine. Probably, this one should be a whole separate article. But I can mention some of the security issues here.&lt;/p&gt;

&lt;p&gt;Forcing users to choose strong passwords is the first step that should be taken. If your system stores passwords in plain text, please don't. Also, we may want to use one of the modern hashing algorithms like SHA512, SHA3, and a teaspoon of "salt" against dictionary attacks.&lt;/p&gt;

&lt;p&gt;Taking action against code injection might be another important step. Modern frontend libraries encode HTML, and some ORMs prevent SQL injection by default.&lt;/p&gt;

&lt;p&gt;Enabling CORS, using CSRF tokens, using strict HTTP headers (CSPs), a TLS layer, constant dependency scans, and automated vulnerability scans can be some of the important ones.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Code Quality Check
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_G8Ju1rw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v9x194zoo8ka9w6zycgp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_G8Ju1rw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v9x194zoo8ka9w6zycgp.png" alt="Code Quality Check" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Code quality check starts with a good code style. Using a code formatter and format checker can be a first step; a linter might also help against some redundant or faulty usages. Like using "var" instead of "const/let" in JavaScript or an unused import statement in Java.&lt;/p&gt;

&lt;p&gt;Some plugins or helper services might help you check your code status. I use such tools for limiting the line count of methods and classes and restricting the cyclomatic complexity of a method or a class.&lt;/p&gt;

&lt;p&gt;Some other tools might prevent you from shooting yourself in the leg. They can detect well-known anti-patterns and faulty usages. Also, we can put testing itself into this category: unit, integration, smoke, end-to-end API/UI tests. Code and path coverage also might be good indicators of the status of your application.&lt;/p&gt;

&lt;p&gt;Some frameworks also provide strict modes for better usage checking and best practices. Using those kinds of options might help you improve code quality.&lt;/p&gt;

&lt;p&gt;Better to put those checks in a pipeline or a git commit hook; it might help us keep our code base clean.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Cross-cutting Concerns
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2lkwVBir--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5eb98rqy4oibapc3l36m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2lkwVBir--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5eb98rqy4oibapc3l36m.png" alt="Cross-cutting Concerns" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's assume we aim to persist a simple User entity in the database. In ideal conditions or a scenario, every user can provide perfect inputs. That code could be a couple of lines. However, we need to pay attention to input validation, database transactions, auditing, timeout management, database connection pooling, retry mechanism, exception handling, anti-corruption layer, and so on.&lt;/p&gt;

&lt;p&gt;Programming becomes a cumbersome task if you're dealing with lots of boilerplate code. It could be 3 lines of code or a thousand lines of code if you're dealing with that kind of thing in your actual code. Using modern frameworks might help with that one. Or some kind of interceptors, middlewares, or aspect-oriented programming.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Statically-typed Language
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kZ6o1Tcq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9yz2sbac3vflg6h1yzit.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kZ6o1Tcq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9yz2sbac3vflg6h1yzit.png" alt="Statically-typed Language" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I don't want to start a flame. This might be a sensitive topic if you're emotionally attached to your programming language. Most modern languages use better practices compared to their predecessors. Statically typed languages help us see our coding errors beforehand or provide us with better IDE or editor code-complete support. They might offer us to compensate for the billion-dollar mistake "Null" data type. Modern languages provide syntactic sugars for optional data management. Also, by default, immutable data types are a really good way to handle data.&lt;/p&gt;

&lt;p&gt;If you're using JavaScript, TypeScript might be a good alternative (and avoiding the "any" type). Kotlin can be an alternative to Java. For Python developers, Python already offers static typing in version 3. Using that one might be a wise choice.&lt;/p&gt;

</description>
      <category>softwaredevelopment</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Lilo the stitching library for GraphQL</title>
      <dc:creator>Fırat Küçük</dc:creator>
      <pubDate>Sun, 18 Sep 2022 11:01:58 +0000</pubDate>
      <link>https://dev.to/fk/lilo-the-stitching-library-for-graphql-3kk0</link>
      <guid>https://dev.to/fk/lilo-the-stitching-library-for-graphql-3kk0</guid>
      <description>&lt;p&gt;The story is a well-known Not Invented Here syndrome among developers. Let me summarize from the beginning. Reverse proxies are good especially if you are using REST API, Even if you have multiple microservices behind the proxy. You can efficiently serve all your REST API via using an API Gateway. You can even make some transformation magic, authorization, aggregation, and plenty of other custom flavors. The sky is the limit.&lt;/p&gt;

&lt;p&gt;But when it comes to GraphQL, it's not that easy. Especially if you want to transform a legacy code base without changing thousands of lines in frontend. You have 2 options one of them is GraphQL Federation which is a good practice to go with it. But it combines the methods in namespaces, so you might need some refactoring on frontend as well. The second option is GraphQL stitching.&lt;/p&gt;

&lt;p&gt;I chose the stitching option. Then I stuck with Atlassian Braid which is a really handy tool TBH. But it seems deprecated and has not been touched for a while. Especially issues sections, there are plenty of bugs reported or questions from 3 years back. I was also trying to use Atlassian Braid on Spring Cloud Gateway. It was really good at the beginning till we deployed it on production. Because of the complex reactive streams logic on the Gateway. It causes lots of thread starvation or unresponsiveness. That eventually triggered me to implement a new one.&lt;/p&gt;

&lt;p&gt;Like most of the developers, my estimation was wrong. I've estimated it as a weekend project then it turns out a complete level. then I ended up with &lt;a href="https://github.com/friatech/lilo/" rel="noopener noreferrer"&gt;Lilo Stitching library&lt;/a&gt; and here we are.&lt;/p&gt;

&lt;h2&gt;
  
  
  How GraphQL Stitching works
&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%2F8t6l6u9u7m7zntuery6l.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%2F8t6l6u9u7m7zntuery6l.png" alt="How GraphQL Stitching works"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When the Stitching library starts, it fetches the schema from the target schema sources, They might be a remote schema source or an internal source as well. After that, it maps all the GraphQL mutations and queries with respective sources.&lt;/p&gt;

&lt;p&gt;For every incoming request, it analyzes the query and redirects the requests to respective schema sources after that it combines all the results and returns an aggregated result as a GraphQL response.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example usage
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Installation
&lt;/h3&gt;

&lt;p&gt;Required dependency should be added to your project if you're using &lt;code&gt;maven&lt;/code&gt; then you can add it into your &lt;code&gt;pom.xml&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;dependencies&amp;gt;&lt;/span&gt;
  ...
  &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;io.fria&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;lilo&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;23.11.1&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
  ...
&lt;span class="nt"&gt;&amp;lt;/dependencies&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you're using &lt;code&gt;gradle&lt;/code&gt; then you can add the dependency in your &lt;code&gt;build.gradle&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;implementation&lt;/span&gt; &lt;span class="s1"&gt;'io.fria:lilo:23.11.1'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Creating the source applications
&lt;/h3&gt;

&lt;p&gt;You can use lilo with various libraries and web frameworks but I'll try to show a basic usage with spring boot. We need to create two different service projects for exhibiting lilo's skills. Thanks to GraphQL spring project we have now the ability to create GraphQL controller via using annotations just like the REST API.&lt;/p&gt;

&lt;p&gt;Controller for Service Application1:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Controller&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GreetingController&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

  &lt;span class="nd"&gt;@QueryMapping&lt;/span&gt;
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nd"&gt;@NonNull&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;greeting1&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Hello world"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we are going to create a similar controller for our second application:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Controller&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GreetingController&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

  &lt;span class="nd"&gt;@QueryMapping&lt;/span&gt;
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nd"&gt;@NonNull&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;greeting2&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Hello world"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We also need to add GraphQL schema definition into &lt;code&gt;resources/graphql&lt;/code&gt; directory. For Application1:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;greeting1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;same for the application 2:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;greeting2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The package hierarchy should be something like this for both applications:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;├── pom.xml
└── src
    └── main
        ├── java
        │   └── com
        │       └── example
        │           └── stitching_sample
        │               └── server1
        │                   ├── BssServer1Application.java
        │                   └── GreetingController.java
        │                       
        └── resources
            ├── application.properties
            └── graphql
                └── schema.graphqls
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It might be wise to assign different port numbers in your &lt;code&gt;application.properties&lt;/code&gt; or &lt;code&gt;application.yml&lt;/code&gt; using &lt;code&gt;server.port&lt;/code&gt;. We will be using &lt;code&gt;8081&lt;/code&gt; for application 1 and &lt;code&gt;8082&lt;/code&gt; for application 2.&lt;/p&gt;

&lt;h1&gt;
  
  
  Creating the gateway
&lt;/h1&gt;

&lt;p&gt;We will be using lilo inside a GraphQL REST controller but you can use it via a filter or you can use it with different web frameworks as well.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Controller&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LiloController&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="no"&gt;SERVER1_NAME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"SERVER1"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="no"&gt;SERVER1_BASE_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"http://localhost:8081"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="no"&gt;SERVER2_NAME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"SERVER2"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="no"&gt;SERVER2_BASE_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"http://localhost:8082"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Lilo&lt;/span&gt; &lt;span class="n"&gt;lilo&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;LiloController&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;lilo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
        &lt;span class="nc"&gt;Lilo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addSource&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
                &lt;span class="nc"&gt;RemoteSchemaSource&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;create&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
                    &lt;span class="no"&gt;SERVER1_NAME&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
                    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;IntrospectionRetrieverImpl&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;SERVER1_BASE_URL&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
                    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;QueryRetrieverImpl&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;SERVER1_BASE_URL&lt;/span&gt;&lt;span class="o"&gt;)))&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addSource&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
                &lt;span class="nc"&gt;RemoteSchemaSource&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;create&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
                    &lt;span class="no"&gt;SERVER2_NAME&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
                    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;IntrospectionRetrieverImpl&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;SERVER2_BASE_URL&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
                    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;QueryRetrieverImpl&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;SERVER2_BASE_URL&lt;/span&gt;&lt;span class="o"&gt;)))&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="nd"&gt;@ResponseBody&lt;/span&gt;
  &lt;span class="nd"&gt;@PostMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/graphql"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nd"&gt;@NonNull&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;stitch&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@RequestBody&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nd"&gt;@NonNull&lt;/span&gt; &lt;span class="nc"&gt;GraphQLRequest&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;lilo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stitch&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toExecutionInput&lt;/span&gt;&lt;span class="o"&gt;()).&lt;/span&gt;&lt;span class="na"&gt;toSpecification&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the controller starts, it will create a combined GraphQL schema using the remote sources and it will execute incoming requests using lilo.&lt;/p&gt;

&lt;p&gt;We also need additional Retriever definitions. Those classes retrieve the schema or query results. &lt;code&gt;IntrospectionRetriever&lt;/code&gt; retrieves the remote schema and &lt;code&gt;QueryRetriever&lt;/code&gt; is used for every single request for communicating and executing a single query or a mutation on the remote site.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;IntrospectionRetrieverImpl&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;SyncIntrospectionRetriever&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;schemaUrl&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;RestTemplate&lt;/span&gt; &lt;span class="n"&gt;restTemplate&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="nc"&gt;IntrospectionRetrieverImpl&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nd"&gt;@NonNull&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;schemaUrl&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;schemaUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;schemaUrl&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"/graphql"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;restTemplate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
        &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;RestTemplateBuilder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;defaultHeader&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;HttpHeaders&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;CONTENT_TYPE&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;MediaType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;APPLICATION_JSON_VALUE&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="nd"&gt;@Override&lt;/span&gt;
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nd"&gt;@NonNull&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
      &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nd"&gt;@NonNull&lt;/span&gt; &lt;span class="nc"&gt;LiloContext&lt;/span&gt; &lt;span class="n"&gt;liloContext&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
      &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nd"&gt;@NonNull&lt;/span&gt; &lt;span class="nc"&gt;SchemaSource&lt;/span&gt; &lt;span class="n"&gt;schemaSource&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
      &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nd"&gt;@NonNull&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
      &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nd"&gt;@Nullable&lt;/span&gt; &lt;span class="nc"&gt;Object&lt;/span&gt; &lt;span class="n"&gt;localContext&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;Objects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;requireNonNull&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;restTemplate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;postForObject&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;schemaUrl&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and we also need to define our &lt;code&gt;QueryRetriever&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;QueryRetrieverImpl&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;SyncQueryRetriever&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;schemaUrl&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;RestTemplate&lt;/span&gt; &lt;span class="n"&gt;restTemplate&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="nc"&gt;QueryRetrieverImpl&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nd"&gt;@NonNull&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;schemaUrl&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;schemaUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;schemaUrl&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"/graphql"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;restTemplate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
        &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;RestTemplateBuilder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;//&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;defaultHeader&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;HttpHeaders&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;CONTENT_TYPE&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;MediaType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;APPLICATION_JSON_VALUE&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;//&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;//&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="nd"&gt;@Override&lt;/span&gt;
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nd"&gt;@NonNull&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
      &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nd"&gt;@NonNull&lt;/span&gt; &lt;span class="nc"&gt;LiloContext&lt;/span&gt; &lt;span class="n"&gt;liloContext&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
      &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nd"&gt;@NonNull&lt;/span&gt; &lt;span class="nc"&gt;SchemaSource&lt;/span&gt; &lt;span class="n"&gt;schemaSource&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
      &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nd"&gt;@NonNull&lt;/span&gt; &lt;span class="nc"&gt;GraphQLQuery&lt;/span&gt; &lt;span class="n"&gt;graphQLQuery&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
      &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nd"&gt;@Nullable&lt;/span&gt; &lt;span class="nc"&gt;Object&lt;/span&gt; &lt;span class="n"&gt;localContext&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;Objects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;requireNonNull&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;restTemplate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;postForObject&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;schemaUrl&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;graphQLQuery&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getQuery&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;now we are ready we can run all 3 applications and see the results.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'content-type: application/json'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"query":"{\ngreeting1\ngreeting2\n}","variables":null}'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    http://localhost:8080/graphql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;greeting1 will be executed on application1 and greeting2 will be executed on application2 we will get the results in a combined GraphQL response.&lt;/p&gt;

&lt;p&gt;You can take a look at the sample implementation code on the official Lilo repo. &lt;a href="https://github.com/friatech/lilo/tree/main/samples/lilo/02-spring-boot-basic-stitching" rel="noopener noreferrer"&gt;Check out the sample&lt;/a&gt;&lt;/p&gt;

</description>
      <category>java</category>
      <category>graphql</category>
      <category>stitching</category>
    </item>
    <item>
      <title>Creating GitHub Action to Deploy Projects into a Private Maven Repository</title>
      <dc:creator>Fırat Küçük</dc:creator>
      <pubDate>Wed, 01 Jul 2020 22:32:55 +0000</pubDate>
      <link>https://dev.to/fk/creating-github-action-to-deploy-projects-into-a-private-maven-repository-2jf0</link>
      <guid>https://dev.to/fk/creating-github-action-to-deploy-projects-into-a-private-maven-repository-2jf0</guid>
      <description>&lt;p&gt;I have been heavily using other CI/CD platforms like GitLab, BitBucket, Jenkins, and Azure DevOps but I can definitely say GitHub nailed it. It has a different and easy-to-use approach and I am surprised that you can add custom runners for your CI/CD pipeline.&lt;/p&gt;

&lt;p&gt;I will create a very simple Kotlin application to show how to deploy a library in a private Maven repository. I am going to use &lt;a href="https://repsy.io"&gt;Repsy&lt;/a&gt; for Maven repository hosting. It gives 3 GB of free storage and should be sufficient for most cases.&lt;/p&gt;

&lt;p&gt;Let's create a Gradle project, your IDE will help with this, or you can install Gradle CLI from the official &lt;a href="https://gradle.org/"&gt;gradle&lt;/a&gt; site or you can use &lt;a href="https://sdkman.io/"&gt;SdkMan&lt;/a&gt; for this purpose.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sdk i gradle
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Gradle CLI will help you to bootstrap your project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;hello-actions-kotlin-lib
&lt;span class="nb"&gt;cd &lt;/span&gt;hello-actions-kotlin-lib
gradle init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Gradle will ask us a bunch of questions. I will select the &lt;code&gt;library&lt;/code&gt; type for project generation&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Select the type of project to generate:
  1: basic
  2: application
  3: library
  4: Gradle plugin
Enter selection (default: basic) [1..4] 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Kotlin for programming language selection. I'm happy to see plenty of options there.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Select implementation language:
  1: C++
  2: Groovy
  3: Java
  4: Kotlin
  5: Scala
  6: Swift
Enter selection (default: Java) [1..6] 4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And going to use Kotlin DSL instead of Groovy.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Select build script DSL:
  1: Kotlin
  2: Groovy
Enter selection (default: Kotlin) [1..2] 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Just press enter for the default project name or you can enter another one suitable for you.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Project name (default: hello-actions-kotlin-lib):
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the source package selection, I am going to use my GitHub TLD but feel free to use your package structure.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Source package (default: hello.actions.kotlin.lib): com.github.firatkucuk.hello_actions_kotlin_lib
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As a final question gradle will ask you the Java version. You may want to select the Latest LTS version (21) or one one the safest ones &lt;code&gt;8&lt;/code&gt; or &lt;code&gt;11&lt;/code&gt;. I'll choose 17.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Enter target version of Java (min. 7) (default: 21): 17
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It seems a little bit long but that’s OK. Gradle will create a simple &lt;code&gt;Library.kt&lt;/code&gt; file. Let’s rename it &lt;code&gt;Hello.kt&lt;/code&gt; and change the content.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.github.firatkucuk.hello_actions_kotlin_lib;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Hello&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;sayHello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Hello $text"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And same for the test file &lt;code&gt;LibraryTest.kt&lt;/code&gt;. Let's rename it to &lt;code&gt;HelloTest.kt&lt;/code&gt; and change the test file content to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.github.firatkucuk.hello_actions_kotlin_lib&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlin.test.Test&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlin.test.assertEquals&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HelloTest&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;@Test&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;sayHelloMethodReturnsHello&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;classUnderTest&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Hello&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;assertEquals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello World"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;classUnderTest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sayHello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"World"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s"&gt;"sayHello method should return 'Hello World'"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we can test the build operation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gradle build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The next phase is publishing our library to our private maven repository in &lt;a href="https://respy.io"&gt;repsy.io&lt;/a&gt;. After signup, &lt;a href="https://repsy.io"&gt;repsy&lt;/a&gt; creates a default repository that can be used with the account password. So you only need to sign up, and that’s all.&lt;/p&gt;

&lt;p&gt;Let’s modify our &lt;code&gt;build.gradle.kts&lt;/code&gt; file for publishing the artifact. The most important part is adding a &lt;code&gt;maven-publish&lt;/code&gt; plugin and a publishing section with the credentials from repsy.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="n"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"1.0.0"&lt;/span&gt;

&lt;span class="nf"&gt;plugins&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Apply the org.jetbrains.kotlin.jvm Plugin to add support for Kotlin.&lt;/span&gt;
    &lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"org.jetbrains.kotlin.jvm"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;version&lt;/span&gt; &lt;span class="s"&gt;"1.9.10"&lt;/span&gt;

    &lt;span class="c1"&gt;// Apply the java-library plugin for API and implementation separation.&lt;/span&gt;
    &lt;span class="n"&gt;`java-library`&lt;/span&gt;
    &lt;span class="n"&gt;`maven-publish`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;repositories&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Use Maven Central for resolving dependencies.&lt;/span&gt;
    &lt;span class="nf"&gt;mavenCentral&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;repsyUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="n"&gt;project&lt;/span&gt;
&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;repsyUsername&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="n"&gt;project&lt;/span&gt;
&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;repsyPassword&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="n"&gt;project&lt;/span&gt;

&lt;span class="nf"&gt;publishing&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;publications&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;MavenPublication&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;"maven"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;components&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"java"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;repositories&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;maven&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;repsyUrl&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nf"&gt;credentials&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;username&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;repsyUsername&lt;/span&gt;
                &lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;repsyPassword&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;dependencies&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Use the Kotlin JUnit 5 integration.&lt;/span&gt;
    &lt;span class="nf"&gt;testImplementation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"org.jetbrains.kotlin:kotlin-test-junit5"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;// Use the JUnit 5 integration.&lt;/span&gt;
    &lt;span class="nf"&gt;testImplementation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"org.junit.jupiter:junit-jupiter-engine:5.9.3"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nf"&gt;testRuntimeOnly&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"org.junit.platform:junit-platform-launcher"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;// This dependency is exported to consumers, that is to say found on their compile classpath.&lt;/span&gt;
    &lt;span class="nf"&gt;api&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"org.apache.commons:commons-math3:3.6.1"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;// This dependency is used internally, and not exposed to consumers on their own compile classpath.&lt;/span&gt;
    &lt;span class="nf"&gt;implementation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"com.google.guava:guava:32.1.1-jre"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Apply a specific Java toolchain to ease working on different environments.&lt;/span&gt;
&lt;span class="nf"&gt;java&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;toolchain&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;languageVersion&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;JavaLanguageVersion&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;17&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;named&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Test&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;"test"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Use JUnit Platform for unit tests.&lt;/span&gt;
    &lt;span class="nf"&gt;useJUnitPlatform&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our project implementation is completed. Let’s create git integration of our project. First, create an empty git project called &lt;code&gt;hello-actions-kotlin-lib&lt;/code&gt; on GitHub. After that, we commit the changes and push files to GitHub.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git init
git add &lt;span class="nb"&gt;.&lt;/span&gt;
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"initial commit"&lt;/span&gt;
git remote add origin git@github.com:YOUR_GITHUB_USER_NAME/hello-actions-kotlin-lib.git
git push origin main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The next step is integrating your project with GitHub Actions. Go to &lt;code&gt;https://github.com/YOUR_USER_NAME/hello-actions-kotlin-lib/actions/new&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Please Find the &lt;strong&gt;Java with Gradle&lt;/strong&gt; Action. Then you can click the &lt;strong&gt;Set up this workflow&lt;/strong&gt; button. An online editor will be opened up.&lt;/p&gt;

&lt;p&gt;Let’s directly commit the changes and we’re gonna see our Action will run immediately. GitHub action will fail so please ignore this. It requires some properties file we’re gonna add properties as GitHub secret.&lt;/p&gt;

&lt;p&gt;We need to create a GitHub secret for our &lt;code&gt;gradle.properties&lt;/code&gt; file. But because of the limitations. GitHub cannot use file content as secrets. GitLab has the same restriction once upon a time then they’ve introduced File types but we need to create a text file our local computer. The content should be something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;repsyUrl&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;https://repo.repsy.io/mvn/YOUR_REPSY_USERNAME/default&lt;/span&gt;
&lt;span class="py"&gt;repsyUsername&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;YOUR_REPSY_USERNAME&lt;/span&gt;
&lt;span class="py"&gt;repsyPassword&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;YOUR_REPSY_PASSWORD&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We need to encode this with base64. There are many online base64 converters. If you’re using Mac/Linux it should be easy like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;base64&lt;/span&gt; &lt;span class="nt"&gt;-w0&lt;/span&gt; gradle.properties
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's copy the output and create a secret. Go to &lt;code&gt;https://github.com/YOUR_USER_NAME/hello-actions-kotlin-lib/settings/secrets&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Add a GitHub secret called GRADLE_PROPERTIES and paste the encoded string into it.&lt;/p&gt;

&lt;p&gt;Now we can open our pipeline configuration file and make the latest changes. Go To &lt;code&gt;https://github.com/YOUR_USER_NAME/hello-actions-kotlin-lib/blob/master/.github/workflows/gradle.yml&lt;/code&gt; and click the edit button. We will add some extra steps for injecting Gradle properties.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Java CI with Gradle&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;main&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;main&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;

    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4.1.1&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Set up JDK &lt;/span&gt;&lt;span class="m"&gt;17&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-java@v3.13.0&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;java-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;17&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Grant execute permission for gradlew&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;chmod +x gradlew&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build with Gradle&lt;/span&gt;
        &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;GRADLE_PROPERTIES&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.GRADLE_PROPERTIES }}&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mkdir -p ~/.gradle &amp;amp;&amp;amp; echo $GRADLE_PROPERTIES | base64 -d &amp;gt; ~/.gradle/gradle.properties &amp;amp;&amp;amp; cat ~/.gradle/gradle.properties &amp;amp;&amp;amp; ./gradlew build&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;publish&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./gradlew publish&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s all you can find the source code &lt;a href="https://github.com/firatkucuk/hello-actions-kotlin-lib"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>java</category>
      <category>kotlin</category>
      <category>git</category>
    </item>
    <item>
      <title>Creating Private Maven/Gradle Repository</title>
      <dc:creator>Fırat Küçük</dc:creator>
      <pubDate>Sun, 31 May 2020 15:03:47 +0000</pubDate>
      <link>https://dev.to/fk/creating-private-maven-gradle-repository-2np3</link>
      <guid>https://dev.to/fk/creating-private-maven-gradle-repository-2np3</guid>
      <description>&lt;p&gt;In some cases, you need a private library, maybe because of your company's privacy policy or your personal preferences. For instance, you have multiple projects and you need some common DTOs or common utilities. It might be a good choice to separate them and make it a common jar package for those.&lt;/p&gt;

&lt;p&gt;You need to install Maven and JDK for this tutorial. If you don't have Maven or JDK installed. Maybe you can try &lt;a href="https://sdkman.io"&gt;sdkman&lt;/a&gt;. In general, I prefer using &lt;a href="https://github.com/takari/maven-wrapper"&gt;maven wrapper&lt;/a&gt; in my projects.&lt;/p&gt;

&lt;h1&gt;
  
  
  Deployment to Private Maven Repository
&lt;/h1&gt;

&lt;p&gt;I am going to use &lt;a href="https://repsy.io"&gt;Repsy&lt;/a&gt; for this purpose. It's easy to use a Cloud Maven repository. So let's create a common library first. You can create a maven project using your favorite IDE or editor.&lt;/p&gt;

&lt;p&gt;Your initial project structure will be like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- src
  - main
    - java
    - resources
  - test
- pom.xml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First, let's create a package that represents our company TLD or our personal preference. I am gonna use my personal GitHub TLD. You can use yours or something else. After creating the package directory structure will be something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- src
  - main
    - java
      - com
        - github
          - firatkucuk
            - hellomavenlib
    - resources
  - test
- pom.xml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ok, now we can create our super complicated library class.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.github.firatkucuk.hellomavenlib&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Hello&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nf"&gt;Hello&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;sayHello&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Hello "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the final stage, we need to modify our &lt;code&gt;pom.xml&lt;/code&gt;. A definitive section for our library artifact is needed. It will be something like that.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;project&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;"http://maven.apache.org/POM/4.0.0"&lt;/span&gt;
         &lt;span class="na"&gt;xmlns:xsi=&lt;/span&gt;&lt;span class="s"&gt;"http://www.w3.org/2001/XMLSchema-instance"&lt;/span&gt;
         &lt;span class="na"&gt;xsi:schemaLocation=&lt;/span&gt;&lt;span class="s"&gt;"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;modelVersion&amp;gt;&lt;/span&gt;4.0.0&lt;span class="nt"&gt;&amp;lt;/modelVersion&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;com.github.firatkucuk&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;hello-maven-lib&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;1.0&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;packaging&amp;gt;&lt;/span&gt;jar&lt;span class="nt"&gt;&amp;lt;/packaging&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;properties&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;maven.compiler.source&amp;gt;&lt;/span&gt;11&lt;span class="nt"&gt;&amp;lt;/maven.compiler.source&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;maven.compiler.target&amp;gt;&lt;/span&gt;11&lt;span class="nt"&gt;&amp;lt;/maven.compiler.target&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;project.build.sourceEncoding&amp;gt;&lt;/span&gt;UTF-8&lt;span class="nt"&gt;&amp;lt;/project.build.sourceEncoding&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;project.reporting.outputEncoding&amp;gt;&lt;/span&gt;UTF-8&lt;span class="nt"&gt;&amp;lt;/project.reporting.outputEncoding&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/properties&amp;gt;&lt;/span&gt;

  &lt;span class="c"&gt;&amp;lt;!-- The other stuff will come here --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/project&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To proceed to the next section, we need to create an account at &lt;a href="https://repsy.io"&gt;Repsy&lt;/a&gt;. You can directly go to the &lt;a href="https://panel/repsy.io/register"&gt;register&lt;/a&gt; section. Pick a username and password that's all. Now we can use our maven repository. Repsy automatically creates a private Maven repository called &lt;code&gt;default&lt;/code&gt; for us.&lt;/p&gt;

&lt;p&gt;It might be a good practice to not store the Maven repository password in our Maven library &lt;code&gt;pom.xml&lt;/code&gt; file. So let's create a settings file or modify the existing one. In your operating system, there should be &lt;code&gt;.m2&lt;/code&gt; folder in your home directory. If you haven't used Maven yet you might need to create one. For Linux/Mac users &lt;code&gt;~/.m2&lt;/code&gt; directory. If it doesn't exist. You can create one via &lt;code&gt;mkdir ~/.m2&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let's create/modify &lt;code&gt;~/.m2/settings.xml&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;settings&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;"http://maven.apache.org/SETTINGS/1.0.0"&lt;/span&gt;
   &lt;span class="na"&gt;xmlns:xsi=&lt;/span&gt;&lt;span class="s"&gt;"http://www.w3.org/2001/XMLSchema-instance"&lt;/span&gt;
   &lt;span class="na"&gt;xsi:schemaLocation=&lt;/span&gt;&lt;span class="s"&gt;"http://maven.apache.org/SETTINGS/1.0.0
   http://maven.apache.org/xsd/settings-1.0.0.xsd"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

   &lt;span class="nt"&gt;&amp;lt;servers&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;server&amp;gt;&lt;/span&gt;
       &lt;span class="nt"&gt;&amp;lt;id&amp;gt;&lt;/span&gt;repsy&lt;span class="nt"&gt;&amp;lt;/id&amp;gt;&lt;/span&gt;
       &lt;span class="nt"&gt;&amp;lt;username&amp;gt;&lt;/span&gt;YOUR_REPSY_USERNAME&lt;span class="nt"&gt;&amp;lt;/username&amp;gt;&lt;/span&gt;
       &lt;span class="nt"&gt;&amp;lt;password&amp;gt;&lt;/span&gt;YOUR_REPSY_PASSWORD&lt;span class="nt"&gt;&amp;lt;/password&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;/server&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;/servers&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;/settings&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Please modify your &lt;code&gt;username&lt;/code&gt; and &lt;code&gt;password&lt;/code&gt; sections. Let's put the deployment repository definition section into our &lt;code&gt;pom.xml&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;project&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;"http://maven.apache.org/POM/4.0.0"&lt;/span&gt;
         &lt;span class="na"&gt;xmlns:xsi=&lt;/span&gt;&lt;span class="s"&gt;"http://www.w3.org/2001/XMLSchema-instance"&lt;/span&gt;
         &lt;span class="na"&gt;xsi:schemaLocation=&lt;/span&gt;&lt;span class="s"&gt;"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;modelVersion&amp;gt;&lt;/span&gt;4.0.0&lt;span class="nt"&gt;&amp;lt;/modelVersion&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;com.github.firatkucuk&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;hello-maven-lib&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;1.0&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;packaging&amp;gt;&lt;/span&gt;jar&lt;span class="nt"&gt;&amp;lt;/packaging&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;properties&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;maven.compiler.source&amp;gt;&lt;/span&gt;11&lt;span class="nt"&gt;&amp;lt;/maven.compiler.source&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;maven.compiler.target&amp;gt;&lt;/span&gt;11&lt;span class="nt"&gt;&amp;lt;/maven.compiler.target&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;project.build.sourceEncoding&amp;gt;&lt;/span&gt;UTF-8&lt;span class="nt"&gt;&amp;lt;/project.build.sourceEncoding&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;project.reporting.outputEncoding&amp;gt;&lt;/span&gt;UTF-8&lt;span class="nt"&gt;&amp;lt;/project.reporting.outputEncoding&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/properties&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;distributionManagement&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;repository&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;id&amp;gt;&lt;/span&gt;repsy&lt;span class="nt"&gt;&amp;lt;/id&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;My Private Maven Repositoty on Repsy&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;url&amp;gt;&lt;/span&gt;https://repo.repsy.io/mvn/YOUR_REPSY_USERNAME/default&lt;span class="nt"&gt;&amp;lt;/url&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/repository&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/distributionManagement&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/project&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Please change your repository URL. It will be something like: &lt;code&gt;https://repo.repsy.io/mvn/YOUR_REPSY_USERNAME/default&lt;/code&gt;. Now we can deploy our very first private repo library.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mvn compile deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's all for the deployment part. If you want to access the source code for this library. You can access it from &lt;a href="https://github.com/firatkucuk/hello-maven-lib"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Using Private Maven Repository
&lt;/h1&gt;

&lt;p&gt;Let's create another project with a proper TLD structure.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- src
  - main
    - java
      - com
        - github
          - firatkucuk
            - hellomavenapp
    - resources
  - test
- pom.xml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and modify our &lt;code&gt;pom.xml&lt;/code&gt; with proper remote repo settings and dependency settings.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;project&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;"http://maven.apache.org/POM/4.0.0"&lt;/span&gt;
         &lt;span class="na"&gt;xmlns:xsi=&lt;/span&gt;&lt;span class="s"&gt;"http://www.w3.org/2001/XMLSchema-instance"&lt;/span&gt;
         &lt;span class="na"&gt;xsi:schemaLocation=&lt;/span&gt;&lt;span class="s"&gt;"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;modelVersion&amp;gt;&lt;/span&gt;4.0.0&lt;span class="nt"&gt;&amp;lt;/modelVersion&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;com.github.firatkucuk&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;hello-maven-app&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;1.0&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;properties&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;maven.compiler.source&amp;gt;&lt;/span&gt;11&lt;span class="nt"&gt;&amp;lt;/maven.compiler.source&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;maven.compiler.target&amp;gt;&lt;/span&gt;11&lt;span class="nt"&gt;&amp;lt;/maven.compiler.target&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;project.build.sourceEncoding&amp;gt;&lt;/span&gt;UTF-8&lt;span class="nt"&gt;&amp;lt;/project.build.sourceEncoding&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;project.reporting.outputEncoding&amp;gt;&lt;/span&gt;UTF-8&lt;span class="nt"&gt;&amp;lt;/project.reporting.outputEncoding&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/properties&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;repositories&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;repository&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;id&amp;gt;&lt;/span&gt;repsy&lt;span class="nt"&gt;&amp;lt;/id&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;My Private Maven Repositoty on Repsy&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;url&amp;gt;&lt;/span&gt;https://repo.repsy.io/mvn/firat/default&lt;span class="nt"&gt;&amp;lt;/url&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/repository&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/repositories&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;dependencies&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;com.github.firatkucuk&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;hello-maven-lib&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;1.0&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/dependencies&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/project&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Please do not forget to change your repository URL.&lt;/p&gt;

&lt;p&gt;Let's create a Java class that uses our hello library.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.github.firatkucuk.hellomavenapp&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.github.firatkucuk.hellomavenlib.Hello&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Main&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;Hello&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sayHello&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;Hello&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sayHello&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"maven"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's compile our project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mvn compile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's all our sample application uses a remote private repository. If you're not using a framework like Spring you need to take a look at some fatjar solutions or if you're gonna deploy to Java Application server. You can change your packaging to war and can execute &lt;code&gt;mvn compile package&lt;/code&gt;. I am going to copy dependencies and execute with that dependency.&lt;/p&gt;

&lt;p&gt;Let's run the Maven dependency plug-in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mvn compile dependency:copy-dependencies
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;let's run with the classpath definition&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;java &lt;span class="nt"&gt;-cp&lt;/span&gt; target/dependency/hello-maven-lib-1.0.jar:target/classes com.github.firatkucuk.hellomavenapp.Main &lt;span class="s2"&gt;"World!"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can reach the source code from &lt;a href="https://github.com/firatkucuk/hello-maven-app"&gt;here&lt;/a&gt;&lt;/p&gt;

</description>
      <category>maven</category>
      <category>gradle</category>
      <category>java</category>
      <category>kotlin</category>
    </item>
    <item>
      <title>Kotlin Native Experiment</title>
      <dc:creator>Fırat Küçük</dc:creator>
      <pubDate>Wed, 11 Dec 2019 21:33:23 +0000</pubDate>
      <link>https://dev.to/fk/kotlin-native-experiment-5e0i</link>
      <guid>https://dev.to/fk/kotlin-native-experiment-5e0i</guid>
      <description>&lt;p&gt;I don't know why but I really love simple executable programs. Maybe it's just because I am dealing with Java stuff and missing fast and small applications. Executables without any runtime dependencies. That's why Go and Rust languages blink. No offense but I don't like Go's exception handling and Rust syntax is pretty weird. More human-readable languages like TypeScript and Kotlin seems better. Thanks to LLVM and GraalVM, our programming languages and applications are faster than ever.&lt;/p&gt;

&lt;p&gt;Microservices age triggers the micro-sized and ultrafast applications and frameworks. Micronaut, Quarkus, Helidon, and Spark some of the great examples of that era. Thanks God, all those fancy toys and spring boot supports Kotlin.&lt;/p&gt;

&lt;p&gt;Kotlin is one of my favorite programming languages. To be honest, at the beginning I refused to accept the variable definition syntax.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;myVariable&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"hello"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I find classical Java-style more convenient. For instance when you write &lt;code&gt;CarFactory&lt;/code&gt; IDE auto-completes &lt;code&gt;carFactory&lt;/code&gt; variable name in Java-like programming languages.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;CarFactory&lt;/span&gt; &lt;span class="n"&gt;carFactory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;CarFactory&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But despite its unusual variable declaration, there're plenty of cool things in Kotlin. Immutable data types, data classes, by default final classes, co-routines, and many more. I am determined and focused on the journey of Kotlin. So here we're. Gonna try a Kotlin native application.&lt;/p&gt;

&lt;p&gt;Currently, most of the Kotlin native examples are based on IntelliJ IDEA. Well... I didn't like this idea. It should be as simple as possible. So I tried to download a native compiler. But currently, it's really difficult to obtain one. Either you should compile or you should use IntelliJ IDEA.&lt;/p&gt;

&lt;p&gt;So I found out the executables URL. You can download them for 1.3.61 version.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://download.jetbrains.com/kotlin/native/builds/releases/1.3.61/linux/kotlin-native-linux-1.3.61.tar.gz"&gt;Linux&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://download.jetbrains.com/kotlin/native/builds/releases/1.3.61/windows/kotlin-native-windows-1.3.61.zip"&gt;Windows&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://download.jetbrains.com/kotlin/native/builds/releases/1.3.61/macos/kotlin-native-macos-1.3.61.tar.gz"&gt;MacOS&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After downloading and extracting the content you can compile via command-line. Try to save this hello world program as &lt;code&gt;hello.kt&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Hello, Kotlin/Native!"&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and then let's compile it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
./kotlinc &lt;span class="nt"&gt;-o&lt;/span&gt; hello hello.kt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Kotlin compiler is gonna compile needed dependencies. After compilation completed we can try our executable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./hello.kexe
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's 387KB a little bit bigger than a standard C/C++ application. But it's Ok. :) It's not a statically compiled executable. The target is dynamically linked.&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>llvm</category>
    </item>
  </channel>
</rss>
