<?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: Sanjay Ghosh</title>
    <description>The latest articles on DEV Community by Sanjay Ghosh (@sanjayghosh).</description>
    <link>https://dev.to/sanjayghosh</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%2F3733607%2F167b985e-e1fa-44ef-afd9-7e6c162a39fe.jpg</url>
      <title>DEV Community: Sanjay Ghosh</title>
      <link>https://dev.to/sanjayghosh</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sanjayghosh"/>
    <language>en</language>
    <item>
      <title>Understanding Common Cybersecurity Attacks: A Practical Overview</title>
      <dc:creator>Sanjay Ghosh</dc:creator>
      <pubDate>Tue, 14 Apr 2026 18:10:37 +0000</pubDate>
      <link>https://dev.to/sanjayghosh/understanding-common-cybersecurity-attacks-a-practical-overview-2mea</link>
      <guid>https://dev.to/sanjayghosh/understanding-common-cybersecurity-attacks-a-practical-overview-2mea</guid>
      <description>&lt;p&gt;Modern applications are more powerful and interconnected than ever—but with that power comes increased exposure to security risks. Whether you're building a small backend service or a large distributed system, &lt;strong&gt;security is no longer optional&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Before diving into specific vulnerabilities, it’s important to understand &lt;strong&gt;why cybersecurity matters&lt;/strong&gt; and how common attacks are structured.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Cybersecurity Matters in Modern Applications
&lt;/h3&gt;

&lt;h4&gt;
  
  
  🔐 Data Protection &amp;amp; Privacy
&lt;/h4&gt;

&lt;p&gt;Modern applications handle large amounts of sensitive data—personally identifiable information (PII), financial records, and intellectual property. This makes them prime targets for attackers.&lt;/p&gt;

&lt;h4&gt;
  
  
  🏢 Maintaining Trust &amp;amp; Reputation
&lt;/h4&gt;

&lt;p&gt;Users trust applications with their personal and financial data. A single breach can damage reputation, erode customer trust, and lead to significant financial loss.&lt;/p&gt;

&lt;h4&gt;
  
  
  ⚖️ Regulatory Compliance
&lt;/h4&gt;

&lt;p&gt;Organizations must comply with regulations such as GDPR and industry standards. Failing to do so can result in heavy fines and legal consequences.&lt;/p&gt;

&lt;h4&gt;
  
  
  ⚙️ System Integrity &amp;amp; Availability
&lt;/h4&gt;

&lt;p&gt;Security controls such as encryption and access management ensure that systems remain reliable, tamper-proof, and available—even under attack.&lt;/p&gt;

&lt;h4&gt;
  
  
  🚀 Defending Against Sophisticated Threats
&lt;/h4&gt;

&lt;p&gt;As technologies like cloud computing and AI evolve, so do attack techniques—ransomware, phishing, and zero-day exploits are becoming more advanced.&lt;/p&gt;

&lt;h4&gt;
  
  
  🌐 Protecting Interconnected Systems
&lt;/h4&gt;

&lt;p&gt;Modern systems rely heavily on APIs, microservices, and IoT devices. A vulnerability in one component can compromise the entire ecosystem.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Role of OWASP (Open Worldwide Application Security Project)
&lt;/h3&gt;

&lt;p&gt;Learn more: &lt;a href="https://owasp.org/" rel="noopener noreferrer"&gt;https://owasp.org/&lt;/a&gt;&lt;br&gt;
When discussing application security, it’s hard to ignore OWASP.&lt;/p&gt;

&lt;p&gt;OWASP is a nonprofit foundation that provides open-source resources, tools, and best practices to help developers build secure applications.&lt;/p&gt;

&lt;p&gt;One of its most well-known contributions is the OWASP Top 10, which highlights the most critical web security risks.&lt;/p&gt;
&lt;h3&gt;
  
  
  OWASP Top 10 (2025)
&lt;/h3&gt;

&lt;p&gt;Full list: &lt;a href="https://owasp.org/Top10/2025/" rel="noopener noreferrer"&gt;https://owasp.org/Top10/2025/&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A01: Broken Access Control&lt;/li&gt;
&lt;li&gt;A02: Security Misconfiguration&lt;/li&gt;
&lt;li&gt;A03: Software Supply Chain Failures&lt;/li&gt;
&lt;li&gt;A04: Cryptographic Failures&lt;/li&gt;
&lt;li&gt;A05: Injection&lt;/li&gt;
&lt;li&gt;A06: Insecure Design&lt;/li&gt;
&lt;li&gt;A07: Authentication Failures&lt;/li&gt;
&lt;li&gt;A08: Software or Data Integrity Failures&lt;/li&gt;
&lt;li&gt;A09: Security Logging and Alerting Failures&lt;/li&gt;
&lt;li&gt;A10: Mishandling of Exceptional Conditions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These categories are widely used as a baseline for secure application design.&lt;/p&gt;
&lt;h3&gt;
  
  
  A Simple Classification of Cybersecurity Attacks
&lt;/h3&gt;

&lt;p&gt;To make sense of the landscape, we can group common attacks into four practical categories:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Web Attacks&lt;/li&gt;
&lt;li&gt;Authentication Attacks&lt;/li&gt;
&lt;li&gt;Network Attacks&lt;/li&gt;
&lt;li&gt;Human (Social Engineering) Attacks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Some threats span multiple areas, so we’ll also note a few cross-category cases.&lt;/p&gt;
&lt;h3&gt;
  
  
  🌐 Web Attacks (Application Layer)
&lt;/h3&gt;

&lt;p&gt;These target application logic, APIs, and user input handling.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Injection Attacks (SQL, Command, LDAP)&lt;/p&gt;

&lt;p&gt;→ Example: ' OR 1=1 -- login bypass&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Cross-Site Scripting (XSS)&lt;/p&gt;

&lt;p&gt;→ Injecting malicious JavaScript into web pages&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Cross-Site Request Forgery (CSRF)&lt;/p&gt;

&lt;p&gt;→ Forcing a logged-in user to perform unintended actions&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Broken Access Control&lt;/p&gt;

&lt;p&gt;→ Accessing unauthorized data (e.g., changing /user/123 to /user/124)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Security Misconfiguration&lt;/p&gt;

&lt;p&gt;→ Default credentials, open ports, debug settings&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Insecure Deserialization&lt;/p&gt;

&lt;p&gt;→ Executing malicious code via manipulated serialized objects&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  🔑 Authentication Attacks
&lt;/h3&gt;

&lt;p&gt;These focus on compromising login systems and user identities.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Brute Force / Dictionary Attacks&lt;/li&gt;
&lt;li&gt;Session Hijacking / Fixation&lt;/li&gt;
&lt;li&gt;Rainbow Table Attacks (password hash cracking technique)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  🧠 Network Attacks
&lt;/h3&gt;

&lt;p&gt;These target communication between systems.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Man-in-the-Middle (MITM)&lt;/p&gt;

&lt;p&gt;→ Intercepting data in transit&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Denial of Service (DoS / DDoS)&lt;br&gt;
→ Overwhelming systems to make them unavailable&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  🧑‍💻 Human Attacks (Social Engineering)
&lt;/h3&gt;

&lt;p&gt;These exploit human behavior rather than systems.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Phishing (Email, SMS, Voice)&lt;/p&gt;

&lt;p&gt;→ Trick users into revealing sensitive data&lt;br&gt;
💡 These are among the most successful real-world attacks.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  🔄 Cross-Category / Special Cases
&lt;/h3&gt;

&lt;p&gt;Some threats don’t fit neatly into one category:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Malware (virus, ransomware, spyware)&lt;/li&gt;
&lt;li&gt;Zero-day exploits (attacks on unknown vulnerabilities)
These can impact multiple layers—from applications to networks to users.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  A Quick Example: How Vulnerabilities Start in Code
&lt;/h3&gt;

&lt;p&gt;At this point, you might be wondering:&lt;br&gt;
“These attacks sound serious—but how do they relate to the code we write every day?”&lt;/p&gt;

&lt;p&gt;Let’s look at a simple backend example that illustrates how easily security vulnerabilities can be introduced.&lt;/p&gt;

&lt;p&gt;This example focuses on password handling, but the same principle applies across all categories—small implementation choices can introduce major vulnerabilities.&lt;/p&gt;

&lt;p&gt;Security vulnerabilities are often not caused by complex systems—but by small, overlooked decisions in everyday code.&lt;/p&gt;

&lt;p&gt;❌ Insecure Approach: Plain Text Storage&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;String&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"admin123"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;stored&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// storing plain text ❌&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If a database is compromised, attackers immediately gain access to user passwords.&lt;/p&gt;

&lt;p&gt;⚠️ Slightly Better: Hashing (But Still Weak)&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;MessageDigest&lt;/span&gt; &lt;span class="n"&gt;md&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MessageDigest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getInstance&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"SHA-256"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;hash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;md&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;digest&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getBytes&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hashing improves security, but it’s still vulnerable to precomputed attacks (like rainbow tables).&lt;/p&gt;

&lt;p&gt;✅ Better Approach (Conceptual)&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;String&lt;/span&gt; &lt;span class="n"&gt;saltedPassword&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;randomSalt&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Adding randomness makes attacks significantly harder.&lt;/p&gt;

&lt;p&gt;We’ll explore why this matters in detail when we dive into authentication attacks in the next article.&lt;/p&gt;

&lt;p&gt;Final Thoughts&lt;/p&gt;

&lt;p&gt;Cybersecurity isn’t just about preventing attacks—it’s about building systems that are resilient by design.&lt;/p&gt;

&lt;p&gt;As we’ve seen:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Attacks can target applications, networks, and even people&lt;/li&gt;
&lt;li&gt;Many vulnerabilities originate from small design or coding decisions&lt;/li&gt;
&lt;li&gt;Understanding attack patterns is the first step toward preventing them&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What’s Next?&lt;br&gt;
In the next article, we’ll take a deeper look at authentication attacks, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How attackers crack passwords&lt;/li&gt;
&lt;li&gt;What rainbow table attacks are&lt;/li&gt;
&lt;li&gt;Why techniques like salting are critical&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>cybersecurity</category>
      <category>security</category>
      <category>webdev</category>
      <category>java</category>
    </item>
    <item>
      <title>Build a RAG Pipeline in Java (Text Vector LLM, No Paid APIs)</title>
      <dc:creator>Sanjay Ghosh</dc:creator>
      <pubDate>Wed, 01 Apr 2026 23:23:34 +0000</pubDate>
      <link>https://dev.to/sanjayghosh/build-a-rag-pipeline-in-java-text-vector-llm-no-paid-apis-3lc3</link>
      <guid>https://dev.to/sanjayghosh/build-a-rag-pipeline-in-java-text-vector-llm-no-paid-apis-3lc3</guid>
      <description>&lt;p&gt;Ever asked an LLM a question about your own data and received an incorrect or generic answer?&lt;/p&gt;

&lt;p&gt;That’s because Large Language Models (LLMs) don’t know your private data.&lt;/p&gt;

&lt;p&gt;In this article, we’ll build a complete &lt;strong&gt;Retrieval-Augmented Generation (RAG)&lt;/strong&gt; pipeline using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Java&lt;/li&gt;
&lt;li&gt;PostgreSQL (with vector support)&lt;/li&gt;
&lt;li&gt;Ollama (local LLM + embeddings)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 No OpenAI / No paid APIs&lt;br&gt;
👉 Fully local&lt;br&gt;
👉 Practical and production-relevant&lt;/p&gt;
&lt;h3&gt;
  
  
  🧠 What is RAG?
&lt;/h3&gt;

&lt;p&gt;Retrieval-Augmented Generation (RAG) is an architecture that improves LLM responses by:&lt;/p&gt;

&lt;p&gt;Retrieving relevant data from a knowledge source&lt;br&gt;
Passing that data to the LLM&lt;br&gt;
Generating an answer grounded in that context&lt;/p&gt;

&lt;p&gt;In simple terms:&lt;/p&gt;

&lt;p&gt;Instead of guessing, the model first looks up relevant information and then answers.&lt;/p&gt;
&lt;h3&gt;
  
  
  🔍 Why Do We Need RAG?
&lt;/h3&gt;

&lt;p&gt;LLMs are powerful, but they have limitations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;❌ They don’t know your private/company data&lt;/li&gt;
&lt;li&gt;❌ Their knowledge is static&lt;/li&gt;
&lt;li&gt;❌ They can hallucinate&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;RAG solves this by combining:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your data (database)&lt;/li&gt;
&lt;li&gt;Smart retrieval (vector search)&lt;/li&gt;
&lt;li&gt;LLM reasoning (generation)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  📊 RAG Flow (This Project)
&lt;/h3&gt;

&lt;p&gt;We will implement this pipeline:&lt;br&gt;
Text → Embedding → Store in DB&lt;/p&gt;

&lt;p&gt;Query → Embedding&lt;br&gt;
        ↓&lt;br&gt;
   Vector Search (Top K)&lt;br&gt;
        ↓&lt;br&gt;
   Pass to LLM&lt;br&gt;
        ↓&lt;br&gt;
   Final Answer&lt;/p&gt;
&lt;h3&gt;
  
  
  ⚙️ Prerequisites
&lt;/h3&gt;
&lt;h4&gt;
  
  
  1. Install PostgreSQL
&lt;/h4&gt;

&lt;p&gt;Make sure PostgreSQL is installed and running.&lt;/p&gt;
&lt;h4&gt;
  
  
  2. Install Ollama (Local LLM)
&lt;/h4&gt;

&lt;p&gt;sudo apt-get install zstd&lt;br&gt;
curl -fsSL &lt;a href="https://ollama.com/install.sh" rel="noopener noreferrer"&gt;https://ollama.com/install.sh&lt;/a&gt; | sh&lt;/p&gt;
&lt;h4&gt;
  
  
  3. Pull Required Models
&lt;/h4&gt;

&lt;p&gt;# LLM (for answer generation)&lt;br&gt;
ollama pull llama3&lt;/p&gt;

&lt;p&gt;# Embedding model&lt;br&gt;
ollama pull nomic-embed-text&lt;/p&gt;
&lt;h4&gt;
  
  
  4. Verify Installation
&lt;/h4&gt;

&lt;p&gt;ollama run llama3&lt;br&gt;
If it responds, you’re ready.&lt;/p&gt;
&lt;h3&gt;
  
  
  🟢 Phase 1: Indexing (Store Data)
&lt;/h3&gt;

&lt;p&gt;In this phase, we:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Convert text → vector (embedding)&lt;/li&gt;
&lt;li&gt;Store it in PostgreSQL&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;
  
  
  Why Embeddings?
&lt;/h4&gt;

&lt;p&gt;Embeddings convert text into numbers so we can measure similarity.&lt;br&gt;
Example:&lt;br&gt;
&lt;code&gt;"OAuth authentication"&lt;br&gt;
→ [0.12, -0.98, 0.45, ...]&lt;/code&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Database Table
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;CREATE TABLE text_embeddings (&lt;br&gt;
    id SERIAL PRIMARY KEY,&lt;br&gt;
    content TEXT,&lt;br&gt;
    embedding VECTOR(768)&lt;br&gt;
);&lt;/code&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Key Class: EmbeddingService.java
&lt;/h4&gt;

&lt;p&gt;Calls Ollama&lt;br&gt;
Converts text → vector&lt;/p&gt;

&lt;p&gt;Snippet&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;ClassicHttpResponse&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ClassicHttpResponse&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nc"&gt;Request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;post&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"http://localhost:11434/api/embeddings"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;bodyString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="nc"&gt;ContentType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;APPLICATION_JSON&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;execute&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;returnResponse&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This returns a numerical vector representation of the input text, which we store in the database.&lt;/p&gt;

&lt;h4&gt;
  
  
  Key Class: StorageService.java
&lt;/h4&gt;

&lt;p&gt;Stores text + embedding into PostgreSQL&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;PreparedStatement&lt;/span&gt; &lt;span class="n"&gt;ps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;prepareStatement&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"INSERT INTO text_embeddings (content, embedding) VALUES (?, ?::vector)"&lt;/span&gt;
        &lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;ps&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;ps&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;ps&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;executeUpdate&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each piece of text is stored along with its vector representation.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔵 Phase 2: Query (RAG Flow)
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Step 1: User Query
&lt;/h4&gt;

&lt;p&gt;"What is OAuth?"&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 2: Convert Query → Embedding
&lt;/h4&gt;

&lt;p&gt;Same process as storing text.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 3: Retrieve Relevant Data
&lt;/h4&gt;

&lt;p&gt;SELECT content&lt;br&gt;
FROM text_embeddings&lt;br&gt;
ORDER BY embedding &amp;lt;-&amp;gt; ?::vector&lt;br&gt;
LIMIT 3;&lt;br&gt;
👉 This finds the most similar text chunks&lt;/p&gt;
&lt;h4&gt;
  
  
  Key Class: Retriever.java
&lt;/h4&gt;

&lt;p&gt;This is the R (Retrieval) in RAG.&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;PreparedStatement&lt;/span&gt; &lt;span class="n"&gt;ps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;prepareStatement&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
            &lt;span class="sh"&gt;"""
            SELECT content
            FROM text_embeddings
            ORDER BY embedding &amp;lt;-&amp;gt; ?::vector
            LIMIT ?
            """&lt;/span&gt;
        &lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;ps&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;ps&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setInt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;topK&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="nc"&gt;ResultSet&lt;/span&gt; &lt;span class="n"&gt;rs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ps&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;executeQuery&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Step 4: Generate Answer Using LLM
&lt;/h4&gt;

&lt;p&gt;We pass retrieved data to the LLM:&lt;/p&gt;

&lt;p&gt;Context:&lt;br&gt;
OAuth 2.0 is an authorization framework...&lt;/p&gt;

&lt;p&gt;Question:&lt;br&gt;
What is OAuth?&lt;/p&gt;

&lt;p&gt;👉 The LLM generates a clean answer.&lt;/p&gt;
&lt;h4&gt;
  
  
  Key Class: LLMService.java
&lt;/h4&gt;

&lt;p&gt;This is the G (Generation) in RAG.&lt;br&gt;
Passing Context to the LLM&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;String&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"""
                        Answer briefly in 2-3 sentences.

                        Context:
                        %s

                        Question:
                        %s
                        """&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;formatted&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We inject retrieved data into the prompt so the LLM generates grounded answers.&lt;/p&gt;

&lt;p&gt;🧪 Sample Output&lt;br&gt;
--- Retrieved Context ---&lt;br&gt;
OAuth 2.0 is an authorization framework.&lt;br&gt;
JWT is used for secure authentication.&lt;/p&gt;

&lt;p&gt;--- Final Answer ---&lt;br&gt;
OAuth is an authorization framework used to grant access to resources...&lt;br&gt;
🧠 What’s Really Happening?&lt;/p&gt;

&lt;p&gt;This is the most important part to understand:&lt;/p&gt;

&lt;p&gt;Component   Role&lt;br&gt;
Database    Stores knowledge&lt;br&gt;
Retriever   Finds relevant information&lt;br&gt;
LLM Generates answer&lt;/p&gt;

&lt;p&gt;👉 The LLM does NOT retrieve data&lt;br&gt;
👉 The database does NOT generate answers&lt;/p&gt;

&lt;h4&gt;
  
  
  💻 Full Code
&lt;/h4&gt;

&lt;p&gt;The project includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;EmbeddingService.java&lt;/li&gt;
&lt;li&gt;StorageService.java&lt;/li&gt;
&lt;li&gt;Retriever.java&lt;/li&gt;
&lt;li&gt;LLMService.java&lt;/li&gt;
&lt;li&gt;RAGApp.java&lt;/li&gt;
&lt;li&gt;pom.xml&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  👉 GitHub Repository
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://github.com/knowledgebase21st/Software-Engineering/tree/dev/AI/RAG" rel="noopener noreferrer"&gt;https://github.com/knowledgebase21st/Software-Engineering/tree/dev/AI/RAG&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  🚀 Why This Approach is Powerful
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Works with your own data&lt;/li&gt;
&lt;li&gt;Reduces hallucination&lt;/li&gt;
&lt;li&gt;Fully offline (with Ollama)&lt;/li&gt;
&lt;li&gt;Production-ready pattern&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  ✅ Conclusion
&lt;/h4&gt;

&lt;p&gt;We built a complete RAG pipeline using Java, PostgreSQL, and Ollama.&lt;/p&gt;

&lt;p&gt;This approach combines:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your data&lt;/li&gt;
&lt;li&gt;Smart retrieval&lt;/li&gt;
&lt;li&gt;LLM reasoning&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Result:&lt;br&gt;
&lt;code&gt;Accurate, context-aware answers using your own knowledge base.&lt;/code&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>postgres</category>
      <category>rag</category>
    </item>
    <item>
      <title>Understanding OAuth2 Flow with a Complete Java Servlet Demo (Step-by-Step)</title>
      <dc:creator>Sanjay Ghosh</dc:creator>
      <pubDate>Wed, 25 Mar 2026 21:30:07 +0000</pubDate>
      <link>https://dev.to/sanjayghosh/understanding-oauth2-flow-with-a-complete-java-servlet-demo-step-by-step-3bai</link>
      <guid>https://dev.to/sanjayghosh/understanding-oauth2-flow-with-a-complete-java-servlet-demo-step-by-step-3bai</guid>
      <description>&lt;p&gt;OAuth2 is everywhere.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“Login with Google”&lt;/li&gt;
&lt;li&gt;“Continue with GitHub”&lt;/li&gt;
&lt;li&gt;“Sign in with Microsoft”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We use it daily—but when it comes to explaining how it actually works, things quickly get confusing.&lt;/p&gt;

&lt;p&gt;Most tutorials either:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Explain only the theory ❌&lt;/li&gt;
&lt;li&gt;Or show isolated code without context ❌&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Very few connect the full &lt;strong&gt;flow end-to-end&lt;/strong&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  🎯 What This Article Does Differently
&lt;/h4&gt;

&lt;p&gt;In this article, we will:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Break down the &lt;strong&gt;4 core actors&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Walk through the &lt;strong&gt;entire OAuth2 flow&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Map each step to &lt;strong&gt;working Java servlet code&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Build a &lt;strong&gt;complete runnable demo&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  🧠 The Key Idea (Read This First)
&lt;/h4&gt;

&lt;p&gt;OAuth2 is &lt;strong&gt;not about authentication&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It is about &lt;strong&gt;delegating access&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of giving your username/password to an application, you allow it to access your data using a &lt;strong&gt;token issued by a trusted server&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔷 Actors in OAuth2
&lt;/h3&gt;

&lt;p&gt;This framework involves four key roles:&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Resource Owner (User)
&lt;/h4&gt;

&lt;p&gt;The user who owns the data&lt;br&gt;
Grants or denies access&lt;/p&gt;
&lt;h4&gt;
  
  
  2. Client (Application)
&lt;/h4&gt;

&lt;p&gt;The application requesting access to user data&lt;/p&gt;
&lt;h4&gt;
  
  
  3. Authorization Server
&lt;/h4&gt;

&lt;p&gt;Authenticates the user&lt;br&gt;
Issues authorization code and access token&lt;/p&gt;
&lt;h4&gt;
  
  
  4. Resource Server
&lt;/h4&gt;

&lt;p&gt;Hosts protected data&lt;br&gt;
Validates access tokens before responding&lt;/p&gt;
&lt;h3&gt;
  
  
  🔷 Real-World Example
&lt;/h3&gt;

&lt;p&gt;A common example is “Login with Google”.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;User&lt;/strong&gt; → You&lt;br&gt;
&lt;strong&gt;Client&lt;/strong&gt; → Airbnb&lt;br&gt;
&lt;strong&gt;Authorization Server&lt;/strong&gt; → Google&lt;br&gt;
&lt;strong&gt;Resource Server&lt;/strong&gt; → Google APIs&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Flow&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You click “Login with Google”&lt;/li&gt;
&lt;li&gt;You are redirected to Google&lt;/li&gt;
&lt;li&gt;You login and click &lt;strong&gt;Allow&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Google sends a **code **to the client&lt;/li&gt;
&lt;li&gt;Client exchanges code for &lt;strong&gt;token&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Client fetches your data using the token&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;👉 This is exactly what we will implement.&lt;/p&gt;
&lt;h3&gt;
  
  
  🔷 High-Level Flow
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Client requests authorization from the user&lt;/li&gt;
&lt;li&gt;User authenticates and grants/denies access&lt;/li&gt;
&lt;li&gt;Authorization Server returns an &lt;strong&gt;authorization code&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Client exchanges code for &lt;strong&gt;access token&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Client uses access token to call Resource Server&lt;/li&gt;
&lt;li&gt;Resource Server validates token and returns data&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  🔷 Endpoints in This Demo
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Endpoint&lt;/th&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;/login&lt;/td&gt;
&lt;td&gt;Starts OAuth flow (Client)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;/authorize&lt;/td&gt;
&lt;td&gt;User login + consent (Authorization Server)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;/callback&lt;/td&gt;
&lt;td&gt;Receives authorization code (Client)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;/getToken&lt;/td&gt;
&lt;td&gt;Helper to call token endpoint&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;/token&lt;/td&gt;
&lt;td&gt;Issues access token&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;/data&lt;/td&gt;
&lt;td&gt;Protected API (Resource Server)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h3&gt;
  
  
  🔷 Full Flow Overview
&lt;/h3&gt;

&lt;p&gt;/login &lt;br&gt;
 → redirect to /authorize&lt;br&gt;
 → user login + allow&lt;br&gt;
 → /callback (gets code)&lt;br&gt;
 → /token (gets access token)&lt;br&gt;
 → /data (uses token)&lt;/p&gt;
&lt;h3&gt;
  
  
  🔷 Step-by-Step Flow with Code
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Full implementation is available in the GitHub repository at the end of this article.&lt;br&gt;
🟢 Step 1: /login → Start Flow&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;LoginServlet.java&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.oauth.demo&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;jakarta.servlet.ServletException&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;jakarta.servlet.annotation.WebServlet&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;jakarta.servlet.http.HttpServlet&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;jakarta.servlet.http.HttpServletRequest&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;jakarta.servlet.http.HttpServletResponse&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;java.io.IOException&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * Servlet implementation class LoginServlet
 */&lt;/span&gt;
&lt;span class="nd"&gt;@WebServlet&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/login"&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;LoginServlet&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;HttpServlet&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;protected&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;doGet&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;HttpServletRequest&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;HttpServletResponse&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;IOException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;redirect&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"http://172.21.236.75:9090/oauth/authorize?"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
                &lt;span class="s"&gt;"response_type=code&amp;amp;client_id=test&amp;amp;redirect_uri=http://172.21.236.75:9090/oauth/callback"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

        &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sendRedirect&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;redirect&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;This is the entry point. It redirects the user to the Authorization Server.&lt;/p&gt;

&lt;p&gt;resp.sendRedirect("&lt;a href="http://host/oauth/authorize?...%22" rel="noopener noreferrer"&gt;http://host/oauth/authorize?..."&lt;/a&gt;); &lt;/p&gt;

&lt;p&gt;👉 This is how the Client requests authorization from the User.&lt;/p&gt;

&lt;p&gt;🟢 Step 2: /authorize → User Login &amp;amp; Consent&lt;/p&gt;

&lt;p&gt;AuthorizeServlet.java&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Displays login form&lt;/li&gt;
&lt;li&gt;Accepts username/password&lt;/li&gt;
&lt;li&gt;Allows user to &lt;strong&gt;Allow **/ **Deny&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&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.oauth.demo&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;jakarta.servlet.ServletException&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;jakarta.servlet.annotation.WebServlet&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;jakarta.servlet.http.HttpServlet&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;jakarta.servlet.http.HttpServletRequest&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;jakarta.servlet.http.HttpServletResponse&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;java.io.IOException&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * Servlet implementation class AuthorizeServlet
 */&lt;/span&gt;
&lt;span class="nd"&gt;@WebServlet&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/authorize"&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;AuthorizeServlet&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;HttpServlet&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;protected&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;doGet&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;HttpServletRequest&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;HttpServletResponse&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;IOException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setContentType&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"text/html"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getWriter&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;write&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"&amp;lt;form method='post'&amp;gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
            &lt;span class="s"&gt;"User: &amp;lt;input name='username'/&amp;gt;&amp;lt;br/&amp;gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
            &lt;span class="s"&gt;"Pass: &amp;lt;input name='password' type='password'/&amp;gt;&amp;lt;br/&amp;gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
            &lt;span class="s"&gt;"&amp;lt;button name='action' value='allow'&amp;gt;Allow&amp;lt;/button&amp;gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
            &lt;span class="s"&gt;"&amp;lt;button name='action' value='deny'&amp;gt;Deny&amp;lt;/button&amp;gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
            &lt;span class="s"&gt;"&amp;lt;input type='hidden' name='redirect_uri' value='"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getParameter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"redirect_uri"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"'/&amp;gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
            &lt;span class="s"&gt;"&amp;lt;/form&amp;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;protected&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;doPost&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;HttpServletRequest&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;HttpServletResponse&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;IOException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getParameter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"action"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;redirectUri&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getParameter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"redirect_uri"&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="s"&gt;"deny"&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sendRedirect&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;redirectUri&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"?error=access_denied"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getParameter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"username"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;pass&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getParameter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"password"&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="s"&gt;"admin"&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="s"&gt;"password"&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pass&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"abc123"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// normally random + stored&lt;/span&gt;
            &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sendRedirect&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;redirectUri&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"?code="&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;code&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="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getWriter&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;write&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Invalid login"&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;👉 Output:&lt;/p&gt;

&lt;p&gt;Success → ?code=abc123&lt;br&gt;
Failure → ?error=access_denied&lt;/p&gt;

&lt;p&gt;🟢 Step 3: /callback → Client Receives Code&lt;/p&gt;

&lt;p&gt;CallbackServlet.java&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.oauth.demo&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;jakarta.servlet.ServletException&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;jakarta.servlet.annotation.WebServlet&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;jakarta.servlet.http.HttpServlet&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;jakarta.servlet.http.HttpServletRequest&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;jakarta.servlet.http.HttpServletResponse&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;java.io.IOException&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * Servlet implementation class CallbackServlet
 */&lt;/span&gt;
&lt;span class="nd"&gt;@WebServlet&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/callback"&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;CallbackServlet&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;HttpServlet&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;protected&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;doGet&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;HttpServletRequest&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;HttpServletResponse&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;IOException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getParameter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"code"&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;code&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getWriter&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;write&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Authorization failed"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setContentType&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"text/html"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getWriter&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;write&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"&amp;lt;h3&amp;gt;Authorization Code: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"&amp;lt;/h3&amp;gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
            &lt;span class="s"&gt;"&amp;lt;a href='/oauth/getToken?code="&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"'&amp;gt;Get Access Token&amp;lt;/a&amp;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;👉 This is the authorization code, a temporary credential.&lt;/p&gt;

&lt;p&gt;🟢 Step 4: /getToken → Prepare Token Request&lt;/p&gt;

&lt;p&gt;GetTokenServlet.java&lt;/p&gt;

&lt;p&gt;Creates a form to call /token:&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.oauth.demo&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;jakarta.servlet.ServletException&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;jakarta.servlet.annotation.WebServlet&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;jakarta.servlet.http.HttpServlet&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;jakarta.servlet.http.HttpServletRequest&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;jakarta.servlet.http.HttpServletResponse&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;java.io.IOException&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * Servlet implementation class GetTokenServlet
 */&lt;/span&gt;
&lt;span class="nd"&gt;@WebServlet&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/getToken"&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;GetTokenServlet&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;HttpServlet&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;protected&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;doGet&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;HttpServletRequest&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;HttpServletResponse&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;IOException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getParameter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"code"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setContentType&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"text/html"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getWriter&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;write&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"&amp;lt;form method='post' action='/oauth/token'&amp;gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
            &lt;span class="s"&gt;"&amp;lt;input name='code' value='"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"'/&amp;gt;&amp;lt;br/&amp;gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
            &lt;span class="s"&gt;"&amp;lt;input name='client_id' value='test'/&amp;gt;&amp;lt;br/&amp;gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
            &lt;span class="s"&gt;"&amp;lt;input name='client_secret' value='secret123'/&amp;gt;&amp;lt;br/&amp;gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
            &lt;span class="s"&gt;"&amp;lt;button type='submit'&amp;gt;Exchange Code for Token&amp;lt;/button&amp;gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
            &lt;span class="s"&gt;"&amp;lt;/form&amp;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;👉 In real systems, this happens server-to-server, not via UI.&lt;/p&gt;

&lt;p&gt;🟢 Step 5: /token → Exchange Code for Token&lt;/p&gt;

&lt;p&gt;TokenServlet.java&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.oauth.demo&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;jakarta.servlet.ServletException&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;jakarta.servlet.annotation.WebServlet&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;jakarta.servlet.http.HttpServlet&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;jakarta.servlet.http.HttpServletRequest&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;jakarta.servlet.http.HttpServletResponse&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;java.io.IOException&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * Servlet implementation class TokenServlet
 */&lt;/span&gt;
&lt;span class="nd"&gt;@WebServlet&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/token"&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;TokenServlet&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;HttpServlet&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;protected&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;doPost&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;HttpServletRequest&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;HttpServletResponse&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;IOException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;clientId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getParameter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"client_id"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;clientSecret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getParameter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"client_secret"&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="s"&gt;"test"&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;clientId&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="s"&gt;"secret123"&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;clientSecret&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setStatus&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;401&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getWriter&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;write&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Invalid client"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;


        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getParameter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"code"&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="s"&gt;"abc123"&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setStatus&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getWriter&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;write&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Invalid code"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// Simple JWT-like token (replace with real JWT later)&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"header.payload.signature"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

        &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setContentType&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"application/json"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getWriter&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;write&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{\"access_token\":\""&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&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;Returns:&lt;br&gt;
{&lt;br&gt;
  "access_token": "header.payload.signature"&lt;br&gt;
}&lt;br&gt;
👉 This is the Access Token&lt;/p&gt;

&lt;p&gt;🟢 Step 6: /data → Access Protected Resource&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;DataServlet&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;java&lt;/span&gt;
&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.oauth.demo&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;jakarta.servlet.ServletException&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;jakarta.servlet.annotation.WebServlet&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;jakarta.servlet.http.HttpServlet&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;jakarta.servlet.http.HttpServletRequest&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;jakarta.servlet.http.HttpServletResponse&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;java.io.IOException&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * Servlet implementation class DataServlet
 */&lt;/span&gt;
&lt;span class="nd"&gt;@WebServlet&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/data"&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;DataServlet&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;HttpServlet&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;protected&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;doGet&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;HttpServletRequest&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;HttpServletResponse&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;IOException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;auth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getHeader&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Authorization"&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;auth&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;auth&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;startsWith&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Bearer "&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setStatus&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;401&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getWriter&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;write&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Unauthorized"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;auth&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;substring&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;7&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="s"&gt;"header.payload.signature"&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setStatus&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;403&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getWriter&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;write&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Invalid token"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getWriter&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;write&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Secure Data for user: admin"&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;👉 Client must call:&lt;br&gt;
Authorization: Bearer header.payload.signature&lt;/p&gt;

&lt;p&gt;If valid:&lt;br&gt;
Secure Data for user: admin&lt;/p&gt;

&lt;h3&gt;
  
  
  🔷 What is the Access Token in this Demo?
&lt;/h3&gt;

&lt;p&gt;In OAuth2, the access token is just a string. The specification does not enforce any particular format.&lt;/p&gt;

&lt;p&gt;However, in most real-world systems, the access token is implemented as a JWT (JSON Web Token).&lt;/p&gt;

&lt;p&gt;In this demo, we return a simplified token:&lt;/p&gt;

&lt;p&gt;header.payload.signature&lt;/p&gt;

&lt;p&gt;This mimics the structure of a JWT.&lt;/p&gt;

&lt;p&gt;👉 For a detailed explanation of how JWT works (structure, signing, validation), you can refer to my earlier article:&lt;/p&gt;

&lt;p&gt;Understanding JWT Authentication in Java with Encryption and Decryption&lt;br&gt;
(&lt;a href="https://dev.to/sanjayghosh/understanding-jwt-authentication-in-java-with-encryption-and-decryption-2ig7"&gt;https://dev.to/sanjayghosh/understanding-jwt-authentication-in-java-with-encryption-and-decryption-2ig7&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;In a production system:&lt;/p&gt;

&lt;p&gt;The Authorization Server generates a signed JWT&lt;br&gt;
The Resource Server validates the JWT before granting access&lt;/p&gt;

&lt;p&gt;This bridges the gap between OAuth2 (authorization framework) and JWT (token format).&lt;/p&gt;

&lt;h3&gt;
  
  
  🔷 Why This Flow Exists
&lt;/h3&gt;

&lt;p&gt;Why not just send username/password to the client?&lt;br&gt;
Because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Security risks ❌&lt;/li&gt;
&lt;li&gt;Third-party access problems ❌&lt;/li&gt;
&lt;li&gt;No control over permissions ❌&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;OAuth2 solves this using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tokens&lt;/li&gt;
&lt;li&gt;Delegated access&lt;/li&gt;
&lt;li&gt;Controlled permissions&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🔷 Common Mistakes
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;❌ Client handling user credentials&lt;/li&gt;
&lt;li&gt;❌ Confusing code vs token&lt;/li&gt;
&lt;li&gt;❌ Sending token in URL&lt;/li&gt;
&lt;li&gt;❌ Thinking client validates token&lt;/li&gt;
&lt;li&gt;❌ Skipping redirect-based flow
### 🔷 Important Notes&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  ⚠️ 1. This is a simplified demo
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Hardcoded values&lt;/li&gt;
&lt;li&gt;No database&lt;/li&gt;
&lt;li&gt;No real token security&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  ⚠️ 2. Token is NOT a real JWT
&lt;/h4&gt;

&lt;p&gt;header.payload.signature&lt;/p&gt;

&lt;p&gt;👉 In real systems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Token is a JWT&lt;/li&gt;
&lt;li&gt;Signed and verified&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  ⚠️ 3. Client Secret should NOT be exposed
&lt;/h4&gt;

&lt;p&gt;In this demo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Shown in UI ❌&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In real OAuth:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Used only in backend communication ✅&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  ⚠️ 4. Browser cannot send Authorization headers directly
&lt;/h4&gt;

&lt;p&gt;Use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;curl&lt;/li&gt;
&lt;li&gt;Postman&lt;/li&gt;
&lt;li&gt;Java client&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  ⚠️ 5. Resource Server must validate token
&lt;/h4&gt;

&lt;p&gt;In real systems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Verify signature&lt;/li&gt;
&lt;li&gt;Check expiry&lt;/li&gt;
&lt;li&gt;Validate issuer&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  🔷 Key Takeaways
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;OAuth2 is about delegation of access&lt;/li&gt;
&lt;li&gt;Client never sees user password&lt;/li&gt;
&lt;li&gt;Authorization Server issues tokens&lt;/li&gt;
&lt;li&gt;Resource Server enforces access&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now that you understand the complete flow, let’s run it.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔷 Try It Yourself
&lt;/h3&gt;

&lt;p&gt;If you want to understand OAuth2 deeply, I highly recommend running this demo locally.&lt;/p&gt;

&lt;p&gt;👉 GitHub Repository (complete working example with all servlets and configuration):&lt;br&gt;&lt;br&gt;
&lt;a href="https://github.com/knowledgebase21st/Software-Engineering/tree/dev/security/OAUTH" rel="noopener noreferrer"&gt;https://github.com/knowledgebase21st/Software-Engineering/tree/dev/security/OAUTH&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Steps:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Clone the repository
&lt;/li&gt;
&lt;li&gt;Deploy it in Tomcat
&lt;/li&gt;
&lt;li&gt;Open &lt;code&gt;/login&lt;/code&gt; in your browser
&lt;/li&gt;
&lt;li&gt;Follow the complete OAuth2 flow step by step
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Hands-on practice will make the concepts much clearer than theory alone.&lt;br&gt;
If you run into any issues while trying this locally, feel free to leave a comment—I’ll be happy to help.&lt;/p&gt;

&lt;h3&gt;
  
  
  🏁 Conclusion
&lt;/h3&gt;

&lt;p&gt;OAuth2 may seem complex at first—but the core idea is simple:&lt;br&gt;
👉 The client never gets your password&lt;br&gt;
👉 The Authorization Server issues a token&lt;br&gt;
👉 The Resource Server trusts that token&lt;/p&gt;

&lt;h3&gt;
  
  
  🔑 What You Built
&lt;/h3&gt;

&lt;p&gt;You implemented:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Client&lt;/li&gt;
&lt;li&gt;Authorization Server&lt;/li&gt;
&lt;li&gt;Resource Server&lt;/li&gt;
&lt;li&gt;Complete OAuth2 flow
This is the same pattern used by Google and Microsoft.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🔗 OAuth2 + JWT
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;OAuth2 = how you get the token&lt;/li&gt;
&lt;li&gt;JWT = what the token contains&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ⚠️ Production Note
&lt;/h3&gt;

&lt;p&gt;Use tools like Keycloak or frameworks like Spring Boot for real systems.&lt;/p&gt;

</description>
      <category>java</category>
      <category>security</category>
      <category>webdev</category>
      <category>oauth</category>
    </item>
    <item>
      <title>Understanding JWT Authentication in Java with Encryption and Decryption</title>
      <dc:creator>Sanjay Ghosh</dc:creator>
      <pubDate>Thu, 19 Mar 2026 20:19:51 +0000</pubDate>
      <link>https://dev.to/sanjayghosh/understanding-jwt-authentication-in-java-with-encryption-and-decryption-2ig7</link>
      <guid>https://dev.to/sanjayghosh/understanding-jwt-authentication-in-java-with-encryption-and-decryption-2ig7</guid>
      <description>&lt;p&gt;JSON Web Token (JWT) is a widely used mechanism for securely transmitting information between systems.&lt;/p&gt;

&lt;p&gt;JWT is commonly used in:&lt;br&gt;
• API authentication&lt;br&gt;
• Single Sign-On (SSO)&lt;br&gt;
• Microservices communication&lt;/p&gt;

&lt;p&gt;This article explains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What JWT is&lt;/li&gt;
&lt;li&gt;JWT structure&lt;/li&gt;
&lt;li&gt;How encryption and signing works&lt;/li&gt;
&lt;li&gt;How to generate and validate JWT in Java&lt;/li&gt;
&lt;li&gt;A simple diagram explaining the flow&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  What is JWT?
&lt;/h2&gt;

&lt;p&gt;JWT (JSON Web Token) is a compact, URL-safe token format used to securely transmit information between two parties. &lt;a href="https://datatracker.ietf.org/doc/html/rfc7519" rel="noopener noreferrer"&gt;Refer RFC7519&lt;/a&gt; .&lt;/p&gt;

&lt;p&gt;A JWT contains claims (information) that are digitally signed and optionally encrypted.&lt;/p&gt;

&lt;p&gt;JWT tokens are typically used after a user logs in successfully. The server generates a token and sends it back to the client. The client includes this token in future requests for authentication.&lt;/p&gt;
&lt;h2&gt;
  
  
  JWT Structure
&lt;/h2&gt;

&lt;p&gt;JWT Structure&lt;/p&gt;

&lt;p&gt;A JWT consists of three parts separated by dots:&lt;/p&gt;

&lt;p&gt;HEADER.PAYLOAD.SIGNATURE&lt;/p&gt;

&lt;p&gt;Example JWT:&lt;/p&gt;

&lt;p&gt;eyJhbGciOiJIUzI1NiJ9&lt;br&gt;
.&lt;br&gt;
eyJpc3MiOiJteS5jb21wYW55LmNvbSIsInN1YiI6ImpvaG4uZG9lIiwiaWF0IjoxNzczMTg0MTIwLCJleHAiOjE3NzMxODQ0MjAsImp0aSI6IjI1Y2JkNjVmLTYzODEtNGZiYi05YWMyLTk4ZTk0ZGYwYTI2YSJ9&lt;br&gt;
.&lt;br&gt;
UEG4iZhhtyG58V0Vcz-IHOL8MMPmDVqZdyRhoaTnYCI&lt;/p&gt;

&lt;p&gt;Each part is Base64URL encoded. ()&lt;/p&gt;
&lt;h3&gt;
  
  
  1. Header
&lt;/h3&gt;

&lt;p&gt;The header contains metadata about the token.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;{"alg":"HS256"}&lt;/p&gt;

&lt;p&gt;alg indicates the algorithm used to sign the token.&lt;/p&gt;

&lt;p&gt;Common algorithms include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HS256&lt;/li&gt;
&lt;li&gt;RS256&lt;/li&gt;
&lt;li&gt;ES256&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  2. Payload
&lt;/h3&gt;

&lt;p&gt;The payload contains claims, which are pieces of information about the user.&lt;br&gt;
Example:&lt;br&gt;
{ &lt;br&gt;
    "iss":"my.company.com",&lt;br&gt;
    "sub":"john.doe","iat":1773184120,&lt;br&gt;
    "exp":1773184420,&lt;br&gt;
    "jti":"25cbd65f-6381-4fbb-9ac2-98e94df0a26a"}&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt;&lt;br&gt;
JWT payload is not encrypted by default. It is only Base64 encoded.&lt;br&gt;
Anyone can decode the payload, but the signature prevents tampering.&lt;/p&gt;
&lt;h3&gt;
  
  
  3. Signature
&lt;/h3&gt;

&lt;p&gt;The signature ensures the token has not been modified.&lt;br&gt;
Example process:&lt;br&gt;
HMACSHA256(&lt;br&gt;
   base64UrlEncode(header) + "." +&lt;br&gt;
   base64UrlEncode(payload),&lt;br&gt;
   secret&lt;br&gt;
)&lt;br&gt;
If someone modifies the payload, the signature verification will fail.&lt;/p&gt;
&lt;h2&gt;
  
  
  JWT Authentication Flow
&lt;/h2&gt;

&lt;p&gt;Typical authentication flow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;User logs in with username and password&lt;/li&gt;
&lt;li&gt;Server validates credentials&lt;/li&gt;
&lt;li&gt;Server generates a JWT&lt;/li&gt;
&lt;li&gt;Client stores the token&lt;/li&gt;
&lt;li&gt;Client sends JWT in Authorization header&lt;/li&gt;
&lt;li&gt;Server verifies the token&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Example header in API request:&lt;/p&gt;

&lt;p&gt;Authorization: Bearer &lt;/p&gt;
&lt;h2&gt;
  
  
  Generating JWT in java
&lt;/h2&gt;

&lt;p&gt;(Example Code)&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;jwt&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;io.jsonwebtoken.Jwts&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;io.jsonwebtoken.security.Keys&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;java.security.Key&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;java.time.Instant&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;java.time.temporal.ChronoUnit&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;java.util.Date&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;java.util.UUID&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;java.nio.charset.StandardCharsets&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;JwtTokenGenerator&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="cm"&gt;/**
     * Generates a signed JWT token using a shared secret key.
     * @param issuer The issuer of the token.
     * @param subject The subject of the token (e.g., user ID).
     * @param secretKey The secret key for signing (must be at least 256 bits).
     * @return The compact JWT string.
     */&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;generateJwtToken&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;issuer&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;subject&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;secretKey&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Define the key from the secret string&lt;/span&gt;
        &lt;span class="c1"&gt;// The key should be securely managed and stored&lt;/span&gt;
        &lt;span class="nc"&gt;Key&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Keys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;hmacShaKeyFor&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;secretKey&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getBytes&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;StandardCharsets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;UTF_8&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

        &lt;span class="nc"&gt;Instant&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Instant&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;now&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="c1"&gt;// Build the JWT&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;jwt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Jwts&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;setIssuer&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;issuer&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Set the issuer claim&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setSubject&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;subject&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Set the subject claim&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setIssuedAt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;from&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;// Set the issued at time&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setExpiration&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;from&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;plus&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5L&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;ChronoUnit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;MINUTES&lt;/span&gt;&lt;span class="o"&gt;)))&lt;/span&gt; &lt;span class="c1"&gt;// Set expiration for 5 minutes later&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setId&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;UUID&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;randomUUID&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="c1"&gt;// Set a unique ID for the token&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;signWith&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Sign the JWT with the key&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;compact&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Compacts the JWT into its final string form&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;jwt&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="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="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="c1"&gt;// Example usage: replace with your actual values&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;myIssuer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"my.company.com"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;mySubject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"john.doe"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="c1"&gt;// Key must be sufficiently long for HS256 (e.g., 32 characters or more for 256 bits)&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;mySecretKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"aVerySecureAndLongSecretKeyForSigningJwts"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;generateJwtToken&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;myIssuer&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mySubject&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mySecretKey&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Generated JWT Token:"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token&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;The above code will create the token. &lt;/p&gt;

&lt;p&gt;Validating JWT in Java&lt;br&gt;
Example Code&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;jwt&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;io.jsonwebtoken.Claims&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;io.jsonwebtoken.Jwts&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;io.jsonwebtoken.security.Keys&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;java.nio.charset.StandardCharsets&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;JWTValidation&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;SECRET_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"aVerySecureAndLongSecretKeyForSigningJwts"&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;Claims&lt;/span&gt; &lt;span class="nf"&gt;validate&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;token&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;Jwts&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;parser&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;verifyWith&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Keys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;hmacShaKeyFor&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;SECRET_KEY&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getBytes&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;StandardCharsets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;UTF_8&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="na"&gt;parseSignedClaims&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;getPayload&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="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="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;lt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Please provide the token String as a parameter"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
            &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;tokenString&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="nc"&gt;Claims&lt;/span&gt; &lt;span class="n"&gt;claims&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;validate&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tokenString&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Subject: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;claims&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getSubject&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Issuer: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;claims&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getIssuer&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Issued At: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;claims&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getIssuedAt&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Expiration: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;claims&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getExpiration&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"ID: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;claims&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getId&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Audience: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;claims&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getAudience&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;By running the above code you can pass the generated token to test the validity. &lt;/p&gt;

&lt;p&gt;Decoding JWT &lt;br&gt;
Java Example&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;jwt&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;java.nio.charset.StandardCharsets&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;java.util.Base64&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;JWTTokenDecoder&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;decodeJWT&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;)&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="n"&gt;parts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;split&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&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;parts&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;!=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;IllegalArgumentException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Invalid JWT token format"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="nc"&gt;Base64&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Decoder&lt;/span&gt; &lt;span class="n"&gt;decoder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Base64&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getUrlDecoder&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="c1"&gt;// Decode Header&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;header&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;String&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;decoder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;decode&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parts&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="nc"&gt;StandardCharsets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;UTF_8&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"JWT Header: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;header&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Decode Payload (Body)&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;payload&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;String&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;decoder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;decode&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parts&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;]),&lt;/span&gt; &lt;span class="nc"&gt;StandardCharsets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;UTF_8&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"JWT Body: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// The signature part (parts[2]) is a hash and cannot be "decoded" into a readable string in the same way.&lt;/span&gt;
        &lt;span class="c1"&gt;// It's used for signature verification.&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="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;lt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Please provide the token String as a parameter"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
            &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;jwtToken&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="n"&gt;decodeJWT&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jwtToken&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;You can pass the JWT and get the decoded value&lt;/p&gt;

&lt;h2&gt;
  
  
  JWT Encryption vs Signing
&lt;/h2&gt;

&lt;p&gt;Many developers confuse signing and encryption.&lt;br&gt;
Signing ensures:&lt;br&gt;
• Token integrity&lt;br&gt;
• Token authenticity&lt;/p&gt;

&lt;p&gt;Encryption ensures:&lt;br&gt;
• Token confidentiality&lt;/p&gt;

&lt;p&gt;Most JWT tokens are &lt;strong&gt;signed but not encrypted&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Security Best Practices
&lt;/h2&gt;

&lt;p&gt;When using JWT in production:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Never store sensitive data in payload&lt;/li&gt;
&lt;li&gt;Always use HTTPS&lt;/li&gt;
&lt;li&gt;Set token expiration (exp claim) Refer: &lt;a href="https://javadoc.io/doc/io.jsonwebtoken/jjwt-api/0.11.2/io/jsonwebtoken/Claims.html" rel="noopener noreferrer"&gt;Claims    &lt;/a&gt;, &lt;a href="https://javadoc.io/static/io.jsonwebtoken/jjwt-api/0.11.2/io/jsonwebtoken/Claims.html#setExpiration(java.util.Date)" rel="noopener noreferrer"&gt;setExpiration&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Rotate secret keys periodically&lt;/li&gt;
&lt;li&gt;Validate token signature on every request&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  When Should You Use JWT?
&lt;/h2&gt;

&lt;p&gt;JWT works well when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Building stateless APIs&lt;/li&gt;
&lt;li&gt;Implementing microservices authentication&lt;/li&gt;
&lt;li&gt;Creating Single Sign-On systems&lt;/li&gt;
&lt;li&gt;Protecting REST APIs&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Source Code
&lt;/h2&gt;

&lt;p&gt;All source files are available on GitHub:&lt;br&gt;
&lt;a href="https://github.com/knowledgebase21st/Software-Engineering/tree/dev/security/JWT" rel="noopener noreferrer"&gt;Github source codes&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;JWT provides a simple and secure way to transmit claims between systems.&lt;/p&gt;

&lt;p&gt;Understanding how JWT works internally, including header, payload, and signature is important when implementing authentication systems in modern applications.&lt;/p&gt;

&lt;p&gt;By using proper signing, validation, and expiration strategies, JWT can be a powerful tool for secure API authentication.&lt;/p&gt;

</description>
      <category>java</category>
      <category>security</category>
      <category>jwt</category>
      <category>authentication</category>
    </item>
    <item>
      <title>Keystore vs Truststore — How SSL Certificate Chain Actually Works (with java Examples)</title>
      <dc:creator>Sanjay Ghosh</dc:creator>
      <pubDate>Sun, 15 Mar 2026 20:18:35 +0000</pubDate>
      <link>https://dev.to/sanjayghosh/keystore-vs-truststore-how-ssl-certificate-chain-actually-works-with-java-examples-3hj5</link>
      <guid>https://dev.to/sanjayghosh/keystore-vs-truststore-how-ssl-certificate-chain-actually-works-with-java-examples-3hj5</guid>
      <description>&lt;p&gt;When you see the 🔒 HTTPS lock icon in your browser, something important has already happened behind the scenes.&lt;/p&gt;

&lt;p&gt;Your browser has verified:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The identity of the server&lt;/li&gt;
&lt;li&gt;The certificate chain&lt;/li&gt;
&lt;li&gt;The trusted Certificate Authority&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But where are these certificates stored?&lt;br&gt;
And how does the verification actually work?&lt;/p&gt;

&lt;p&gt;This is where Keystore and Truststore come in.&lt;/p&gt;

&lt;p&gt;In this article we will cover:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What a Keystore is&lt;/li&gt;
&lt;li&gt;What a Truststore is&lt;/li&gt;
&lt;li&gt;How the certificate chain works&lt;/li&gt;
&lt;li&gt;How they are used during the TLS handshake&lt;/li&gt;
&lt;li&gt;Examples using keytool&lt;/li&gt;
&lt;li&gt;Common SSL handshake errors&lt;/li&gt;
&lt;li&gt;A quick look at Mutual TLS (mTLS) (two-way TLS (or two-way SSL) &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🧾 Certificate Creation Flow
&lt;/h2&gt;

&lt;p&gt;Before talking about keystore and truststore, let's see how a certificate is created.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The server generates a public/private key pair.&lt;/li&gt;
&lt;li&gt;It creates a CSR (Certificate Signing Request).&lt;/li&gt;
&lt;li&gt;The CSR is sent to a Certificate Authority (CA).&lt;/li&gt;
&lt;li&gt;The CA verifies the identity of the organization.&lt;/li&gt;
&lt;li&gt;The CA issues a leaf certificate.&lt;/li&gt;
&lt;li&gt;The certificate is signed by an Intermediate CA.&lt;/li&gt;
&lt;li&gt;The intermediate CA is signed by a Root CA.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This produces a certificate chain.&lt;br&gt;
Example chain:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Root CA&lt;br&gt;
   ↓&lt;br&gt;
Intermediate CA 1&lt;br&gt;
   ↓&lt;br&gt;
Intermediate CA 2&lt;br&gt;
   ↓&lt;br&gt;
Leaf Certificate (Server Certificate)&lt;/code&gt;&lt;br&gt;
Each certificate is digitally signed by the one above it.&lt;/p&gt;

&lt;h2&gt;
  
  
  🏪 What is a Truststore?
&lt;/h2&gt;

&lt;p&gt;A Truststore is a secure repository that contains certificates from trusted entities.&lt;/p&gt;

&lt;p&gt;These certificates are used to verify the identity of remote systems during secure communication.&lt;/p&gt;

&lt;p&gt;A truststore typically contains:&lt;/p&gt;

&lt;h3&gt;
  
  
  Trusted Root Certificates
&lt;/h3&gt;

&lt;p&gt;These are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Self-signed certificates&lt;/li&gt;
&lt;li&gt;Issued by trusted Certificate Authorities&lt;/li&gt;
&lt;li&gt;Preinstalled in operating systems, browsers, or Java runtimes&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Intermediate CA Certificates
&lt;/h3&gt;

&lt;p&gt;Intermediate certificates help bridge the chain of trust between a root CA and the server certificate.&lt;/p&gt;

&lt;h3&gt;
  
  
  🎯 Purpose of Truststore
&lt;/h3&gt;

&lt;p&gt;The truststore is used to validate certificates presented by other parties.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
When a browser connects to:&lt;br&gt;
&lt;code&gt;https://myserver.com&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The browser:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Receives the server’s certificate&lt;/li&gt;
&lt;li&gt;Builds the certificate chain&lt;/li&gt;
&lt;li&gt;Verifies the chain up to a trusted root certificate in its truststore&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If the verification succeeds, the connection is trusted.&lt;br&gt;
If not, the browser displays a certificate warning.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔑 What is a Keystore?
&lt;/h2&gt;

&lt;p&gt;A Keystore is a secure repository that stores your own cryptographic identity.&lt;/p&gt;

&lt;p&gt;It usually contains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Server private key&lt;/li&gt;
&lt;li&gt;Server leaf certificate&lt;/li&gt;
&lt;li&gt;Sometimes intermediate certificates&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;Note: The private key stored in the keystore corresponds to the leaf certificate of the server.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The private key is used during the TLS handshake to &lt;strong&gt;prove ownership of the certificate&lt;/strong&gt;.&lt;br&gt;
It must &lt;strong&gt;never be shared&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔄 How Keystore and Truststore Work Together
&lt;/h2&gt;

&lt;p&gt;During the TLS handshake:&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 1 — Client connects to server
&lt;/h4&gt;

&lt;p&gt;The client initiates a secure connection.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 2 — Server sends certificate chain
&lt;/h4&gt;

&lt;p&gt;The server sends:&lt;br&gt;
&lt;code&gt;Leaf Certificate&lt;br&gt;
Intermediate Certificates&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 3 — Client validates the chain
&lt;/h4&gt;

&lt;p&gt;The client verifies:&lt;br&gt;
&lt;code&gt;Leaf Certificate&lt;br&gt;
   ↓&lt;br&gt;
Intermediate Certificate&lt;br&gt;
   ↓&lt;br&gt;
Root CA&lt;/code&gt;&lt;br&gt;
The &lt;strong&gt;root CA must exist in the client's truststore&lt;/strong&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 4 — Secure connection established
&lt;/h4&gt;

&lt;p&gt;If the certificate chain is valid and trusted, the TLS session is established.&lt;/p&gt;

&lt;h2&gt;
  
  
  ☕ Java Example — Keystore
&lt;/h2&gt;

&lt;p&gt;In Java applications, keystores are commonly stored as:&lt;br&gt;
&lt;code&gt;.jks&lt;br&gt;
.p12&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Create a Keystore
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;keytool -genkeypair \&lt;br&gt;
-alias myserver \&lt;br&gt;
-keyalg RSA \&lt;br&gt;
-keysize 2048 \&lt;br&gt;
-keystore keystore.jks&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This above command generates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A private key&lt;/li&gt;
&lt;li&gt;A self-signed certificate&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  View Keystore Contents
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;keytool -list -v -keystore keystore.jks&lt;/code&gt;&lt;br&gt;
Example output:&lt;br&gt;
&lt;code&gt;Alias name: myserver&lt;br&gt;
Entry type: PrivateKeyEntry&lt;br&gt;
Certificate chain length: 1&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ☕ Java Example — Truststore
&lt;/h2&gt;

&lt;p&gt;Java provides a default truststore which is:&lt;br&gt;
&lt;code&gt;$JAVA_HOME/lib/security/cacerts&lt;/code&gt;&lt;br&gt;
Default password:&lt;br&gt;
&lt;code&gt;changeit&lt;/code&gt;&lt;br&gt;
List certificates in the truststore:&lt;br&gt;
&lt;code&gt;keytool -list -keystore $JAVA_HOME/lib/security/cacerts&lt;/code&gt;&lt;br&gt;
This truststore contains &lt;strong&gt;nearly two hundred trusted CA certificates&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Import Certificate into a Truststore
&lt;/h3&gt;

&lt;p&gt;When the certificate is trusted by the Truststore&lt;br&gt;
Example&lt;br&gt;
&lt;code&gt;keytool -importcert \&lt;br&gt;
-alias myserver \&lt;br&gt;
-file server.crt \&lt;br&gt;
-keystore truststore.jks&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ⚠️ SSL Handshake Errors Related to Certificate Issues
&lt;/h2&gt;

&lt;p&gt;Many SSL handshake failures occur because of certificate chain or trust problems.&lt;br&gt;
Here are some of the most common errors.&lt;/p&gt;

&lt;h4&gt;
  
  
  SSL Handshake Failed / Error 525
&lt;/h4&gt;

&lt;p&gt;This indicates that the &lt;strong&gt;client and server failed to establish a secure connection&lt;/strong&gt;.&lt;br&gt;
A common cause is an &lt;strong&gt;incomplete certificate chain&lt;/strong&gt;, where the server does not send the required intermediate certificates.&lt;/p&gt;

&lt;h4&gt;
  
  
  Certificate Unknown (Java / JSSE)
&lt;/h4&gt;

&lt;p&gt;In Java applications, you may see errors such as:&lt;br&gt;
&lt;code&gt;javax.net.ssl.SSLHandshakeException:&lt;br&gt;
PKIX path building failed&lt;/code&gt;&lt;br&gt;
This means the client &lt;strong&gt;cannot verify the certificate chain&lt;/strong&gt;, usually because the issuing CA is &lt;strong&gt;not present in the truststore&lt;/strong&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  ERR_CERT_AUTHORITY_INVALID (Browser)
&lt;/h4&gt;

&lt;p&gt;Browsers show this error when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The root CA is not trusted&lt;/li&gt;
&lt;li&gt;The intermediate certificate is missing&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The certificate is self-signed&lt;br&gt;
&lt;strong&gt;The certificate chain was issued by an authority that is not trusted&lt;/strong&gt;&lt;br&gt;
This error commonly appears in:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;SQL Server connections&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Internal client-server applications&lt;br&gt;
It occurs when the &lt;strong&gt;client cannot recognize the certificate authority that signed the server certificate&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  SSL error: 0x8009001a (SChannel)
&lt;/h4&gt;

&lt;p&gt;In Windows systems using SChannel, this error usually indicates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An invalid certificate&lt;/li&gt;
&lt;li&gt;A broken certificate chain&lt;/li&gt;
&lt;li&gt;A trust validation failure&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Key Takeaway
&lt;/h4&gt;

&lt;p&gt;Most SSL handshake errors occur because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The client truststore does not trust the CA&lt;/li&gt;
&lt;li&gt;The server did not send the full certificate chain&lt;/li&gt;
&lt;li&gt;The certificate has expired or is invalid
Understanding keystore and truststore helps quickly diagnose these issues.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🔐 Mutual TLS (mTLS) (Or two-way TLS (or two-way SSL)
&lt;/h2&gt;

&lt;p&gt;In standard TLS:&lt;br&gt;
&lt;code&gt;Client verifies Server&lt;/code&gt;&lt;br&gt;
In Mutual TLS (mTLS):&lt;br&gt;
&lt;code&gt;Client verifies Server&lt;br&gt;
Server verifies Client&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Both sides present certificates.&lt;br&gt;
Flow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Client connects to server&lt;/li&gt;
&lt;li&gt;Server presents its certificate&lt;/li&gt;
&lt;li&gt;Client verifies it using its truststore&lt;/li&gt;
&lt;li&gt;Server requests client certificate&lt;/li&gt;
&lt;li&gt;Client sends its certificate&lt;/li&gt;
&lt;li&gt;Server verifies it using its truststore
mTLS is commonly used in:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Microservices architectures&lt;/li&gt;
&lt;li&gt;Banking systems&lt;/li&gt;
&lt;li&gt;Internal APIs&lt;/li&gt;
&lt;li&gt;Zero-trust security environments&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🧠 Summary
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Keystore:&lt;/strong&gt;   Stores private keys and certificates used to prove identity&lt;br&gt;
&lt;strong&gt;Truststore:&lt;/strong&gt; Stores trusted CA certificates used to verify others&lt;br&gt;
&lt;strong&gt;Certificate Chain:&lt;/strong&gt;  Establishes trust from server certificate to a trusted root CA&lt;/p&gt;

&lt;p&gt;Every secure TLS connection depends on this chain of trust.&lt;/p&gt;

&lt;h2&gt;
  
  
  📌 Final Thought
&lt;/h2&gt;

&lt;p&gt;Next time you see the 🔒 lock icon in your browser, remember:&lt;br&gt;
Behind that simple symbol is a complex system involving:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;certificate chains&lt;/li&gt;
&lt;li&gt;keystores&lt;/li&gt;
&lt;li&gt;truststores&lt;/li&gt;
&lt;li&gt;certificate authorities&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;—all working together to ensure secure communication.&lt;/p&gt;

</description>
      <category>truststore</category>
      <category>keystore</category>
      <category>tls</category>
      <category>keytool</category>
    </item>
    <item>
      <title>From Image to Vector: Building Image Similarity Search with Python and MySQL</title>
      <dc:creator>Sanjay Ghosh</dc:creator>
      <pubDate>Sun, 08 Mar 2026 19:24:17 +0000</pubDate>
      <link>https://dev.to/sanjayghosh/from-image-to-vector-building-image-similarity-search-with-python-and-mysql-kol</link>
      <guid>https://dev.to/sanjayghosh/from-image-to-vector-building-image-similarity-search-with-python-and-mysql-kol</guid>
      <description>&lt;p&gt;Modern applications increasingly rely on vector embeddings to search and compare data such as text, images, and audio.&lt;br&gt;
For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;finding visually similar images&lt;/li&gt;
&lt;li&gt;semantic document search&lt;/li&gt;
&lt;li&gt;recommendation systems&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this article we will:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Convert an &lt;strong&gt;image to a vector embedding&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Store the vector in &lt;strong&gt;MySQL&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Compare images using &lt;strong&gt;vector similarity&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Stacks used:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Python&lt;/li&gt;
&lt;li&gt;sentence-transformers&lt;/li&gt;
&lt;li&gt;PyTorch&lt;/li&gt;
&lt;li&gt;MySQL vector support&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Final Result
&lt;/h2&gt;

&lt;p&gt;After storing the vectors in MySQL we can run a similarity query.&lt;br&gt;
Example output:&lt;br&gt;
&lt;code&gt;+------------+-------------+&lt;br&gt;
| image_name | similarity  |&lt;br&gt;
+------------+-------------+&lt;br&gt;
| img/t3.jpg | 1.00        |&lt;br&gt;
| img/t2.jpg | 0.96        |&lt;br&gt;
| img/t1.jpg | 0.96        |&lt;br&gt;
| img/t4.jpg | 0.92        |&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  System Architecture
&lt;/h2&gt;

&lt;p&gt;The overall pipeline is simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An image is processed by a multimodal embedding model&lt;/li&gt;
&lt;li&gt;The model converts the image into a numerical vector&lt;/li&gt;
&lt;li&gt;The vector is stored in MySQL&lt;/li&gt;
&lt;li&gt;SQL queries compute similarity between vectors&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;AI → ML → DL → Neural Networks → LLM&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let’s briefly explain each level.&lt;/p&gt;
&lt;h3&gt;
  
  
  Artificial Intelligence (AI)
&lt;/h3&gt;

&lt;p&gt;Artificial Intelligence refers to systems designed to simulate aspects of human intelligence, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;learning&lt;/li&gt;
&lt;li&gt;reasoning&lt;/li&gt;
&lt;li&gt;decision making&lt;/li&gt;
&lt;li&gt;problem solving&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Early AI systems (often called Good Old-Fashioned AI) did not involve learning. They relied on predefined rules.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Example:&lt;br&gt;
IF humidity &amp;gt; 60% THEN alert&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Machine Learning (ML)
&lt;/h3&gt;

&lt;p&gt;Machine Learning is a subset of AI where systems learn patterns from data rather than being explicitly programmed.&lt;/p&gt;

&lt;p&gt;There are three main types of machine learning:&lt;/p&gt;
&lt;h4&gt;
  
  
  Supervised Learning
&lt;/h4&gt;

&lt;p&gt;Uses labeled data, where each input has a known correct output.&lt;br&gt;
&lt;em&gt;Example: Predicting house prices.&lt;br&gt;
Inputs: house size, location&lt;br&gt;
Output: predicted price&lt;/em&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Unsupervised Learning
&lt;/h4&gt;

&lt;p&gt;The data is not labeled. The system tries to discover patterns or structure in the data on its own.&lt;br&gt;
&lt;em&gt;Example:&lt;br&gt;
Customer purchase behavior analysis.&lt;br&gt;
For instance, the system might detect that customers who buy Product P1 often also buy Product P2.&lt;/em&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Reinforcement Learning
&lt;/h4&gt;

&lt;p&gt;Works through interaction with an environment using a reward/penalty mechanism.&lt;br&gt;
The system learns through trial and error, continuously improving its decisions based on feedback.&lt;br&gt;
An agent interacts with the environment repeatedly to achieve the optimal outcome.&lt;/p&gt;
&lt;h3&gt;
  
  
  Deep Learning (DL)
&lt;/h3&gt;

&lt;p&gt;Deep Learning is a subset of Machine Learning.&lt;br&gt;
It uses multi-layer neural networks to learn complex patterns in large datasets.&lt;br&gt;
Deep learning is especially powerful for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;images&lt;/li&gt;
&lt;li&gt;speech&lt;/li&gt;
&lt;li&gt;language processing&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Neural Networks (NN)
&lt;/h3&gt;

&lt;p&gt;Neural Networks are the core architecture used in deep learning.&lt;br&gt;
They consist of nodes (neurons) organized into layers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Input layer&lt;/li&gt;
&lt;li&gt;Hidden layers&lt;/li&gt;
&lt;li&gt;Output layer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each neuron performs a mathematical operation based on the following equation:&lt;br&gt;
y = Σ (xi * wi) + b&lt;br&gt;
Where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;xi = input value&lt;/li&gt;
&lt;li&gt;wi = weight (importance of the input)&lt;/li&gt;
&lt;li&gt;b = bias (a learnable scalar parameter)&lt;/li&gt;
&lt;li&gt;y = output&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Data flows through the network in a feed-forward manner, and the network learns by adjusting weights during training.&lt;/p&gt;

&lt;p&gt;Types of Neural Networks&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Artificial Neural Networks (ANN)&lt;br&gt;
Basic layered neural networks where information flows in one direction.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Convolutional Neural Networks (CNN)&lt;br&gt;
Designed for image data. CNNs extract spatial features such as:&lt;br&gt;
edges&lt;br&gt;
textures&lt;br&gt;
shapes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Recurrent Neural Networks (RNN)&lt;br&gt;
These networks contain loops and can remember previous inputs. They are commonly used for sequence data such as text or speech.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  Large Language Models (LLM)
&lt;/h3&gt;

&lt;p&gt;Large Language Models are a type of deep learning model trained on massive text datasets.&lt;/p&gt;

&lt;p&gt;They are capable of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;understanding language&lt;/li&gt;
&lt;li&gt;generating human-like text&lt;/li&gt;
&lt;li&gt;producing embeddings for semantic similarity&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Process Overview with practical example
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Convert an image to a vector embedding&lt;/li&gt;
&lt;li&gt;Store the vector in MySQL (version 9.0 or later)&lt;/li&gt;
&lt;li&gt;Run queries to compare vectors&lt;/li&gt;
&lt;li&gt;Identify which images are most similar&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  Environment Setup
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Create a Python Virtual Environment
&lt;/h3&gt;

&lt;p&gt;Install the virtual environment package:&lt;br&gt;
&lt;code&gt;sudo apt install python3.12-venv&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
Create the environment:&lt;br&gt;
&lt;code&gt;python3 -m venv venv&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Activate it&lt;br&gt;
Linux/macOS&lt;br&gt;
&lt;code&gt;source venv/bin/activate&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
Windows&lt;br&gt;
&lt;code&gt;venv\Scripts\activate&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Install Required Libraries
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;pip install sentence-transformers pillow torch&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Create the MySQL Table
&lt;/h2&gt;

&lt;p&gt;Create a table with a vector column (createtable.sql).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    /*This SQL is to create the table with Vector , MySQL Version 9.6.0
     *The size of the Vector is set to (512) ,
     * The INSERT statement has 512 floating point number
     * and this is the correct match for Common Model Source - CLIP / Truncated OpenAI */
    CREATE TABLE image_embeddings (
        id INT PRIMARY KEY AUTO_INCREMENT,
        image_name VARCHAR(255),
        embedding VECTOR(512) -- Example for a 512-dimensional float vector
    );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Python Script: Convert Image to Vector
&lt;/h2&gt;

&lt;p&gt;Write a Python script to convert images into vectors.&lt;br&gt;
(transformer_image-to-vector.py)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import glob
import sys
import os

# Test it!
if len(sys.argv) &amp;gt; 2:
    imageDir = sys.argv[1]
    sqlFilePath = sys.argv[2]
    if os.path.exists(sqlFilePath):
        os.remove(sqlFilePath)
else:
    print("Usage: python3 transformer_image-to-vector.py &amp;lt;image directory&amp;gt; &amp;lt;path of the output sql")
    sys.exit();

from sentence_transformers import SentenceTransformer
from PIL import Image
import json


# 1. Load the CLIP model (this is the modern equivalent of imgbeddings)
# It downloads about 600MB on the first run.
model = SentenceTransformer('clip-ViT-B-32')

#This is the Function to generate the sql from the image and write to a desired file
def get_sql_insert(image_path,file_path_to_write):
    try:
        print("Will write the image {} to file: {}".format(image_path,file_path_to_write))
        # 2. Load and process the image
        img = Image.open(image_path)

        # 3. Generate the vector (embedding)
        # We use .tolist() to turn the math array into a Python list
        embedding = model.encode(img).tolist()

        # 4. Format the list as a string for SQL [0.1, 0.2, ...]
        vector_string = json.dumps(embedding)

        # 5. Create the SQL command
        sql = "--This sql is genrated from the image using  the model SentenceTransformer('clip-ViT-B-32')\n"
        sql = sql + f"INSERT INTO image_embeddings (image_name, embedding) VALUES ('{image_path}', STRING_TO_VECTOR('{vector_string}'));\n"
        with open(file_path_to_write, "a") as file:
            file.write(sql)
        return ("Successfully Wrote the image {} to file: {}".format(image_path,file_path_to_write))

    except Exception as e:
        return f"Error: {e}"

#It will take all the .jpg files from the image directory (First parameter of this python script)
#and write to the desired file (2nd parameter of this python script)
for lst in glob.glob(f"{imageDir}/*.jpg"):
    print(get_sql_insert(lst,sqlFilePath))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Usage:&lt;br&gt;
&lt;code&gt;python3 transformer_image-to-vector.py &amp;lt;image_directory&amp;gt; &amp;lt;output_sql_file&amp;gt;&lt;/code&gt;&lt;br&gt;
The script generates SQL statements that insert vectors into the MySQL table. Run the output SQL file to store the vectors in MySQL Database.&lt;/p&gt;
&lt;h2&gt;
  
  
  Comparing Image Vectors
&lt;/h2&gt;

&lt;p&gt;Once the vectors are stored, we can compare them using vector similarity.&lt;br&gt;
At the moment, some MySQL vector functions are still evolving.&lt;br&gt;
For example, direct usage of VECTOR_DISTANCE() may have limitations in certain versions (9.60).&lt;br&gt;
So we implement custom helper functions.&lt;/p&gt;
&lt;h2&gt;
  
  
  Custom MySQL Functions
&lt;/h2&gt;

&lt;p&gt;Two helper functions are created:&lt;/p&gt;

&lt;p&gt;my_dot_product(vector, vector)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DELIMITER //

CREATE FUNCTION my_dot_product(v1 VECTOR, v2 VECTOR)
RETURNS FLOAT DETERMINISTIC
BEGIN
    DECLARE total FLOAT DEFAULT 0;
    DECLARE i INT DEFAULT 0;
    DECLARE dim INT;
    -- Convert Vector to String, then to JSON
    DECLARE j1 JSON DEFAULT CAST(VECTOR_TO_STRING(v1) AS JSON);
    DECLARE j2 JSON DEFAULT CAST(VECTOR_TO_STRING(v2) AS JSON);

    SET dim = JSON_LENGTH(j1);

    WHILE i &amp;lt; dim DO
        SET total = total + (JSON_EXTRACT(j1, CONCAT('$[', i, ']')) * JSON_EXTRACT(j2, CONCAT('$[', i, ']')));
        SET i = i + 1;
    END WHILE;

    RETURN total;
END //

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

&lt;/div&gt;



&lt;p&gt;my_vec_norm(vector)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DELIMITER //

CREATE FUNCTION my_vec_norm(v VECTOR)
RETURNS FLOAT DETERMINISTIC
BEGIN
    DECLARE total FLOAT DEFAULT 0;
    DECLARE i INT DEFAULT 0;
    DECLARE dim INT;
    DECLARE j JSON DEFAULT CAST(VECTOR_TO_STRING(v) AS JSON);
    DECLARE val FLOAT;

    SET dim = JSON_LENGTH(j);

    WHILE i &amp;lt; dim DO
        SET val = JSON_EXTRACT(j, CONCAT('$[', i, ']'));
        SET total = total + (val * val);
        SET i = i + 1;
    END WHILE;

    RETURN SQRT(total);
END //

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

&lt;/div&gt;



&lt;p&gt;These functions allow us to compute cosine similarity between vectors.&lt;/p&gt;

&lt;h2&gt;
  
  
  Querying Image Similarity
&lt;/h2&gt;

&lt;p&gt;Now we run a query to compare stored images against a target image.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SET @target = STRING_TO_VECTOR('[0.07557862997055054, 0.3899604380130768, -0.149032324552536, 0.06481198966503143, 0.17365998029708862, 0.1696033775806427, -0.009633079171180725, 0.026114463806152344, 0.13283401727676392, -0.048670023679733276, 0.2853511571884155, -0.47713860869407654, 0.3193468451499939, -0.4782599210739136, 0.19979414343833923, -0.4020282030105591, -0.17893710732460022, -0.16028517484664917, 0.11166025698184967, -0.4441247880458832, 0.0721852108836174, -0.015377134084701538, 0.06420326232910156, -0.5317407846450806, 0.011108562350273132, 0.7078717350959778, -0.15541546046733856, 0.06636792421340942, -0.1235189437866211, 0.17564985156059265, -0.2749885618686676, -0.021165557205677032, 0.24020248651504517, 0.4338991641998291, 0.3174438774585724, -0.2427300065755844, -0.15270879864692688, -0.13448885083198547, -0.03258641064167023, 1.4516336917877197, 0.2088334858417511, -0.07482234388589859, -0.060038354247808456, -0.09696637094020844, 0.2288440763950348, -0.45773571729660034, -0.442022442817688, -0.1333482265472412, 0.20572619140148163, 0.022368118166923523, 0.2268296778202057, 0.0717138946056366, -0.18176983296871185, -0.08150641620159149, -0.3742990493774414, -0.08863221853971481, 0.24395513534545898, 0.14680302143096924, 0.45115935802459717, 0.07179692387580872, 0.13299871981143951, -0.6536737680435181, -0.10842005163431168, 0.46789559721946716, -0.09359163045883179, -0.029734283685684204, -0.4210904538631439, 0.44143062829971313, -0.2495618760585785, 0.16764293611049652, -0.0010016188025474548, 0.12750700116157532, -0.09728701412677765, -0.33462393283843994, -0.19563797116279602, 0.38896551728248596, -0.07021686434745789, 0.05845819413661957, -0.2159923017024994, 0.22142955660820007, 0.08275012671947479, 0.08141633123159409, 0.011051833629608154, -0.0470392107963562, 0.2281772345304489, 0.1281975507736206, -0.2673131823539734, 0.09869228303432465, -0.46927496790885925, 0.5890671014785767, -0.26286429166793823, 0.029046714305877686, -6.433596611022949, 0.8787387609481812, -0.3467825651168823, 0.3790345788002014, 0.04438466578722, 0.651203453540802, -0.34149351716041565, -0.8458610773086548, 0.034017741680145264, -0.2053813338279724, 0.35773321986198425, 0.04032140225172043, 0.30020737648010254, -0.20292143523693085, -0.6659493446350098, -0.14945490658283234, -0.08128952980041504, 0.037803277373313904, -0.24363872408866882, -0.5452983975410461, -0.15123391151428223, 0.06196553260087967, 0.0037244856357574463, 0.37201881408691406, 0.3830801248550415, 0.038900259882211685, 0.5477883815765381, -0.2165623903274536, -0.12358544021844864, 0.6665405035018921, 0.08692356944084167, -0.7012655138969421, -0.2776182293891907, -0.10287892073392868, -0.16323958337306976, 0.29088079929351807, 0.17843754589557648, -0.041389890015125275, -0.206215500831604, 0.8713011741638184, 0.10298433899879456, 0.8146358132362366, 0.5424628257751465, 0.2975153625011444, -0.013563252985477448, 0.13421256840229034, -0.3498159945011139, -0.3292694687843323, -0.2611740529537201, 0.026821553707122803, -0.4656805992126465, 0.733379602432251, 0.09556902945041656, 0.031042248010635376, 0.3466207981109619, 0.470894992351532, -0.24531006813049316, 0.09481766074895859, -0.07527203112840652, -0.3095394968986511, 0.6393522024154663, -0.09749913960695267, -0.11673454940319061, -0.17871969938278198, -0.1564812809228897, 0.2511930465698242, -0.13378417491912842, 0.17615115642547607, -0.06127139925956726, -0.04496309161186218, -0.35364609956741333, -0.08319900929927826, 0.14410080015659332, -0.2627147138118744, 0.9161733388900757, 0.37756675481796265, 0.1632954180240631, 0.0905647948384285, -0.10490548610687256, 0.33364954590797424, -0.05363786220550537, -0.6529805064201355, 0.26767054200172424, 0.26338034868240356, -1.0595732927322388, -0.22944216430187225, -0.26375362277030945, -0.1988820880651474, -0.12509888410568237, 0.24070680141448975, -0.2588941156864166, -0.33498746156692505, 0.126882404088974, 0.17642360925674438, 0.040883928537368774, -0.0052263736724853516, -0.16343313455581665, 0.0562138706445694, 0.2096858024597168, 0.09584870934486389, -0.11106163263320923, 0.1729261875152588, 0.20461152493953705, 0.12263501435518265, 0.27892982959747314, -0.6255460381507874, -0.764202892780304, 0.14997950196266174, 0.16245627403259277, -0.37481117248535156, -0.06923999637365341, 0.6191018223762512, -0.2948871850967407, 0.261602520942688, -0.04764917492866516, -0.15079966187477112, -0.5841816067695618, 0.21257054805755615, -0.21506810188293457, -0.04135539382696152, 0.5817644596099854, 0.12262402474880219, 0.42174848914146423, 0.1265665739774704, 0.01666194200515747, 0.13379910588264465, -0.5832018256187439, -0.3252071738243103, 0.22216439247131348, 0.4046194851398468, 0.20799392461776733, -0.07600507140159607, -0.3153631389141083, -0.10026045888662338, 0.2151670753955841, -0.15998244285583496, -0.498496949672699, -0.04490187019109726, -0.3262564539909363, 0.2954603433609009, -0.07442381978034973, 0.24110326170921326, 0.17248889803886414, 0.45136961340904236, 0.13689523935317993, -0.4876601994037628, 0.050953567028045654, -0.5781422853469849, 0.39940330386161804, 0.08282990008592606, 0.12615060806274414, -0.29397282004356384, -0.1800389140844345, 0.6491589546203613, -0.46026864647865295, 0.35799282789230347, -0.2924331724643707, -0.43013110756874084, -0.3808341324329376, 0.55094313621521, 0.03232079744338989, -0.462185800075531, -0.313692569732666, 0.07338142395019531, 0.16393449902534485, -0.039127856492996216, 0.6098682880401611, -0.16981320083141327, -0.35463374853134155, -0.4267345666885376, -0.09102936089038849, 1.8269031047821045, 0.20107018947601318, 0.15080709755420685, 0.3966326117515564, 0.14836283028125763, 0.43229472637176514, -0.12651363015174866, 0.008955806493759155, -0.02638685703277588, 0.13089591264724731, 0.07453787326812744, -0.26478222012519836, -0.22489425539970398, 0.24618230760097504, 0.17845292389392853, -0.0707186758518219, -0.062373995780944824, -0.06923562288284302, 0.47168073058128357, -0.07979298382997513, -0.07240656018257141, 0.20423418283462524, 0.4307517111301422, -0.9086780548095703, 0.40964275598526, -0.23126669228076935, -0.28451400995254517, -0.020541366189718246, 0.2600404620170593, -0.10833749175071716, 0.036447957158088684, -0.36018478870391846, -0.12711986899375916, 0.2606499195098877, 0.2881711423397064, 0.7029435634613037, -0.1414911448955536, -0.0848516896367073, 0.3585105538368225, -0.04511311650276184, 0.24639412760734558, 0.4116198420524597, -0.4193349778652191, 0.5370025038719177, 0.4218825697898865, 0.03302404284477234, 0.04051119089126587, -0.4930671155452728, 0.12944979965686798, 0.8145080804824829, -0.49908819794654846, 0.19380804896354675, 0.09682479500770569, 0.4217352271080017, -0.5215371251106262, -0.06526830792427063, -0.26663315296173096, 0.2522737979888916, 1.213325023651123, 0.0012408196926116943, -0.2426946759223938, -0.28965428471565247, -0.3634025752544403, -0.13846488296985626, -0.3301095962524414, -0.12310884147882462, -0.03835451602935791, -0.7434549331665039, 0.24088844656944275, -0.17097029089927673, -0.13022029399871826, -0.007050663232803345, 0.06718186289072037, 0.45522329211235046, 0.10973918437957764, 0.012622185051441193, 0.16777338087558746, -0.05771467462182045, 0.19996578991413116, -0.24137984216213226, 0.24456733465194702, -0.11382054537534714, 0.010699808597564697, 0.19115638732910156, -0.0028515905141830444, -0.09564647823572159, 0.09341803193092346, 0.2944413125514984, 0.23297476768493652, -0.17356669902801514, 0.39457371830940247, -0.31496915221214294, 0.23409241437911987, -0.12645113468170166, -0.6129994988441467, -0.15042293071746826, -0.26337844133377075, 0.3586566150188446, 0.015362411737442017, -0.1516532152891159, 0.22309523820877075, -1.4553773403167725, 0.622140645980835, -0.5070102214813232, -0.7885435223579407, 0.1319749355316162, -0.446965754032135, -0.16092371940612793, 0.3529052436351776, 0.007851272821426392, 0.09744635224342346, 0.20603105425834656, -0.08496123552322388, 0.3391745984554291, 0.0328497439622879, 1.0089284181594849, 0.3865002393722534, 0.8738011121749878, 0.06040278077125549, -0.015890859067440033, -0.21144962310791016, 0.5995208621025085, 0.32733339071273804, 0.9662830829620361, 0.3483368158340454, 0.08898067474365234, 0.887071430683136, 0.3696739375591278, 0.19864115118980408, 0.03314075618982315, 0.03536325320601463, -0.12863528728485107, 0.06904687732458115, -0.24006515741348267, -0.012378469109535217, -0.5082074403762817, -0.7163709402084351, -0.1123851016163826, 0.010127410292625427, 0.4355129599571228, -0.6237277984619141, 0.2890245020389557, 0.5209721326828003, -0.15595661103725433, 0.08429825305938721, 0.09569454938173294, -0.23599457740783691, -0.16896066069602966, -0.004924099892377853, 0.6319135427474976, 0.4765503704547882, 0.01589702069759369, -0.05348372459411621, 0.055996619164943695, -0.5671727657318115, 0.15062867105007172, -0.5092383623123169, -0.058769792318344116, 0.09755947440862656, 0.2507498860359192, 0.08485430479049683, 0.0793701708316803, 0.021087057888507843, -0.5461320281028748, 0.304355651140213, -0.7253096699714661, 0.6294398307800293, -0.3105747103691101, 0.3905089199542999, 0.2852843105792999, -0.07321953773498535, 0.023653872311115265, -0.37693509459495544, 0.2675110697746277, 0.04210440814495087, 0.09981885552406311, -0.20424491167068481, 0.3030926287174225, 0.026748113334178925, 0.5781193375587463, 0.00048617273569107056, -0.1131657287478447, 0.2036598026752472, -0.2140207141637802, -0.011482134461402893, -0.2234390377998352, -0.43609818816185, -0.504375696182251, -0.01408250629901886, -0.06268232315778732, -0.3341209888458252, 0.29185229539871216, -0.2411029040813446, 0.5522151589393616, -0.06291865557432175, -0.3783164620399475, -0.2328968197107315, -0.3904339075088501, -0.11180463433265686, -0.16056767106056213, -0.16029603779315948, -0.2223338484764099, 0.33838483691215515, -0.23742935061454773, 0.12314961105585098, -0.5309375524520874, -0.07631200551986694, 0.35636740922927856, 0.17236372828483582, 0.19029422104358673, -0.1397394984960556, 0.5870028734207153, -0.4097609221935272, 0.15144716203212738, 0.003988280892372131, -0.05234433710575104, -0.2421717643737793, -0.006953790783882141, -0.5565206408500671, 0.06222153455018997, -0.07391542196273804, 0.40786826610565186, -0.04986128211021423, -0.285273939371109, -0.1444988250732422, 0.024988561868667603, -0.3689330816268921, -0.40285810828208923, -0.10759894549846649, -0.0395619198679924, 0.01536903902888298, 0.0707881823182106, 0.22722786664962769, 0.2506854236125946, 0.023645572364330292, -0.14591404795646667, 0.09581179171800613, -0.12541484832763672, 0.03997009992599487, -0.02025282382965088, -0.23364081978797913, 0.3128877580165863, 0.12357562780380249, -0.1596986949443817, 0.22576884925365448, -0.14733293652534485, 0.24771124124526978, 0.0026986300945281982, 0.5146662592887878]');

SELECT image_name,
       (my_dot_product(embedding, @target) / (my_vec_norm(embedding) * my_vec_norm(@target))) AS similarity
FROM image_embeddings
ORDER BY similarity DESC
LIMIT 5;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example output:&lt;br&gt;
&lt;code&gt;+------------+--------------------+&lt;br&gt;
| image_name | similarity         |&lt;br&gt;
+------------+--------------------+&lt;br&gt;
| img/t3.jpg | 1.0000000040388952 |&lt;br&gt;
| img/t2.jpg | 0.9667246382795552 |&lt;br&gt;
| img/t1.jpg | 0.9642200115094365 |&lt;br&gt;
| img/t4.jpg | 0.9213785475357513 |&lt;br&gt;
+------------+--------------------+&lt;/code&gt;&lt;br&gt;
In this example, the target image is most similar to t3.jpg.&lt;/p&gt;

&lt;h2&gt;
  
  
  Source Code
&lt;/h2&gt;

&lt;p&gt;All source files are available on GitHub:&lt;br&gt;
&lt;a href="https://github.com/knowledgebase21st/Software-Engineering/tree/dev/AI" rel="noopener noreferrer"&gt;GIT Source Codes&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Role of the Libraries Used
&lt;/h2&gt;

&lt;h4&gt;
  
  
  NumPy
&lt;/h4&gt;

&lt;p&gt;Handles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;arrays&lt;/li&gt;
&lt;li&gt;matrix operations&lt;/li&gt;
&lt;li&gt;linear algebra&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  PyTorch
&lt;/h4&gt;

&lt;p&gt;Used for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;building neural networks&lt;/li&gt;
&lt;li&gt;defining layers (Linear, CNN, Transformer)&lt;/li&gt;
&lt;li&gt;training models&lt;/li&gt;
&lt;li&gt;GPU acceleration&lt;/li&gt;
&lt;li&gt;backpropagation&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  sentence-transformers
&lt;/h4&gt;

&lt;p&gt;This library converts text or images into dense vector embeddings using deep neural networks.&lt;br&gt;
Internally the process is:&lt;br&gt;
&lt;code&gt;Input → Transformer Model → Embedding Vector&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Pillow
&lt;/h4&gt;

&lt;p&gt;Pillow is a Python library for image processing.&lt;br&gt;
Before an image is passed to a neural network, it usually undergoes preprocessing such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;loading&lt;/li&gt;
&lt;li&gt;resizing&lt;/li&gt;
&lt;li&gt;cropping&lt;/li&gt;
&lt;li&gt;normalization&lt;/li&gt;
&lt;li&gt;converting to tensors&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pillow helps perform these operations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real-World Use Cases
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Images stored as vectors could be useful for many real world applications&lt;/li&gt;
&lt;li&gt;Search Image: Find similar images&lt;/li&gt;
&lt;li&gt;Ecommerce: Find visually similar products&lt;/li&gt;
&lt;li&gt;Check Duplicity: Detect very similar or duplicate image&lt;/li&gt;
&lt;li&gt;Prohibited Image: Identify prohibited or restricted image&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Tested with:
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- Python 3.12  
- MySQL 9.x  
- sentence-transformers  
- PyTorch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Vector embeddings enable powerful capabilities such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;semantic search&lt;/li&gt;
&lt;li&gt;image similarity detection&lt;/li&gt;
&lt;li&gt;recommendation systems&lt;/li&gt;
&lt;li&gt;multimodal AI applications
With modern databases like MySQL supporting vector storage, it becomes possible to build AI-powered search systems directly inside the database layer.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>python</category>
      <category>vectordatabase</category>
      <category>mysql</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>Cipher Suite Explained Component by Component</title>
      <dc:creator>Sanjay Ghosh</dc:creator>
      <pubDate>Mon, 02 Mar 2026 08:13:07 +0000</pubDate>
      <link>https://dev.to/sanjayghosh/cipher-suite-explained-component-by-component-p2c</link>
      <guid>https://dev.to/sanjayghosh/cipher-suite-explained-component-by-component-p2c</guid>
      <description>&lt;h4&gt;
  
  
  Key Exchange
&lt;/h4&gt;

&lt;p&gt;How the keys are exchanged.&lt;br&gt;
&lt;em&gt;Example :DH,DHE (Diffie Hillman Ephamarel 1.e short lived), ADH(Anonymous DH), ECDHE (Eliptic curve ), RSA&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Authentication
&lt;/h4&gt;

&lt;p&gt;This is digital signature algorithm. This is needed to confirm if the client is sending to the correct server. Server sends the certificate back to the client (That certificate contains the public key).&lt;br&gt;
&lt;em&gt;Examples : RSA, ECDSA (Elliptic Curve Digital Signature Algorithm )&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Bulk Encryption Cipher
&lt;/h4&gt;

&lt;p&gt;It is used to encrypt the data being sent.&lt;br&gt;
There are 2 kinds of Bult Ciphers:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Stream Cipher: A stream cipher, which operates on data 1 byte at a time, converts a key to a keystream to encrypt data and produce ciphertext. The remote end converts the shared key to the same keystream and decrypts the plaintext data.&lt;/li&gt;
&lt;li&gt;Block Cipher: A block cipher operates on data in groups (or blocks) of bytes. Stream ciphers perform better than block ciphers. However, block ciphers provide better security. DES (56-bit), Triple-Data Encryption Standard (TDES) (168-bit), and Advanced Encryption Standard (AES) are the most common block ciphers. DES and TDES operate on blocks of 8 bytes at a time. AES operates on blocks of 16 bytes at a time.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;Example: AES (Advanced Encryption Standard).&lt;/em&gt;&lt;br&gt;
&lt;a href="https://en.wikipedia.org/wiki/Cipher_suite#:~:text=The%20bulk%20encryption%20algorithm%20is,the%20server%20and%20or%20client." rel="noopener noreferrer"&gt;Refer&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Hash or MAC
&lt;/h4&gt;

&lt;p&gt;MAC (Message Authentication Code) : This is to verify the legitimacy of data sent. This is to make sure message sent is not altered or tamperd and data integrity is maintained.&lt;br&gt;
&lt;a href="https://en.wikipedia.org/wiki/Message_authentication_code" rel="noopener noreferrer"&gt;Refer&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Example : SHA, MD5&lt;/em&gt;&lt;/p&gt;

</description>
      <category>tls</category>
      <category>cipher</category>
      <category>encryption</category>
      <category>security</category>
    </item>
    <item>
      <title>Understanding RSA: A Simple Guide to Public-Key Math</title>
      <dc:creator>Sanjay Ghosh</dc:creator>
      <pubDate>Mon, 23 Feb 2026 01:36:37 +0000</pubDate>
      <link>https://dev.to/sanjayghosh/understanding-rsa-a-simple-guide-to-public-key-math-6g7</link>
      <guid>https://dev.to/sanjayghosh/understanding-rsa-a-simple-guide-to-public-key-math-6g7</guid>
      <description>&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/RSA_cryptosystem" rel="noopener noreferrer"&gt;RSA&lt;/a&gt; (Rivest–Shamir–Adleman) is a Public-Key cryptographic algorithm. It involves a public key to encrypt and corresponding private key to decrypt data to transmit securely and to verify digital signature. &lt;/p&gt;

&lt;h4&gt;
  
  
  Step 1: Generate the key
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Take any 2 large prime numbers p and q&lt;/li&gt;
&lt;li&gt;Let n = p*q&lt;/li&gt;
&lt;li&gt;Find the totient of n
&lt;em&gt;(Totient of n means the count of the numbers which are less than n and each of the numbers are relatively prime to n.
So, for example totient of 11 is 11 , because there are 11 numbers 1,2,3,4,5,6.7,8,9,10 , these are relatively prime to 11.
Same way Totient of 12 is 4, because 1,5,7,11 , these 4 numbers are relatively prime to 12, and there is no common factor of 12 and any of these numbers. Easy way to find totient of p*q = (p-1)*(q-1))
)&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Step 2: Do the math to encrypt/decrypt
&lt;/h4&gt;

&lt;p&gt;If your message is m and cypher is c , then    &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; c = m^e mod n  -- This is encryption&lt;/li&gt;
&lt;li&gt;     m = c^d mod n  -- This is decryption&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  &lt;u&gt;Example&lt;/u&gt;
&lt;/h4&gt;

&lt;p&gt;Let p = 7 and q = 17 , so n = 7 x 17 = 119&lt;br&gt;
    The totient of n (119) = (p-1)&lt;em&gt;(q-1) = (7-1)&lt;/em&gt;(17-1) = 96&lt;br&gt;&lt;br&gt;
     Choose integer e (public exponent) which is &amp;lt; 96  and relatively prime to 96 . Let us choose the number 53 which satisfies this condition.&lt;br&gt;
     Choose the 2nd integer d (private exponent) , which will satisfy (e*d) mod totient(n) = 1 . d = 29 satisfies this. &lt;br&gt;
     (53 * 29) mod 96 = 1)&lt;br&gt;
     so public key = 53 and private key = 29 .&lt;br&gt;
     Let us encrypt the Letter H (Which is 7 as integer, A=0, B=1 , C=2 ....Z=25) and decrypt back.) &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;c = m^e mod n = 7^53 mod 119 = 28  Encrypted&lt;/li&gt;
&lt;li&gt;     m = c^d mod n = 28^29 mod 119 = 7  Decrypted (Which is back to H)&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  &lt;u&gt;Why is it secure&lt;/u&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;In our example we used very small prime integers (7 and 17). But in real use, the prime integers are big to enhance security. It is not only knowing the public exponent e and the value of n to crack this, the totient is needed too.&lt;/li&gt;
&lt;li&gt;If it is said that 2048 bit RSA signature means the n is  of 2048 bits (Max integer value 2^2048 - 1). So, if the value of n is a 2048 bit number, it is almost impossible to crack it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  &lt;u&gt;Implementation&lt;/u&gt;
&lt;/h4&gt;

&lt;p&gt;I’ve implemented a simple version of this in Java so you can play with the logic yourself.&lt;br&gt;
&lt;a href="https://github.com/knowledgebase21st/Software-Engineering/tree/dev/RSA" rel="noopener noreferrer"&gt;GitHub: Supporting Java code and Readme&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;u&gt;Common Risks&lt;/u&gt;
&lt;/h4&gt;

&lt;h4&gt;
  
  
  Size
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Problem: If the value of n (p*q) is small, it is easy to detect the factors (p and q) quickly.&lt;/li&gt;
&lt;li&gt;Solution: Use 2048 bit numbers&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Determinism Attack
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Problem: When attacker could guess the message, because as per the theory the encrypted value of the same TEXT would be the same. If "Hi" is encrypted with the public key twice it would give the same encrypted value. &lt;/li&gt;
&lt;li&gt;Solution: Using Padding like &lt;a href="https://en.wikipedia.org/wiki/Optimal_asymmetric_encryption_padding" rel="noopener noreferrer"&gt;OAEP &lt;/a&gt;. Here random data are added to the message before encrypting it to make the text of the message look different before encrypting. &lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Mathematical Attack
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Problem: when m is small , it could be easy for the attacker to find the value of c = m^e mod n , without knowing the private exponent d.&lt;/li&gt;
&lt;li&gt;Solution: Same as before, use padding &lt;a href="https://en.wikipedia.org/wiki/Optimal_asymmetric_encryption_padding" rel="noopener noreferrer"&gt;OAEP&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>cryptography</category>
      <category>security</category>
      <category>java</category>
      <category>math</category>
    </item>
    <item>
      <title>How to Debug Deadlocks Using Thread Dumps and Scripts (Bash/Python)</title>
      <dc:creator>Sanjay Ghosh</dc:creator>
      <pubDate>Sun, 15 Feb 2026 19:33:33 +0000</pubDate>
      <link>https://dev.to/sanjayghosh/deadlock-abe</link>
      <guid>https://dev.to/sanjayghosh/deadlock-abe</guid>
      <description>&lt;p&gt;Have you ever had an application completely freeze in production without throwing a single error? You likely encountered a Deadlock. While Java’s JVM is powerful, circular dependencies between threads can bring your entire system to a halt.&lt;/p&gt;

&lt;p&gt;In this post, we’ll analyze a real-world deadlock scenario and I’ll share two scripts (Bash and Python) to help you automate the detection of these "silent killers."&lt;/p&gt;

&lt;h3&gt;
  
  
  🏗️ The Scenario
&lt;/h3&gt;

&lt;p&gt;The scenario is like this with 2 Threads, Thread1 and Thread2.&lt;br&gt;
Thread 1 acquired a lock on a Resource1 (Thread2 is trying to lock it) and waiting to acquire a lock on Resource2 (Already locked by Thread2).Thread 2 acquired a lock on the Resource2 (Thread 1 is trying to lock it)  and waiting to acquire a lock on Resource1 (Already locked by Thread1).&lt;/p&gt;

&lt;p&gt;Example of java code which will cause dead-lock&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class MyDeadLockExample1 {    

    public static Object someResource1 = new Object();

    public static Object someResource2 = new Object();

    public static void main (String[] args) {     

        System.out.println("Test of DeadLock -------------------");
        TestThread1 t1  = new TestThread1();
        TestThread2 t2  = new TestThread2();     
        t1.start();
        t2.start();
    }

    /*Now create a class which will Acquire lock on someResource1 and also wait to Acquire lock on someResource 2*/

    private static class TestThread1 extends Thread {    

        public void run() {
            /*Aquiring lock on someResource1*/

            synchronized (someResource1) {           
                      System.out.println("Thread 1 has locked someResource1");            
                      /*Now sleep for a minute to wait and then try to acquire lock on someResource 2*/           
                       try {
                           Thread.sleep(60)           
                       }           
                       catch (InterruptedException ie)           
                       {           
                           ie.printStackTrace();         
                       }

                       /*Now going to acquire lock on someResource2*/           
                       synchronized(someResource2) {           
                           System.out.println("Thread 1 has locked someResource 2");           
                       }

         }

      }

    } /*End class TestThread1*/



    /*Now create a class which will Acquire lock on someResource2 and also wait to Acquire lock on someResource1*/

    private static class TestThread2 extends Thread {   

        public void run() {

            /*Aquiring lock on someResource1*/

            synchronized (someResource2) {           
                       System.out.println("Thread 2 has locked someResource2");            
                       /*Now sleep for a minute to wait and then try to acquire lock on someResource 1*/          
                       try {           
                           Thread.sleep(60);           
                       }           
                       catch (InterruptedException ie)           
                       {           
                          ie.printStackTrace();           
                       }             
                       /*Now going to acquire lock on someResource1*/           
                       synchronized(someResource1) {           
                           System.out.println("Thread 1 has locked someResource 2");           
                       }
            }

        }

    } /*End class TestThread1*/



} /*End of class MyDeadLockExample1*/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the above code:&lt;br&gt;
javac MyDeadLockExample1.java&lt;br&gt;
java MyDeadLockExample1&lt;br&gt;
It will hang forever because of deadlock&lt;/p&gt;
&lt;h3&gt;
  
  
  🛡️ How to know that there is a Dead Lock
&lt;/h3&gt;

&lt;p&gt;🔍 Step 1: Generate the Thread Dump&lt;br&gt;
Either do&lt;br&gt;
kill -3   //From Linux&lt;br&gt;
or&lt;br&gt;
jcmd  Thread.print &lt;/p&gt;

&lt;p&gt;This will create the thread dump and you can save in a file (In example td.txt)&lt;/p&gt;

&lt;p&gt;Thread dump for this below (td.txt):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;     1  25047:
     2  2026-02-07 18:37:20
     3  Full thread dump OpenJDK 64-Bit Server VM (17.0.18+8-Ubuntu-124.04.1 mixed mode, sharing):
     4
     5  Threads class SMR info:
     6  _java_thread_list=0x00007df42c001ed0, length=14, elements={
     7  0x00007df4c017c250, 0x00007df4c017d640, 0x00007df4c0185610, 0x00007df4c01869d0,
     8  0x00007df4c0187df0, 0x00007df4c01897b0, 0x00007df4c018acf0, 0x00007df4c0194160,
     9  0x00007df4c019b8d0, 0x00007df4c019ef20, 0x00007df4c01a17f0, 0x00007df4c01a28b0,
    10  0x00007df4c00182e0, 0x00007df42c000f40
    11  }
    12
    13  "Reference Handler" #2 daemon prio=10 os_prio=0 cpu=0.26ms elapsed=213.94s tid=0x00007df4c017c250 nid=0x61df waiting on condition  [0x00007df4a13a9000]
    14     java.lang.Thread.State: RUNNABLE
    15          at java.lang.ref.Reference.waitForReferencePendingList(java.base@17.0.18/Native Method)
    16          at java.lang.ref.Reference.processPendingReferences(java.base@17.0.18/Reference.java:253)
    17          at java.lang.ref.Reference$ReferenceHandler.run(java.base@17.0.18/Reference.java:215)
    18
    19  "Finalizer" #3 daemon prio=8 os_prio=0 cpu=0.33ms elapsed=213.94s tid=0x00007df4c017d640 nid=0x61e0 in Object.wait()  [0x00007df4a12a9000]
    20     java.lang.Thread.State: WAITING (on object monitor)
    21          at java.lang.Object.wait(java.base@17.0.18/Native Method)
    22          - waiting on &amp;lt;0x0000000717602f40&amp;gt; (a java.lang.ref.ReferenceQueue$Lock)
    23          at java.lang.ref.ReferenceQueue.remove(java.base@17.0.18/ReferenceQueue.java:155)
    24          - locked &amp;lt;0x0000000717602f40&amp;gt; (a java.lang.ref.ReferenceQueue$Lock)
    25          at java.lang.ref.ReferenceQueue.remove(java.base@17.0.18/ReferenceQueue.java:176)
    26          at java.lang.ref.Finalizer$FinalizerThread.run(java.base@17.0.18/Finalizer.java:172)
    27
    28  "Signal Dispatcher" #4 daemon prio=9 os_prio=0 cpu=0.74ms elapsed=213.94s tid=0x00007df4c0185610 nid=0x61e1 waiting on condition  [0x0000000000000000]
    29     java.lang.Thread.State: RUNNABLE
    30
    31  "Service Thread" #5 daemon prio=9 os_prio=0 cpu=0.18ms elapsed=213.94s tid=0x00007df4c01869d0 nid=0x61e2 runnable  [0x0000000000000000]
    32     java.lang.Thread.State: RUNNABLE
    33
    34  "Monitor Deflation Thread" #6 daemon prio=9 os_prio=0 cpu=61.88ms elapsed=213.94s tid=0x00007df4c0187df0 nid=0x61e3 runnable  [0x0000000000000000]
    35     java.lang.Thread.State: RUNNABLE
    36
    37  "C2 CompilerThread0" #7 daemon prio=9 os_prio=0 cpu=5.41ms elapsed=213.94s tid=0x00007df4c01897b0 nid=0x61e4 waiting on condition  [0x0000000000000000]
    38     java.lang.Thread.State: RUNNABLE
    39     No compile task
    40
    41  "C1 CompilerThread0" #10 daemon prio=9 os_prio=0 cpu=4.74ms elapsed=213.94s tid=0x00007df4c018acf0 nid=0x61e5 waiting on condition  [0x0000000000000000]
    42     java.lang.Thread.State: RUNNABLE
    43     No compile task
    44
    45  "Sweeper thread" #11 daemon prio=9 os_prio=0 cpu=0.27ms elapsed=213.94s tid=0x00007df4c0194160 nid=0x61e6 runnable  [0x0000000000000000]
    46     java.lang.Thread.State: RUNNABLE
    47
    48  "Notification Thread" #12 daemon prio=9 os_prio=0 cpu=0.31ms elapsed=213.94s tid=0x00007df4c019b8d0 nid=0x61e7 runnable  [0x0000000000000000]
    49     java.lang.Thread.State: RUNNABLE
    50
    51  "Common-Cleaner" #13 daemon prio=8 os_prio=0 cpu=0.68ms elapsed=213.92s tid=0x00007df4c019ef20 nid=0x61e9 in Object.wait()  [0x00007df4a094f000]
    52     java.lang.Thread.State: TIMED_WAITING (on object monitor)
    53          at java.lang.Object.wait(java.base@17.0.18/Native Method)
    54          - waiting on &amp;lt;0x0000000717618120&amp;gt; (a java.lang.ref.ReferenceQueue$Lock)
    55          at java.lang.ref.ReferenceQueue.remove(java.base@17.0.18/ReferenceQueue.java:155)
    56          - locked &amp;lt;0x0000000717618120&amp;gt; (a java.lang.ref.ReferenceQueue$Lock)
    57          at jdk.internal.ref.CleanerImpl.run(java.base@17.0.18/CleanerImpl.java:140)
    58          at java.lang.Thread.run(java.base@17.0.18/Thread.java:840)
    59          at jdk.internal.misc.InnocuousThread.run(java.base@17.0.18/InnocuousThread.java:162)
    60
    61  "Thread-0" #14 prio=5 os_prio=0 cpu=14.72ms elapsed=213.89s tid=0x00007df4c01a17f0 nid=0x61ea waiting for monitor entry  [0x00007df4a084f000]
    62     java.lang.Thread.State: BLOCKED (on object monitor)
    63          at MyDeadLockExample1$TestThread1.run(MyDeadLockExample1.java:35)
    64          - waiting to lock &amp;lt;0x0000000717619480&amp;gt; (a java.lang.Object)
    65          - locked &amp;lt;0x0000000717619470&amp;gt; (a java.lang.Object)
    66
    67  "Thread-1" #15 prio=5 os_prio=0 cpu=15.43ms elapsed=213.89s tid=0x00007df4c01a28b0 nid=0x61eb waiting for monitor entry  [0x00007df4a074f000]
    68     java.lang.Thread.State: BLOCKED (on object monitor)
    69          at MyDeadLockExample1$TestThread2.run(MyDeadLockExample1.java:60)
    70          - waiting to lock &amp;lt;0x0000000717619470&amp;gt; (a java.lang.Object)
    71          - locked &amp;lt;0x0000000717619480&amp;gt; (a java.lang.Object)
    72
    73  "DestroyJavaVM" #16 prio=5 os_prio=0 cpu=32.70ms elapsed=213.89s tid=0x00007df4c00182e0 nid=0x61d8 waiting on condition  [0x0000000000000000]
    74     java.lang.Thread.State: RUNNABLE
    75
    76  "Attach Listener" #17 daemon prio=9 os_prio=0 cpu=1.51ms elapsed=12.63s tid=0x00007df42c000f40 nid=0x620e waiting on condition  [0x0000000000000000]
    77     java.lang.Thread.State: RUNNABLE
    78
    79  "VM Periodic Task Thread" os_prio=0 cpu=327.22ms elapsed=213.94s tid=0x00007df4c019d220 nid=0x61e8 waiting on condition
    80
    81  "VM Thread" os_prio=0 cpu=17.21ms elapsed=213.94s tid=0x00007df4c0178270 nid=0x61de runnable
    82
    83  "G1 Service" os_prio=0 cpu=81.37ms elapsed=213.96s tid=0x00007df4c01498e0 nid=0x61dd runnable
    84
    85  "G1 Refine#0" os_prio=0 cpu=0.38ms elapsed=213.96s tid=0x00007df4c01489d0 nid=0x61dc runnable
    86
    87  "G1 Conc#0" os_prio=0 cpu=0.23ms elapsed=213.96s tid=0x00007df4c0095020 nid=0x61db runnable
    88
    89  "G1 Main Marker" os_prio=0 cpu=0.23ms elapsed=213.96s tid=0x00007df4c00940a0 nid=0x61da runnable
    90
    91  "GC Thread#0" os_prio=0 cpu=0.36ms elapsed=213.96s tid=0x00007df4c0083280 nid=0x61d9 runnable
    92
    93  JNI global refs: 6, weak refs: 0
    94
    95
    96  Found one Java-level deadlock:
    97  =============================
    98  "Thread-0":
    99    waiting to lock monitor 0x00007df410001000 (object 0x0000000717619480, a java.lang.Object),
   100    which is held by "Thread-1"
   101
   102  "Thread-1":
   103    waiting to lock monitor 0x00007df404000d80 (object 0x0000000717619470, a java.lang.Object),
   104    which is held by "Thread-0"
   105
   106  Java stack information for the threads listed above:
   107  ===================================================
   108  "Thread-0":
   109          at MyDeadLockExample1$TestThread1.run(MyDeadLockExample1.java:35)
   110          - waiting to lock &amp;lt;0x0000000717619480&amp;gt; (a java.lang.Object)
   111          - locked &amp;lt;0x0000000717619470&amp;gt; (a java.lang.Object)
   112  "Thread-1":
   113          at MyDeadLockExample1$TestThread2.run(MyDeadLockExample1.java:60)
   114          - waiting to lock &amp;lt;0x0000000717619470&amp;gt; (a java.lang.Object)
   115          - locked &amp;lt;0x0000000717619480&amp;gt; (a java.lang.Object)
   116
   117  Found 1 deadlock.
   118
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;📊 Step 2: Analysis of the Dump (td.txt)&lt;br&gt;
Look for the BLOCKED state in your logs:&lt;br&gt;
"Thread-0" #14 ... java.lang.Thread.State: BLOCKED (on object monitor)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;waiting to lock &amp;lt;0x0000000717619480&amp;gt;&lt;/li&gt;
&lt;li&gt;locked &amp;lt;0x0000000717619470&amp;gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When we look at a thread dump, the smoking gun is usually the BLOCKED state. Let's look at the specific conflict in our example:&lt;/p&gt;

&lt;p&gt;Key Findings:&lt;/p&gt;

&lt;p&gt;Thread-0 (Lines 61-66) has locked ID ...9470 but is waiting for ...9480.&lt;/p&gt;

&lt;p&gt;Thread-1 (Lines 67-71) has locked ID ...9480 but is waiting for ...9470.&lt;/p&gt;

&lt;p&gt;Thread-0: Holding Resource 1, Waiting for Resource 2&lt;br&gt;
Looking at lines 61-66, we see Thread-0 in action:&lt;/p&gt;

&lt;p&gt;Status: java.lang.Thread.State: BLOCKED (on object monitor)&lt;/p&gt;

&lt;p&gt;Locked: 0x0000000717619470 (Source 1)&lt;/p&gt;

&lt;p&gt;Waiting to lock: 0x0000000717619480 (Source 2)&lt;/p&gt;

&lt;p&gt;Thread-1: Holding Resource 2, Waiting for Resource 1&lt;br&gt;
In lines 67-71, the "Circular Wait" is completed:&lt;/p&gt;

&lt;p&gt;Status: BLOCKED&lt;/p&gt;

&lt;p&gt;Locked: 0x0000000717619480 (Source 2)&lt;/p&gt;

&lt;p&gt;Waiting to lock: 0x0000000717619470 (Source 1)&lt;/p&gt;

&lt;p&gt;The Conclusion: Neither thread can proceed because each is holding the key that the other one needs.&lt;/p&gt;

&lt;p&gt;🛠️ Automation Scripts&lt;br&gt;
Instead of manually digging through thousands of lines in a production thread dump, you can use these automation scripts to flag deadlocks instantly.&lt;/p&gt;

&lt;p&gt;🔗 [GitHub Repository Link Here]&lt;br&gt;
All resources for this example are available on GitHub: &lt;a href="https://github.com/knowledgebase21st/Software-Engineering/tree/dev/threads/locks/deadlocks" rel="noopener noreferrer"&gt;GitHub location&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;Included Files:&lt;/u&gt;&lt;/strong&gt;&lt;br&gt;
MyDeadLockExample1.java: The Java source that reproduces this exact deadlock.&lt;/p&gt;

&lt;p&gt;td.txt: The raw thread dump file used in this analysis.&lt;/p&gt;

&lt;p&gt;parse.py: A Python script for deep parsing. (Usage: python3 parse.py td.txt)&lt;/p&gt;

&lt;p&gt;parse.sh: A lightweight Bash script for quick CLI checks. (Usage: ./parse.sh td.txt)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;Pro-Tip&lt;br&gt;
&lt;/u&gt;&lt;/strong&gt;These scripts aren't just for this example—you can run them against any thread dump file to detect monitor-based deadlocks in your own applications.&lt;/p&gt;

</description>
      <category>thread</category>
      <category>deadlock</category>
      <category>java</category>
      <category>concurrency</category>
    </item>
  </channel>
</rss>
